Take the codebase from "Effect at the CLI edge" to Effect v4 as the idiom throughout — CLI core, server, and SPA — starting with Schema as the payload contract.
Starting point
Effect v4 already carries the CLI entry (src/cli.ts), the HTTP edge (src/server/serve.ts), and one real service with typed errors (src/pr/locate.ts, named in DECISIONS.md as "the first piece of the Effect-throughout direction"). Everything else is plain TS by an earlier decision: hand-rolled boundary parsers, spawnSync behind src/resolve/exec.ts, { value, diagnostics } records in the core, and a Promise-based SPA with zero Effect imports.
Two DECISIONS.md entries lock the old direction in and are superseded by this umbrella:
- "The payload contract stays plain interfaces"
- "The core returns records; Effect stays at the CLI edge"
Ground rules
- Every API is verified against the installed
.d.ts under node_modules/effect/dist/. The pinned 4.0.0-beta.102 (the current beta dist-tag) exports Context.Service — not ServiceMap — and FileSystem/Path/Config live in effect core.
- The encoded JSON of every persisted or transported shape stays byte-compatible: baked
window.__BALADE__ HTML, localStorage, .balade/*.review.json, the /api/* responses.
- Diagnostics stay values.
CheckDiagnostic is the product of check, not a failure; the error channel is for real failures only.
- Each phase lands with the full pipeline green (typecheck, lint, format, tests). The two dialects coexist between phases; that transitional state is recorded in DECISIONS.md and removed at the end.
Phases
Dependency chain: 0 → 1 → 2 → 3 → 4. Phase 5 (SPA) needs only Phase 1 and can run in parallel after it. Phases 6 and 7 trail the others continuously.
The sub-issues below hold the per-phase scope and task lists.
Take the codebase from "Effect at the CLI edge" to Effect v4 as the idiom throughout — CLI core, server, and SPA — starting with Schema as the payload contract.
Starting point
Effect v4 already carries the CLI entry (
src/cli.ts), the HTTP edge (src/server/serve.ts), and one real service with typed errors (src/pr/locate.ts, named in DECISIONS.md as "the first piece of the Effect-throughout direction"). Everything else is plain TS by an earlier decision: hand-rolled boundary parsers,spawnSyncbehindsrc/resolve/exec.ts,{ value, diagnostics }records in the core, and a Promise-based SPA with zero Effect imports.Two DECISIONS.md entries lock the old direction in and are superseded by this umbrella:
Ground rules
.d.tsundernode_modules/effect/dist/. The pinned4.0.0-beta.102(the currentbetadist-tag) exportsContext.Service— notServiceMap— andFileSystem/Path/Configlive in effect core.window.__BALADE__HTML, localStorage,.balade/*.review.json, the/api/*responses.CheckDiagnosticis the product ofcheck, not a failure; the error channel is for real failures only.Phases
Dependency chain: 0 → 1 → 2 → 3 → 4. Phase 5 (SPA) needs only Phase 1 and can run in parallel after it. Phases 6 and 7 trail the others continuously.
The sub-issues below hold the per-phase scope and task lists.