Decision records
ADR 0010 — the loom CLI (logs / debug / eval)
- Status: Accepted (DX tooling — Phase 2)
- Date: 2026-07-07
- Builds on: ADR 0009
Context
Loom had no unified CLI (only loom-compile + create-loom-app) and no way to
inspect the durable event log. The through-line of the DX roadmap is that the log
is the moat and most tooling is a lens on it — so the first CLI commands expose
the log directly.
Decision
New @loom/cli with bin loom. Each command’s logic is a pure function; the
bin is a thin argv wrapper, so behaviour is unit-tested without spawning
processes.
loom debug --db <path> <executionId> [--at N]— time-travel over the log.foldAt(events, seq)reconstructs the exactExecutionStateat any sequence, deterministically, with no live effects (reusing@loom/eval’s identity-seeded fold). This is the uniquely-Loom capability — principled time-travel is only possible because of deterministic replay + snapshots.loom logs --db <path> <executionId>—formatLogprints the event stream as a timeline and marks suspend points.loom eval --dir <path>—evaluateGoldensreplays golden logs (storedEventEnvelope[]JSON + expectations) and checks status / output / completed steps; exits non-zero on failure (CI-ready).
Scope decisions (deliberate):
- Commands take an explicit
--db/--dirpath so v1 needs no TS-config loading — tractable and testable.deploy/check/dev(which need the app’s flows) get config-loading in later phases. loom debugv1 is non-interactive (--at); an interactive REPL and fork-from-sequence (which needs an app load) are follow-ons.- No
loom create-app— rejected as redundant with the idiomaticcreate-loom-app(npm create loom-app), because theloomCLI is project-local (likenext/vite), whereas creation is pre-project.--helphints atnpm create loom-app; in-project generation lands asloom new(Phase 3).
Consequences
- The durable log becomes directly inspectable/debuggable from the terminal.
foldAt/formatLog/evaluateGoldensare exported for reuse (e.g. the Phase-6 inspector reusesfoldAtfor its time-travel slider).- New package:
@loom/cli(deps: core, eval, event-runtime, replay-vm).
Verification
- 10 tests:
parseArgs;foldAtreconstructs a past sequence (running) vs final (suspended);formatLogmarks the suspend;describeState;cmdLogs/cmdDebugover a real temp SQLite store recorded by a real run; graceful unknown-execution;loom evalpasses/fails goldens and reports step-completion misses.loom --helpsmoke-verified. Full repo: build + typecheck clean, 77/77 test tasks green, biome clean (538).
Source: docs/adr/0010-loom-cli.md in the loom repository.