ems-dev-harness
Improvements to review
- Extend with
qualityagent-
ponytail - sonar/similar
-
- Extend
scoutwitharchitectcompanion agent-
understand-everything -
treesitter-mcp(maybe overlap withunderstand-everything) -
backstagemcp -
aimee(per:Stacking NeuralMind + Headroom + Ponytail)
-
The reliability layer for agent-authored pull requests/local develompent. It turns a clearly
scoped td task into a reviewed PR with evidence, and makes the next run
better when this one fails.
Humans steer. Agents execute. The harness is the product; target-repo code is the output. When agents struggle, fix the harness.
The stack is modern: Effect for types/errors/IO, the Claude Agent SDK as
the default agent runtime, LangGraph for the pipeline graph, and @effect/cli for
the CLI. See CONTEXT.md for the full design and vocabulary.
Core Loop
ems run --task td-1234 --repo-path ../target-repo
The pipeline runs deterministic phases — the LLM does the work inside each phase, TypeScript decides which phase runs next:
scout → implement → verify → review → quality → close → retrospective
Every run is event-sourced: an append-only JSONL log under
<target-repo>/.ems/<task-slug>/ is the source of truth, and reduceEvents
reconstructs PipelineState, so runs resume after a crash. Evidence gates
(tested, manual-tested, reviewed) must pass before the closer opens a PR.
Architecture
| Layer | Package |
|---|---|
| Domain model + contract | @ems/core — Effect Schema, typed errors, Runtime tag |
| Pipeline | @ems/orchestration — event log, router, evidence gates, LangGraph |
| Default runtime | @ems/agent-claude — Claude Agent SDK |
| Provider adapters | @ems/agent-{claude,pi,openrouter,copilot} |
| Task store | @ems/task-management-td — td CLI as an Effect service |
| CLI | apps/cli — the ems binary (@effect/cli) |
| Surfaces | @ems/plugin-{pi,opencode,vscode,copilot-cli,claude} |
Every provider adapter implements one interface — AgentRuntime.spawn — and
provides it as an Effect Layer for the Runtime service tag. The pipeline
asks for Runtime; --runtime claude|pi|openrouter|copilot picks the adapter.
CLI
ems run --task <td-id> [--repo-path <path>] [--runtime <r>] [--model <m>] [--merge]
# --merge: closer merges into the base branch
# locally (git) instead of opening a PR
ems status <td-id> # projected pipeline state
ems watch <task-slug> # tail the event log
ems mark-tested <td-id>
ems mark-reviewed <td-id> --critical 0
ems init # write ~/.config/ems/config.json
Surfaces
The harness is exposed through five editor/agent integrations, each
delegating to the ems CLI: a pi tool set, an opencode plugin, a
VS Code extension (command palette), a copilot-cli MCP bridge, and a
Claude Code plugin (/ems-run, /ems-status, /ems-watch slash commands).
Development
This is a Vite+ (vp) + Bun workspace.
vp install # after pulling
vp check # fmt + lint + typecheck (whole repo)
vp run -r test # all package tests
vp run -r build # build all packages
Per package: bun run check and bun run test.