Effect Prepare Script Simplification Research
Effect Prepare Script Simplification Research
Scope
Find the smallest safe implementation for adding the Effect tsgo Oxlint patch to an existing package.json prepare script. Research covered required behavior, reusable repository patterns, and the validation surface. All lanes were read-only.
Evidence
- The Effect lint asset requires one command,
effect-tsgo patch --no-typescript --oxlint, and an exact compatible dependency tuple. The asset declaration is the authority for this behavior.apps/cli/src/data/catalog/lint.ts - Scaffold materialization adds required prepare commands and records them as
required-shell-segmentstructured entries.apps/cli/src/scaffold/output.ts - Update reconciliation observes, adds, removes, and migrates those receipt-owned entries.
apps/cli/src/update/run.ts - The current implementation contains a partial POSIX and Windows shell parser in the scaffold output module. It handles quoting, groups, control structures, redirects, command substitution, and exit behavior solely to compose one lifecycle command.
apps/cli/src/scaffold/output.ts - The behavioral portfolio repeats much of that shell grammar at helper, scaffold-process, and update-process levels. The essential integration cases are scaffold/idempotency, receipt adoption/removal, preservation of project edits, command migration, atomic conflict failure, and dependency-tuple rejection.
apps/cli/src/cli/behavioral-portfolio.test.ts - The repository has no reusable general shell parser. Its existing script transformations are narrow, domain-specific string operations for scaffold-owned scripts.
apps/cli/src/scaffold/stage.ts shell-quoteis only a transitive lockfile entry and would not provide the implemented POSIX-plus-Windows control-flow validation.bun.lock
Findings by lane
- Required behavior: preserve a project-owned prepare action, run it before the Effect patch, deduplicate repeated scaffold/update runs, restore or remove the managed addition when ownership changes, and fail closed on conflicts.
- Repository patterns: structured-entry reconciliation is the correct ownership mechanism. Shell parsing is not an established scaffold concern, and parser internals should not live in the already broad output generator.
- Validation: retain integration-level proofs for scaffold, update, receipt migration, project-edit preservation, atomic failure, and the supported dependency tuple. Large cross-product syntax matrices are not required to prove the Effect feature.
Conflict and uncertainty
- Moving the original command into a private child package script avoids shell parsing and preserves its bytes, but nested package-manager invocation needs cross-manager proof and can change lifecycle environment details.
- Restricting composition to a narrow syntax and failing closed is simpler, but intentionally drops convenience support for complex shell programs.
- Blindly appending
&&is smallest, but cannot guarantee the patch runs after early exit or other shell control flow.
Synthesized conclusion
The Effect feature should own a narrow lifecycle-command transformation, not a general shell language. Keep receipt-based ownership and typed conflict failure. Support only the forms needed for deterministic append, detection, removal, and migration; reject ambiguous project-owned shell programs without mutation. Delete parser branches and repeated tests that exist only to emulate arbitrary POSIX or Windows control flow.
Next local action
Apply simplify to the prepare-command helpers and their tests, then validate the focused Effect scenarios, the full CLI behavioral portfolio, build/type checks, and release classification before updating PR #159.