@bastani/atomic 0.6.4 → 0.6.5-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/.agents/skills/create-spec/SKILL.md +6 -3
  2. package/.agents/skills/tdd/SKILL.md +107 -0
  3. package/.agents/skills/tdd/deep-modules.md +33 -0
  4. package/.agents/skills/tdd/interface-design.md +31 -0
  5. package/.agents/skills/tdd/mocking.md +59 -0
  6. package/.agents/skills/tdd/refactoring.md +10 -0
  7. package/.agents/skills/tdd/tests.md +61 -0
  8. package/.agents/skills/workflow-creator/SKILL.md +550 -0
  9. package/.agents/skills/workflow-creator/references/agent-sessions.md +891 -0
  10. package/.agents/skills/workflow-creator/references/agent-setup-recipe.md +266 -0
  11. package/.agents/skills/workflow-creator/references/computation-and-validation.md +201 -0
  12. package/.agents/skills/workflow-creator/references/control-flow.md +470 -0
  13. package/.agents/skills/workflow-creator/references/failure-modes.md +1014 -0
  14. package/.agents/skills/workflow-creator/references/getting-started.md +392 -0
  15. package/.agents/skills/workflow-creator/references/registry-and-validation.md +141 -0
  16. package/.agents/skills/workflow-creator/references/running-workflows.md +418 -0
  17. package/.agents/skills/workflow-creator/references/session-config.md +384 -0
  18. package/.agents/skills/workflow-creator/references/state-and-data-flow.md +356 -0
  19. package/.agents/skills/workflow-creator/references/user-input.md +234 -0
  20. package/.agents/skills/workflow-creator/references/workflow-inputs.md +392 -0
  21. package/.claude/agents/debugger.md +2 -2
  22. package/.claude/agents/reviewer.md +1 -1
  23. package/.claude/agents/worker.md +2 -2
  24. package/.github/agents/debugger.md +1 -1
  25. package/.github/agents/worker.md +1 -1
  26. package/.mcp.json +5 -1
  27. package/.opencode/agents/debugger.md +1 -1
  28. package/.opencode/agents/worker.md +1 -1
  29. package/README.md +236 -201
  30. package/dist/sdk/define-workflow.d.ts +11 -6
  31. package/dist/sdk/define-workflow.d.ts.map +1 -1
  32. package/dist/sdk/errors.d.ts +10 -0
  33. package/dist/sdk/errors.d.ts.map +1 -1
  34. package/dist/sdk/index.d.ts +21 -9
  35. package/dist/sdk/index.d.ts.map +1 -1
  36. package/dist/sdk/primitives/inputs.d.ts +36 -0
  37. package/dist/sdk/primitives/inputs.d.ts.map +1 -0
  38. package/dist/sdk/primitives/metadata.d.ts +40 -0
  39. package/dist/sdk/primitives/metadata.d.ts.map +1 -0
  40. package/dist/sdk/primitives/run.d.ts +57 -0
  41. package/dist/sdk/primitives/run.d.ts.map +1 -0
  42. package/dist/sdk/primitives/sessions.d.ts +128 -0
  43. package/dist/sdk/primitives/sessions.d.ts.map +1 -0
  44. package/dist/sdk/runtime/executor.d.ts +24 -56
  45. package/dist/sdk/runtime/executor.d.ts.map +1 -1
  46. package/dist/sdk/runtime/orchestrator-entry.d.ts +26 -0
  47. package/dist/sdk/runtime/orchestrator-entry.d.ts.map +1 -0
  48. package/dist/sdk/runtime/tmux.d.ts +20 -0
  49. package/dist/sdk/runtime/tmux.d.ts.map +1 -1
  50. package/dist/sdk/types.d.ts +26 -86
  51. package/dist/sdk/types.d.ts.map +1 -1
  52. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +1 -1
  53. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +1 -1
  54. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +1 -1
  55. package/dist/sdk/workflows/builtin/open-claude-design/claude/index.d.ts.map +1 -1
  56. package/dist/sdk/workflows/builtin/open-claude-design/copilot/index.d.ts.map +1 -1
  57. package/dist/sdk/workflows/builtin/open-claude-design/opencode/index.d.ts.map +1 -1
  58. package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts.map +1 -1
  59. package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts.map +1 -1
  60. package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts.map +1 -1
  61. package/dist/sdk/workflows/index.d.ts +20 -12
  62. package/dist/sdk/workflows/index.d.ts.map +1 -1
  63. package/dist/services/config/additional-instructions.d.ts +1 -1
  64. package/dist/services/config/additional-instructions.d.ts.map +1 -1
  65. package/package.json +4 -4
  66. package/src/cli.ts +39 -56
  67. package/src/commands/builtin-registry.ts +37 -0
  68. package/src/commands/cli/chat/index.ts +1 -3
  69. package/src/{sdk → commands/cli}/management-commands.ts +15 -55
  70. package/src/commands/cli/session.ts +1 -1
  71. package/src/commands/cli/workflow-command.test.ts +250 -16
  72. package/src/commands/cli/workflow-inputs.test.ts +1 -0
  73. package/src/commands/cli/workflow-inputs.ts +13 -3
  74. package/src/commands/cli/workflow-list.test.ts +1 -0
  75. package/src/commands/cli/workflow-list.ts +0 -0
  76. package/src/commands/cli/workflow-status.ts +1 -1
  77. package/src/commands/cli/workflow.ts +191 -11
  78. package/src/sdk/define-workflow.test.ts +47 -16
  79. package/src/sdk/define-workflow.ts +24 -6
  80. package/src/sdk/errors.test.ts +11 -0
  81. package/src/sdk/errors.ts +13 -0
  82. package/src/sdk/index.test.ts +92 -0
  83. package/src/sdk/index.ts +71 -15
  84. package/src/sdk/primitives/inputs.ts +48 -0
  85. package/src/sdk/primitives/metadata.ts +63 -0
  86. package/src/sdk/primitives/run.ts +81 -0
  87. package/src/sdk/primitives/sessions.test.ts +594 -0
  88. package/src/sdk/primitives/sessions.ts +328 -0
  89. package/src/sdk/runtime/executor.ts +36 -115
  90. package/src/sdk/runtime/orchestrator-entry.ts +110 -0
  91. package/src/sdk/runtime/tmux.ts +33 -0
  92. package/src/sdk/types.ts +26 -91
  93. package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +1 -0
  94. package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +1 -0
  95. package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +1 -0
  96. package/src/sdk/workflows/builtin/open-claude-design/claude/index.ts +1 -0
  97. package/src/sdk/workflows/builtin/open-claude-design/copilot/index.ts +1 -0
  98. package/src/sdk/workflows/builtin/open-claude-design/opencode/index.ts +1 -0
  99. package/src/sdk/workflows/builtin/ralph/claude/index.ts +1 -0
  100. package/src/sdk/workflows/builtin/ralph/copilot/index.ts +1 -0
  101. package/src/sdk/workflows/builtin/ralph/opencode/index.ts +1 -0
  102. package/src/sdk/workflows/index.ts +68 -51
  103. package/src/services/config/additional-instructions.ts +1 -1
  104. package/.agents/skills/test-driven-development/SKILL.md +0 -371
  105. package/.agents/skills/test-driven-development/testing-anti-patterns.md +0 -299
  106. package/dist/commands/cli/session.d.ts +0 -67
  107. package/dist/commands/cli/session.d.ts.map +0 -1
  108. package/dist/commands/cli/workflow-status.d.ts +0 -63
  109. package/dist/commands/cli/workflow-status.d.ts.map +0 -1
  110. package/dist/sdk/commander.d.ts +0 -74
  111. package/dist/sdk/commander.d.ts.map +0 -1
  112. package/dist/sdk/management-commands.d.ts +0 -42
  113. package/dist/sdk/management-commands.d.ts.map +0 -1
  114. package/dist/sdk/workflow-cli.d.ts +0 -103
  115. package/dist/sdk/workflow-cli.d.ts.map +0 -1
  116. package/dist/sdk/workflows/builtin-registry.d.ts +0 -113
  117. package/dist/sdk/workflows/builtin-registry.d.ts.map +0 -1
  118. package/src/sdk/commander.ts +0 -161
  119. package/src/sdk/workflow-cli.ts +0 -409
  120. package/src/sdk/workflows/builtin-registry.ts +0 -23
package/README.md CHANGED
@@ -9,27 +9,21 @@
9
9
  [![Bun](https://img.shields.io/badge/Bun-Runtime-f9f1e1?logo=bun&logoColor=black)](./package.json)
10
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
11
11
 
12
- **An open-source CLI and TypeScript SDK for building harnesses around your coding agent** — Claude Code, OpenCode, or GitHub Copilot CLI. Chain agent sessions into deterministic pipelines, add human-in-the-loop approval gates, dispatch **12 specialized sub-agents**, and tap **57 built-in skills** then ship it as TypeScript your whole team runs.
12
+ **Turn coding agents into reliable engineering workflows.** Atomic is an open-source CLI and TypeScript SDK for Claude Code, OpenCode, and GitHub Copilot CLI. Define the steps, guardrails, review gates, and execution environment your agent should follow, then run the workflow as TypeScript your whole team can review and reuse.
13
13
 
14
- > Define how your agent works. Start for yourself, scale to your team across GitHub, Azure DevOps (ADO), or Sapling.
14
+ > Build the workflow once. Run it across agents, repos, and teamswith GitHub, Azure DevOps (ADO), or Sapling.
15
15
 
16
16
  ---
17
17
 
18
- ## Two surfaces: CLI and SDK
19
-
20
- Atomic ships **two** things that share one orchestrator runtime. You can use either on its own or both together:
18
+ ## Why Atomic
21
19
 
22
- | | Atomic CLI | Atomic SDK |
23
- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
24
- | **What it is** | Global `atomic` binary | `@bastani/atomic/workflows` TypeScript library |
25
- | **Install** | `bun install -g @bastani/atomic` (or `install.sh` / `install.ps1`) | `bun add @bastani/atomic` inside your project |
26
- | **Entrypoint** | `atomic <command>` | `bun run src/<agent>-worker.ts` |
27
- | **Code required?** | No — everything is pre-built | Yes — you write `defineWorkflow(...)` + a 3-line composition root |
28
- | **What you get** | `atomic chat` (agent REPL), three autonomous builtins (`ralph`, `deep-research-codebase`, `open-claude-design`), session management, the live orchestrator panel, Atomic skills (`/init`, `/research-codebase`, `/create-spec`, …) | `defineWorkflow`, `createWorkflowCli`, `createRegistry`, `ctx.stage`, `s.save` / `s.transcript`, headless stages, the Commander adapter (`toCommand`, `runCli`) |
29
- | **When to reach for** | You want autonomous execution of a standard pattern out of the box, or interactive chat with your agent's full toolset | You want to encode **your** team's process — review flows, deployment gates, custom research pipelines — as TypeScript every teammate runs identically |
30
- | **Read next** | [Quick Start](#quick-start) (steps 1–3) | [Quick Start step 4](#4-build-your-own-workflow--sdk) and [Building your own atomic-powered app](#building-your-own-atomic-powered-app) |
20
+ Coding agents are great inside a single session. They can inspect code, use tools, make edits, and explain their work. The trouble starts when the task is ambiguous/complex, tied to specific outcomes/exit criteria, long-running, or tied to a large codebase: you end up reminding the agent of the process, moving output between sessions, checking whether it followed the right steps, and deciding when a human needs to review the work. Atomic turns that process into code. A workflow can branch, retry, run stages in parallel, isolate sessions, pass only the right transcript forward, pause for human approval, and run inside a devcontainer so the agent is not loose on your host machine.
31
21
 
32
- Both surfaces call the same runtime underneath (tmux/psmux session graph, provider SDKs, detach/reattach) they're two entry points, not two products. Neither depends on the other: you can `bun add @bastani/atomic` in a project without ever installing the global binary, and you can use `atomic chat` and the builtins without writing any TypeScript.
22
+ - **Start with your own process.** Automate the repetitive parts of research, product feedback, debugging, review, migrations, or PR prep. One TypeScript file, versioned with the repo.
23
+ - **Scale to your team.** Encode review gates, quality checks, and approvals so every teammate runs the same workflow instead of manually steering an agent.
24
+ - **Keep the coding agent.** Atomic adds structure around Claude Code, OpenCode, and Copilot CLI without rebuilding their file editing, tool use, MCP setup, hooks, or context handling from scratch.
25
+ - **Use natural language to get started.** Ask the `workflow-creator` skill to turn a workflow description into `defineWorkflow()` code, or let an agent use the skill when a complex task needs a repeatable workflow.
26
+ - **Control the outer loop.** Instead of trusting a black-box harness to improvise process, Atomic makes the orchestration inspectable: the agent stil uses it's harness with its native tools and context management, but the workflow, gates, handoffs, and execution graph are TypeScript you can read, edit, and version. This allows you to enhance your existing coding agent's capabilities.
33
27
 
34
28
  ---
35
29
 
@@ -39,7 +33,7 @@ Install, generate context, try Ralph, then write your own workflow — four step
39
33
 
40
34
  ### Prerequisites
41
35
 
42
- Atomic doesn't replace your coding agent or terminal — it orchestrates them. Three things have to exist on the host before a workflow can run:
36
+ Atomic doesn't replace your coding agent or terminal — it gives them a workflow to follow. Three things have to exist on the host before a workflow can run:
43
37
 
44
38
  - **[Bun](https://bun.sh/)** as the JavaScript runtime — Atomic and the SDK ship source that relies on `Bun.spawn`, native pty handling, and Bun-specific module resolution. **They do not run on Node.js.** The bootstrap installer below installs Bun for you; if you install `@bastani/atomic` manually, install Bun first.
45
39
  - **A terminal multiplexer** — every stage runs inside a detachable session on a dedicated `atomic` socket (your personal tmux is untouched). That's how workflows survive terminal disconnects, how `-d/--detach` puts a run in the background, and how `atomic session connect` reattaches later from any shell.
@@ -51,7 +45,7 @@ Atomic doesn't replace your coding agent or terminal — it orchestrates them. T
51
45
  - [GitHub Copilot CLI](https://github.com/features/copilot/cli) — run `copilot` and authenticate
52
46
  - **Windows only:** PowerShell 7+ ([install guide](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows))
53
47
 
54
- > The bootstrap installer below installs Bun and Atomic but **does not** install tmux/psmux or the coding agents. Install those separately before running any workflow — `bun run src/claude-worker.ts -n <workflow-name> -a claude` will fail loudly at stage spawn if either is missing. Using a [devcontainer](#alternative-devcontainer-recommended-for-autonomous-workflows) short-circuits all of this: the atomic feature bundles Bun + tmux + the agent CLI into the container image.
48
+ > The bootstrap installer below installs Bun and Atomic but **does not** install tmux/psmux or the coding agents. Install those separately before running any workflow — `bun run src/claude-worker.ts` will fail loudly at stage spawn if either is missing. Using a [devcontainer](#alternative-devcontainer-recommended-for-autonomous-workflows) short-circuits all of this: the atomic feature bundles Bun + tmux + the agent CLI into the container image.
55
49
 
56
50
  ### 1. Install — CLI + SDK share the same package
57
51
 
@@ -233,22 +227,52 @@ export default defineWorkflow({
233
227
  .compile();
234
228
  ```
235
229
 
236
- Wire it to a CLI in `src/claude-worker.ts` three lines:
230
+ Wire it to a CLI in `src/claude-worker.ts`. The SDK ships pure
231
+ primitives — no wrapper to opt into. Compose with your CLI library of
232
+ choice (Commander, citty, yargs, …) and call `runWorkflow`. Catch the
233
+ SDK's typed errors (`MissingDependencyError`, `SessionNotFoundError`,
234
+ …) for friendly CLI output:
237
235
 
238
236
  ```ts
239
- import { createWorkflowCli } from "@bastani/atomic/workflows";
237
+ import { Command } from "@commander-js/extra-typings";
238
+ import {
239
+ getInputSchema,
240
+ runWorkflow,
241
+ MissingDependencyError,
242
+ } from "@bastani/atomic/workflows";
240
243
  import workflow from "./workflows/review-to-merge/claude.ts";
241
244
 
242
- await createWorkflowCli(workflow).run();
245
+ const program = new Command();
246
+ for (const input of getInputSchema(workflow)) {
247
+ program.option(`--${input.name} <value>`, input.description ?? "");
248
+ }
249
+ program.action(async (rawOpts) => {
250
+ try {
251
+ await runWorkflow({ workflow, inputs: rawOpts as Record<string, string> });
252
+ } catch (err) {
253
+ if (err instanceof MissingDependencyError) {
254
+ console.error(`Missing dependency: ${err.dependency}. Install it and retry.`);
255
+ process.exit(1);
256
+ }
257
+ throw err;
258
+ }
259
+ });
260
+ await program.parseAsync();
243
261
  ```
244
262
 
245
263
  Run it:
246
264
 
247
265
  ```bash
248
- bun run src/claude-worker.ts -n review-to-merge -a claude
266
+ bun run src/claude-worker.ts --target_branch=main
249
267
  ```
250
268
 
251
- That's the full shape — one workflow file, one three-line composition root. `createWorkflowCli` handles named dispatch (`-n/--name` + `-a/--agent`), the `--<input>` flags declared by your workflow, detached execution, and the interactive picker. Pass an array (`createWorkflowCli([claude, copilot])`) for multi-agent or multi-workflow apps; the file stays three lines. See [Workflow SDK](#workflow-sdk--build-your-own-deterministic-harness) for parallel stages, input schemas, headless stages, and the full API reference.
269
+ That's the full shape — one workflow file, one composition root. The
270
+ SDK exposes primitives (`runWorkflow`, `getInputSchema`, `listWorkflows`,
271
+ `getName`, `getAgent`, `validateInputs`, `listSessions`, …) and the
272
+ developer composes them into whatever CLI shape they prefer. See
273
+ [Workflow SDK](#workflow-sdk--build-reliable-engineering-workflows) for
274
+ parallel stages, input schemas, headless stages, and the full API
275
+ reference.
252
276
 
253
277
  ### Managing sessions
254
278
 
@@ -270,42 +294,42 @@ atomic workflow -n ralph -a claude -d "build the auth module" # returns immedi
270
294
  atomic workflow session connect atomic-wf-claude-ralph-<id> # attach later
271
295
  ```
272
296
 
273
- Detached mode is what you want for scripted / CI automation and long-running tasks — the orchestrator keeps running on the atomic tmux socket regardless of your terminal.
297
+ Detached mode is what you want for scripted / CI automation and long-running tasks — the workflow keeps running on the atomic tmux socket regardless of your terminal.
274
298
 
275
299
  ---
276
300
 
277
- ## Why Atomic
301
+ ## Two surfaces: CLI and SDK
278
302
 
279
- Better models make harnesses **more** important, not less. The more you trust an agent to execute complex tasks, the more value you get from defining exactly **what** it should execute, in **what order**, with **what checks** along the way. The harness is the durable layer models keep improving underneath it, but your process stays the same.
303
+ Atomic ships **two** things that share one workflow runtime. You can use either on its own or both together:
280
304
 
281
- - **Start for yourself.** Automate the repetitive parts of your own workflow — research a codebase, add monitoring, generate specs. One TypeScript file, one afternoon.
282
- - **Scale to your team.** Encode your team's review process, deployment gates, and quality checks as TypeScript every member runs identically — versioned, testable, reproducible.
283
- - **Work across agents.** Write a harness once, run it on Claude Code, OpenCode, or Copilot CLI with a flag change.
305
+ | | Atomic CLI | Atomic SDK |
306
+ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
307
+ | **What it is** | Global `atomic` binary | `@bastani/atomic/workflows` TypeScript library |
308
+ | **Install** | `bun install -g @bastani/atomic` (or `install.sh` / `install.ps1`) | `bun add @bastani/atomic` inside your project |
309
+ | **Entrypoint** | `atomic <command>` | `bun run src/<agent>-worker.ts` |
310
+ | **Code required?** | No — everything is pre-built. You can also ask the agent inside `atomic chat` to use the `workflow-creator` skill, decide when a complex task needs its own workflow, and build/run that workflow on the fly. | No to start — describe the workflow in natural language and use the `workflow-creator` skill to generate it. Then refine it in natural language or edit the TypeScript workflow and composition root directly, with full visibility into exactly what will run. |
311
+ | **What you get** | `atomic chat` (agent REPL), three autonomous built-in workflows (`ralph`, `deep-research-codebase`, `open-claude-design`), session management, the live workflow panel, Atomic skills (`/init`, `/research-codebase`, `/create-spec`, …) | `defineWorkflow`, `createRegistry`, `runWorkflow`, metadata accessors (`getName`, `getInputSchema`, …), session primitives (`listSessions`, `getSessionStatus`, `attachSession` / `detachSession`, `nextWindow` / `previousWindow` / `gotoOrchestrator`), typed errors (`MissingDependencyError`, `SessionNotFoundError`, …), `ctx.stage`, `s.save` / `s.transcript`, headless stages |
312
+ | **When to reach for** | You want autonomous execution of a standard pattern out of the box, interactive chat with your agent's full toolset, or a CLI agent that can create a purpose-built workflow before doing complex work. | You want to control the outer loop yourself — review flows, deployment gates, custom research pipelines — with full visibility into the TypeScript your team will run identically. |
313
+ | **Read next** | [Quick Start](#quick-start) (steps 1–3) | [Quick Start step 4](#4-build-your-own-workflow--sdk) and [Building your own atomic-powered app](#building-your-own-atomic-powered-app) |
284
314
 
285
- ### Example use cases
315
+ Both surfaces call the same runtime underneath (tmux/psmux session graph, provider SDKs, detach/reattach) — they're two entry points, not two products. Neither depends on the other: you can `bun add @bastani/atomic` in a project without ever installing the global binary, and you can use `atomic chat` and the built-in workflows without writing any TypeScript.
286
316
 
287
- These are shapes you'd **author** with `defineWorkflow` and then run from your own `src/<agent>-worker.ts` — see [step 4 of Quick Start](#4-build-your-own-workflow) for the three-line entrypoint. Atomic ships three built-in workflows (`ralph`, `deep-research-codebase`, `open-claude-design`); everything else is yours to define.
317
+ ## Example use cases
288
318
 
289
- **Add production monitoring.** Research observability gaps, implement missing metrics and health checks, review the changes.
319
+ These are workflows you'd author with `defineWorkflow` and run from your own `src/<agent>-worker.ts` — see [step 4 of Quick Start](#4-build-your-own-workflow--sdk) for the three-line entrypoint. Atomic ships three built-in workflows (`ralph`, `deep-research-codebase`, `open-claude-design`); everything else is yours to define.
290
320
 
291
- ```bash
292
- bun run src/claude-worker.ts -n observability -a claude "add Prometheus metrics and health checks to all API endpoints"
293
- ```
294
-
295
- **Parallel UX testing with 50 personas.** Spin up 50 agents, each with a distinct persona (power user, accessibility-dependent, non-technical stakeholder), each using [Playwright](#built-in-skills) to test your app.
296
-
297
- ```bash
298
- bun run src/claude-worker.ts -n ux-personas -a claude --personas=50
299
- ```
300
-
301
- **Review-to-merge pipeline.** The workflow from [step 4](#4-build-your-own-workflow) above — reviews code, runs CI in parallel, opens a PR, notifies Slack, waits for approval, merges.
321
+ - **Review-to-merge pipeline.** Review code, run CI in parallel, open a PR, notify Slack, wait for approval, merge.
322
+ - **Support ticket to draft PR.** Reproduce the issue, find the root cause, try a fix in a sandbox, run tests, pause for review.
323
+ - **Production alert investigation.** Pull the failing trace, inspect recent commits, rank likely causes, then draft a fix or page the on-call with evidence.
324
+ - **Parallel UX testing.** Run many persona-specific agents against the same feature, aggregate structured feedback, and turn selected issues into tasks.
325
+ - **Large migration or refactor.** Research the codebase, split the work into safe batches, run implementation and review passes, and keep artifacts for later runs.
302
326
 
303
327
  ---
304
328
 
305
329
  ## Table of Contents
306
330
 
307
331
  - [Atomic](#atomic)
308
- - [Two surfaces: CLI and SDK](#two-surfaces-cli-and-sdk)
332
+ - [Why Atomic](#why-atomic)
309
333
  - [Quick Start](#quick-start)
310
334
  - [Prerequisites](#prerequisites)
311
335
  - [1. Install — CLI + SDK share the same package](#1-install--cli--sdk-share-the-same-package)
@@ -313,16 +337,16 @@ bun run src/claude-worker.ts -n ux-personas -a claude --personas=50
313
337
  - [3. Try Ralph — CLI (autonomous coding)](#3-try-ralph--cli-autonomous-coding)
314
338
  - [4. Build your own workflow — SDK](#4-build-your-own-workflow--sdk)
315
339
  - [Managing sessions](#managing-sessions)
316
- - [Why Atomic](#why-atomic)
317
- - [Example use cases](#example-use-cases)
340
+ - [Two surfaces: CLI and SDK](#two-surfaces-cli-and-sdk)
341
+ - [Example use cases](#example-use-cases)
318
342
  - [Table of Contents](#table-of-contents)
319
343
  - [Security: Workflow Permissions Model](#security-workflow-permissions-model)
320
344
  - [Core Features](#core-features)
321
345
  - [Multi-Agent Support](#multi-agent-support)
322
- - [Workflow SDK — Build Your Own Deterministic Harness](#workflow-sdk--build-your-own-deterministic-harness)
346
+ - [Workflow SDK — Build Reliable Engineering Workflows](#workflow-sdk--build-reliable-engineering-workflows)
323
347
  - [Runnable examples shipped with the repo](#runnable-examples-shipped-with-the-repo)
324
348
  - [Builder API](#builder-api)
325
- - [WorkflowContext (`ctx`) — top-level orchestrator](#workflowcontext-ctx--top-level-orchestrator)
349
+ - [WorkflowContext (`ctx`) — top-level workflow context](#workflowcontext-ctx--top-level-workflow-context)
326
350
  - [SessionContext (`s`) — inside each session callback](#sessioncontext-s--inside-each-session-callback)
327
351
  - [Session Options (`SessionRunOptions`)](#session-options-sessionrunoptions)
328
352
  - [Saving Transcripts](#saving-transcripts)
@@ -334,7 +358,7 @@ bun run src/claude-worker.ts -n ux-personas -a claude --personas=50
334
358
  - [Containerized Execution](#containerized-execution)
335
359
  - [Specialized Sub-Agents](#specialized-sub-agents)
336
360
  - [Built-in Skills](#built-in-skills)
337
- - [Workflow Orchestrator Panel](#workflow-orchestrator-panel)
361
+ - [Workflow Panel](#workflow-panel)
338
362
  - [Commands Reference](#commands-reference)
339
363
  - [CLI Commands](#cli-commands)
340
364
  - [Global Flags](#global-flags)
@@ -346,8 +370,8 @@ bun run src/claude-worker.ts -n ux-personas -a claude --personas=50
346
370
  - [Building your own atomic-powered app](#building-your-own-atomic-powered-app)
347
371
  - [One factory, three input shapes](#one-factory-three-input-shapes)
348
372
  - [One method: `run()`](#one-method-run)
349
- - [Embedding under a parent CLI — `toCommand` + `runCli`](#embedding-under-a-parent-cli--tocommand--runcli)
350
- - [`entry` — for bundled apps and test harnesses](#entry--for-bundled-apps-and-test-harnesses)
373
+ - [Embedding under a parent CLI — `runWorkflow` inside any Commander tree](#embedding-under-a-parent-cli--runworkflow-inside-any-commander-tree)
374
+ - [`entry` — for bundled apps and tests](#entry--for-bundled-apps-and-tests)
351
375
  - [Registry rules](#registry-rules)
352
376
  - [Input precedence](#input-precedence)
353
377
  - [Builtin workflows via the `atomic` CLI](#builtin-workflows-via-the-atomic-cli)
@@ -395,21 +419,23 @@ Atomic works across **three production coding agents** — switch with a flag an
395
419
 
396
420
  Each agent gets its own configuration directory (`.claude/`, `.opencode/`, `.github/`), skills, and context files — all managed by Atomic.
397
421
 
398
- ### Workflow SDK — Build Your Own Deterministic Harness
422
+ ### Workflow SDK — Build Reliable Engineering Workflows
399
423
 
400
- The Workflow SDK (`@bastani/atomic/workflows`) lets you encode your team's process as TypeScript — spawn agent sessions dynamically with native control flow (`for`, `if`, `Promise.all()`), and watch them appear in a live graph as they execute.
424
+ The Workflow SDK (`@bastani/atomic/workflows`) lets you encode your team's process as TypeScript — spawn agent sessions dynamically with native control flow (`for`, `if`, `Promise.all()`), pass state explicitly, and watch each stage appear in a live graph as it runs.
401
425
 
402
- Set up a workflow project (`bun init && bun add @bastani/atomic`), define your workflow with `defineWorkflow`, then bind it to a CLI with `createWorkflowCli(definition)` (single workflow) or `createWorkflowCli(registry)` (many workflows):
426
+ Set up a workflow project (`bun init && bun add @bastani/atomic`), define your workflow with `defineWorkflow`, then call `runWorkflow({ workflow, inputs })` from inside whatever CLI library you prefer (Commander, citty, yargs, an OpenTUI app, …). The SDK ships pure primitives — no opinionated wrapper:
403
427
 
404
428
  ```bash
405
- bun run src/claude-worker.ts -n <workflow-name> -a claude --prompt "describe this project"
429
+ bun run src/claude-worker.ts --prompt="describe this project"
406
430
  ```
407
431
 
408
- See [step 4 of Quick Start](#4-build-your-own-workflow) for a complete review-to-merge example. More examples and the full API reference below.
432
+ See [step 4 of Quick Start](#4-build-your-own-workflow--sdk) for a complete review-to-merge example. More examples and the full API reference below.
409
433
 
410
434
  #### Runnable examples shipped with the repo
411
435
 
412
- The [`examples/`](./examples) directory contains small, complete user apps you can run directly. Most subdirectories ship `claude/`, `copilot/`, and `opencode/` variants plus one agent-scoped worker file per agent — `claude-worker.ts`, `copilot-worker.ts`, `opencode-worker.ts` — each a three-line `createWorkflowCli(workflow).run()` entrypoint. `multi-workflow/` and `commander-embed/` use a single `cli.ts` instead, to demonstrate multi-workflow dispatch and Commander embedding respectively.
436
+ The [`examples/`](./examples) directory contains small, complete user apps you can run directly. Most subdirectories ship `claude/`, `copilot/`, and `opencode/` variants plus one agent-scoped worker file per agent — `claude-worker.ts`, `copilot-worker.ts`, `opencode-worker.ts` — each a small Commander entrypoint that calls `runWorkflow({ workflow, inputs })`. `multi-workflow/` and `commander-embed/` use a single `cli.ts` instead, to demonstrate multi-workflow dispatch and Commander embedding respectively.
437
+
438
+ **Design principle — when does `-a/--agent` belong on your CLI?** Each agent-scoped worker file imports a single workflow pinned to one agent (`import workflow from "./claude/index.ts"`), so there's nothing to disambiguate — no `-a` flag. Only reach for `-a/--agent` when one CLI dispatches across workflows that exist in multiple agent variants — e.g. a `cli.ts` that registers `hello` for claude *and* copilot. The atomic CLI itself uses `-a` for exactly that reason: its builtin registry has cross-agent variants of `ralph`, `deep-research-codebase`, and `open-claude-design`.
413
439
 
414
440
  | Example | What it demonstrates |
415
441
  | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
@@ -421,29 +447,28 @@ The [`examples/`](./examples) directory contains small, complete user apps you c
421
447
  | `hil-favorite-color-headless` | HIL pause inside a headless stage |
422
448
  | `structured-output-demo` | Per-SDK structured output (JSON-schema validation, Zod) |
423
449
  | `reviewer-tool-test` | Custom reviewer tool wiring (Copilot — copilot-worker.ts only) |
424
- | `review-fix-loop` | Draft → loop(review → fix) with bounded iterations and early exit on a `CLEAN` verdict — the quintessential harness pattern, showing how a stage's return value (`handle.result`) drives TypeScript control flow |
425
- | `multi-workflow` | Two Claude workflows under one `cli.ts` — `-n/--name` dispatch, per-workflow `--<input>` flag union, and the interactive picker. Shows the array form (`createWorkflowCli([hello, goodbye])`) and the `createRegistry().register(...)` variant side by side. |
426
- | `commander-embed` | Mount an atomic workflow under a parent Commander CLI with `toCommand(cli, "greet")`, alongside a plain Commander sibling command. `runCli` replaces `program.parseAsync()` and transparently handles detached orchestrator re-entry. |
450
+ | `review-fix-loop` | Draft → loop(review → fix) with bounded iterations and early exit on a `CLEAN` verdict — a reliable review gate showing how a stage's return value (`handle.result`) drives TypeScript control flow |
451
+ | `multi-workflow` | Two Claude workflows under one `cli.ts` — uses `listWorkflows(registry)` to register one Commander subcommand per workflow with each workflow's declared inputs as `--<flag>` options. |
452
+ | `commander-embed` | Mount an atomic workflow under a parent Commander CLI by calling `runWorkflow({ workflow, inputs })` inside a Commander action, alongside a plain Commander sibling command. No re-entry boilerplate the SDK ships its own orchestrator entry script. |
453
+ | `pane-navigation` | Driver CLI for the SDK pane-navigation primitives (`nextWindow`, `previousWindow`, `gotoOrchestrator`, `attachSession`, `detachSession`). Spawns a 3-stage workflow detached and exposes `start / list / status / next / prev / home / attach / stop` subcommands. Catches `SessionNotFoundError` for friendly errors. |
427
454
 
428
455
  Run any of them with:
429
456
 
430
457
  ```bash
431
- # Single-workflow examplesone worker file per agent
432
- bun run examples/<name>/<agent>-worker.ts -n <workflow-name> -a <agent> [--field=value | "<prompt>"]
433
-
434
- # e.g.
435
- bun run examples/hello-world/claude-worker.ts -n hello-world -a claude --greeting="Hello" --style=casual
436
- bun run examples/sequential-describe-summarize/claude-worker.ts -n sequential-describe-summarize -a claude --topic="Bun"
437
- bun run examples/review-fix-loop/claude-worker.ts -n review-fix-loop -a claude --topic="adopting Bun" --max_iterations=3
438
- bun run examples/headless-test/copilot-worker.ts -n headless-test -a copilot "TypeScript"
439
-
440
- # Multi-workflow — one cli.ts, dispatch by `-n/--name`
441
- bun run examples/multi-workflow/cli.ts -n hello -a claude --who=Alex
442
- bun run examples/multi-workflow/cli.ts -n goodbye -a claude --tone=melodramatic
443
- bun run examples/multi-workflow/cli.ts -a claude # interactive picker (TTY)
444
-
445
- # Commander embedding — workflow mounted as a subcommand under a parent CLI
446
- bun run examples/commander-embed/cli.ts greet -n greet -a claude --who=Alex
458
+ # Single-workflow workersagent is pinned by which file you run, so no `-a` flag.
459
+ # Inputs map to `--<input>=<value>` flags; if the workflow declares no inputs,
460
+ # trailing positional tokens become the prompt.
461
+ bun run examples/hello-world/claude-worker.ts --greeting="Hello" --style=casual
462
+ bun run examples/sequential-describe-summarize/claude-worker.ts --topic="Bun"
463
+ bun run examples/review-fix-loop/claude-worker.ts --topic="adopting Bun" --max_iterations=3
464
+ bun run examples/headless-test/copilot-worker.ts --prompt="TypeScript"
465
+
466
+ # Multi-workflow CLI — one cli.ts, one Commander subcommand per registered workflow.
467
+ bun run examples/multi-workflow/cli.ts hello --who=Alex
468
+ bun run examples/multi-workflow/cli.ts goodbye --tone=melodramatic
469
+
470
+ # Commander embedding — atomic workflow mounted as `greet` alongside plain Commander commands.
471
+ bun run examples/commander-embed/cli.ts greet --who=Alex
447
472
  bun run examples/commander-embed/cli.ts status # sibling Commander command
448
473
  bun run examples/commander-embed/cli.ts --help # all commands
449
474
  ```
@@ -583,13 +608,11 @@ export default defineWorkflow({
583
608
  .compile();
584
609
  ```
585
610
 
586
- Wire it into `src/claude-worker.ts` (three lines — see [step 4 of Quick Start](#4-build-your-own-workflow)) and run it:
611
+ Wire it into `src/claude-worker.ts` (three lines — see [step 4 of Quick Start](#4-build-your-own-workflow--sdk)) and run it:
587
612
 
588
613
  ```bash
589
614
  # Scriptable; CI-friendly
590
615
  bun run src/claude-worker.ts \
591
- -n gen-spec \
592
- -a claude \
593
616
  --research_doc=research/docs/2026-04-11-auth.md \
594
617
  --focus=standard
595
618
  ```
@@ -662,15 +685,17 @@ The graph shows `seed → merge` — headless stages are transparent to the topo
662
685
  | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
663
686
  | **Dynamic session spawning** | `ctx.stage()` spawns sessions at runtime — each gets its own tmux window and graph node |
664
687
  | **Native TypeScript control flow** | Use `for`, `if/else`, `Promise.all()`, `try/catch` — no framework DSL |
688
+ | **Review gates and approvals** | Pause for human input, run structured review stages, and decide whether the next stage should continue |
665
689
  | **Session return values** | Session callbacks can return data: `const h = await ctx.stage(...); h.result` |
666
690
  | **Transcript passing** | Access prior output via handle (`s.transcript(handle)`) or name (`s.transcript("name")`) |
667
691
  | **Declared input schemas** | Add an `inputs: [...]` array and the CLI materialises `--<field>=<value>` flags with built-in validation |
668
- | **Interactive picker** | `atomic workflow -a <agent>` is the explicit no-`-n` discovery path; direct runs use `-n <name>` |
692
+ | **Interactive picker** | `atomic workflow -a <agent>` is the explicit no-`-n` discovery path; direct runs use `-n <name>` |
669
693
  | **Nested sub-sessions** | `s.stage()` inside a callback spawns child sessions — visible as nested graph nodes |
670
694
  | **Auto-inferred graph** | Topology derived from `await` / `Promise.all` patterns — no annotations |
671
695
  | **Provider-agnostic** | Write raw SDK code for Claude, Copilot, or OpenCode inside each callback |
672
696
  | **Live graph visualization** | Sessions appear in the TUI graph as they spawn — loops and conditionals visible in real time |
673
697
  | **Background (headless) stages** | `headless: true` runs in-process without a tmux window — invisible in graph, tracked by statusline counter, identical callback API |
698
+ | **Token-aware handoffs** | Save transcripts to disk and pass paths or distilled outputs forward instead of stuffing every stage with the full history |
674
699
 
675
700
  **Deterministic execution guarantees:**
676
701
 
@@ -682,7 +707,7 @@ Workflows are deterministic by design — the same definition produces the same
682
707
  - **Isolated context windows** — Each session runs in its own tmux pane with a fresh context. Data flows only through explicit `ctx.transcript()` / `ctx.getMessages()` calls.
683
708
  - **Persisted artifacts** — Every session writes messages, transcript, and metadata to disk — a complete, inspectable execution record.
684
709
 
685
- Variance comes only from the LLM's responses, not from the harness.
710
+ Variance comes from the LLM's responses, not from a changing workflow.
686
711
 
687
712
  > Ask Atomic to build workflows for you: `Use your workflow-creator skill to create a workflow that plans, implements, and reviews a feature.`
688
713
 
@@ -697,7 +722,7 @@ Variance comes only from the LLM's responses, not from the harness.
697
722
  | `.run(async (ctx) => { ... })` | Set the workflow's entry point — `ctx` is a `WorkflowContext` |
698
723
  | `.compile()` | **Required** — terminal method that seals the workflow definition |
699
724
 
700
- #### WorkflowContext (`ctx`) — top-level orchestrator
725
+ #### WorkflowContext (`ctx`) — top-level workflow context
701
726
 
702
727
  | Property | Type | Description |
703
728
  | ---------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -759,7 +784,7 @@ The runtime auto-creates `s.client` and `s.session` — use them directly inside
759
784
  2. Session names must be unique within a workflow run
760
785
  3. `transcript()` / `getMessages()` only access completed sessions (callback returned + saves flushed)
761
786
  4. Each session runs in its own tmux window with the chosen agent
762
- 5. Bind a workflow to a CLI with `createWorkflowCli(workflow)` (single workflow) or `createWorkflowCli(createRegistry().register(...))` (many workflows)
787
+ 5. Run a workflow by calling `runWorkflow({ workflow, inputs })` from inside any CLI library (Commander, citty, yargs, …). Use `listWorkflows(registry)` to iterate when registering multiple workflows.
763
788
  6. Set up your workflow project with `bun init && bun add @bastani/atomic`
764
789
  7. Background (headless) stages use the same callback API — `s.client`, `s.session`, `s.save()`, return values all work identically
765
790
 
@@ -818,7 +843,7 @@ The [Ralph Method](https://ghuntley.com/ralph/) enables **multi-hour autonomous
818
843
  **How Ralph works:**
819
844
 
820
845
  1. **Task Decomposition** — A `planner` sub-agent breaks your spec into a task list with dependency tracking, stored in SQLite (WAL mode for parallel access).
821
- 2. **Orchestration** — An `orchestrator` retrieves the task list, validates the dependency graph, and dispatches `worker` sub-agents for ready tasks.
846
+ 2. **Execution** — An `orchestrator` retrieves the task list, validates the dependency graph, and dispatches `worker` sub-agents for ready tasks.
822
847
  3. **Review & Debug** — A `reviewer` audits the implementation with structured JSON output; if P0–P2 findings exist, a `debugger` investigates root causes and feeds back to the planner on the next iteration.
823
848
 
824
849
  **Loop config:** Up to **10 iterations**. Exits early after **2 consecutive clean reviews** (zero actionable findings). P3 (minor) findings are non-actionable.
@@ -917,16 +942,16 @@ Skills are structured capability modules that give agents best practices and reu
917
942
  <details>
918
943
  <summary><b>Development workflows</b></summary>
919
944
 
920
- | Skill | Description |
921
- | ------------------------- | --------------------------------------------------------------------------- |
922
- | `init` | Generate `CLAUDE.md` and `AGENTS.md` by exploring the codebase |
923
- | `research-codebase` | Analyze codebase with parallel sub-agents and document findings |
924
- | `create-spec` | Create detailed execution plans from research documents |
925
- | `workflow-creator` | Create multi-agent workflows using the session-based `defineWorkflow()` API |
926
- | `explain-code` | Explain code functionality in detail using DeepWiki |
927
- | `find-skills` | Discover and install agent skills from the community |
928
- | `test-driven-development` | Write tests first; includes a testing anti-patterns guide |
929
- | `prompt-engineer` | Create, improve, and optimize prompts using best practices |
945
+ | Skill | Description |
946
+ | ------------------- | --------------------------------------------------------------------------- |
947
+ | `init` | Generate `CLAUDE.md` and `AGENTS.md` by exploring the codebase |
948
+ | `research-codebase` | Analyze codebase with parallel sub-agents and document findings |
949
+ | `create-spec` | Create detailed execution plans from research documents |
950
+ | `workflow-creator` | Create multi-agent workflows using the session-based `defineWorkflow()` API |
951
+ | `explain-code` | Explain code functionality in detail using DeepWiki |
952
+ | `find-skills` | Discover and install agent skills from the community |
953
+ | `tdd` | Write tests first; includes a testing anti-patterns guide |
954
+ | `prompt-engineer` | Create, improve, and optimize prompts using best practices |
930
955
 
931
956
  </details>
932
957
 
@@ -1025,9 +1050,9 @@ Skills are structured capability modules that give agents best practices and reu
1025
1050
 
1026
1051
  Skills are auto-invoked when relevant. Run `ls .agents/skills/` for the complete, current list on disk.
1027
1052
 
1028
- ### Workflow Orchestrator Panel
1053
+ ### Workflow Panel
1029
1054
 
1030
- During `atomic workflow` execution, Atomic renders a live orchestrator panel built on [OpenTUI](https://github.com/anomalyco/opentui) over the workflow's tmux session graph. It shows:
1055
+ During `atomic workflow` execution, Atomic renders a live workflow panel built on [OpenTUI](https://github.com/anomalyco/opentui) over the workflow's tmux session graph. It shows:
1031
1056
 
1032
1057
  - **Session graph** — Nodes per `.stage()` with status (pending / running / completed / failed) and edges for sequential / parallel dependencies
1033
1058
  - **Task list tracking** — Ralph's decomposed task list with dependency arrows, updated in real time
@@ -1038,7 +1063,7 @@ During `atomic chat`, there is no Atomic-owned TUI — `atomic chat -a <agent>`
1038
1063
 
1039
1064
  | Context | UI provider |
1040
1065
  | -------------------------------------- | ----------------------------------------------------------- |
1041
- | `atomic workflow -n <name> -a <agent>` | Atomic (orchestrator panel + tmux session graph) |
1066
+ | `atomic workflow -n <name> -a <agent>` | Atomic (workflow panel + tmux session graph) |
1042
1067
  | `atomic chat -a <agent>` | The native agent CLI (Claude Code / OpenCode / Copilot CLI) |
1043
1068
 
1044
1069
  ---
@@ -1047,16 +1072,16 @@ During `atomic chat`, there is no Atomic-owned TUI — `atomic chat -a <agent>`
1047
1072
 
1048
1073
  ### CLI Commands
1049
1074
 
1050
- | Command | Description |
1051
- | ------------------------------- | --------------------------------------------------------------- |
1052
- | `atomic chat` | Spawn the native agent CLI inside a tmux session |
1053
- | `atomic workflow` | Run a named multi-session workflow with the Atomic orchestrator panel |
1054
- | `atomic workflow list` | List available workflows, grouped by source |
1055
- | `atomic session list` | List all running sessions on the atomic tmux socket |
1056
- | `atomic session connect [name]` | Attach to a session (interactive picker when no name given) |
1057
- | `atomic session kill [name]` | Kill a session by name, or all sessions when no name is given |
1058
- | `atomic completions <shell>` | Output shell completion script (bash, zsh, fish, powershell) |
1059
- | `atomic config set <k> <v>` | Set configuration values (supports `telemetry` and `scm`) |
1075
+ | Command | Description |
1076
+ | ------------------------------- | ----------------------------------------------------------------- |
1077
+ | `atomic chat` | Spawn the native agent CLI inside a tmux session |
1078
+ | `atomic workflow` | Run a named multi-session workflow with the Atomic workflow panel |
1079
+ | `atomic workflow list` | List available workflows, grouped by source |
1080
+ | `atomic session list` | List all running sessions on the atomic tmux socket |
1081
+ | `atomic session connect [name]` | Attach to a session (interactive picker when no name given) |
1082
+ | `atomic session kill [name]` | Kill a session by name, or all sessions when no name is given |
1083
+ | `atomic completions <shell>` | Output shell completion script (bash, zsh, fish, powershell) |
1084
+ | `atomic config set <k> <v>` | Set configuration values (supports `telemetry` and `scm`) |
1060
1085
 
1061
1086
  #### Global Flags
1062
1087
 
@@ -1113,7 +1138,7 @@ atomic chat -a claude --verbose # forward --verbose to claude
1113
1138
 
1114
1139
  | Flag | Description |
1115
1140
  | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
1116
- | `-n, --name <name>` | Workflow name (required for direct runs; omit only for the interactive picker) |
1141
+ | `-n, --name <name>` | Workflow name (required for direct runs; omit only for the interactive picker) |
1117
1142
  | `-a, --agent <name>` | Agent: `claude`, `opencode`, `copilot` |
1118
1143
  | `-d, --detach` | Start the workflow in the background without attaching — ideal for scripted / CI runs; attach later with `atomic workflow session connect <name>` |
1119
1144
  | `--<field>=<value>` | Structured input for workflows that declare an `inputs` schema (also accepts `--<field> <value>`) |
@@ -1137,7 +1162,7 @@ atomic workflow -n open-claude-design -a claude \
1137
1162
  --prompt="a dashboard for monitoring API latency" \
1138
1163
  --output-type=prototype
1139
1164
 
1140
- # 5. Run detached — orchestrator runs in the background; prints the session name
1165
+ # 5. Run detached — workflow runs in the background; prints the session name
1141
1166
  # and returns immediately. Attach any time with `atomic workflow session connect`.
1142
1167
  atomic workflow -n ralph -a claude -d "build a REST API for user management"
1143
1168
  ```
@@ -1212,150 +1237,160 @@ Native slash commands (`/help`, `/clear`, `/compact`, `/model`, `/theme`, `/agen
1212
1237
 
1213
1238
  `@bastani/atomic/workflows` is a library, not just a CLI. Use it directly to build your own TypeScript app that runs your team's workflows.
1214
1239
 
1215
- > **SDK-only users:** you don't need the global `atomic` binary, but you still need the runtime prerequisites — **[Bun](https://bun.sh/) (the SDK does not run on Node.js)**, a terminal multiplexer (tmux on macOS/Linux, psmux on Windows), and at least one authenticated coding agent CLI (`claude`, `opencode`, or `copilot`). See [Prerequisites](#prerequisites) for the "why" and install commands. The SDK spawns the agent CLI at each stage and wraps it in a detachable multiplexer session — those are orchestration primitives the SDK doesn't embed.
1240
+ > **SDK-only users:** you don't need the global `atomic` binary, but you still need the runtime prerequisites — **[Bun](https://bun.sh/) (the SDK does not run on Node.js)**, a terminal multiplexer (tmux on macOS/Linux, psmux on Windows), and at least one authenticated coding agent CLI (`claude`, `opencode`, or `copilot`). See [Prerequisites](#prerequisites) for the "why" and install commands. The SDK spawns the agent CLI at each stage and wraps it in a detachable multiplexer session.
1216
1241
  >
1217
- > **Management commands ship natively.** `createWorkflowCli` auto-registers `session` and `status` subcommands on every worker CLI by default, so `bun run src/claude-worker.ts session list`, `… status <id>`, `… session connect <id>`, and `… session kill <id> -y` all work with zero extra code. Sessions live on the shared `atomic` tmux socket, so the worker CLI, the global `atomic` binary, and `bunx atomic` (for SDK-only installs) all see the same runtime state. Opt out with `createWorkflowCli(workflow, { includeManagementCommands: false })` when you want a minimal CLI or are embedding under a parent Commander program that owns session management. The names `session` and `status` are reserved — workflow inputs with those names throw at `defineWorkflow` time to prevent flag collisions.
1242
+ > **Session management primitives.** The SDK exposes `listSessions`, `getSession`, `stopSession`, `attachSession`, `detachSession`, `getSessionStatus`, `getSessionTranscript`, plus pane-navigation verbs `nextWindow` / `previousWindow` / `gotoOrchestrator` wire them into your CLI's `session list`, `status`, etc. subcommands as you see fit. Sessions live on the shared `atomic` tmux socket, so a worker CLI built on the primitives, the global `atomic` binary, and `bunx atomic` all see the same runtime state.
1243
+ >
1244
+ > **Typed errors.** Every error path the SDK throws — missing tmux/psmux/bun, unknown session id, missing `.compile()`, invalid workflow file, `minSDKVersion` mismatch — is a typed class (`MissingDependencyError`, `SessionNotFoundError`, `WorkflowNotCompiledError`, `InvalidWorkflowError`, `IncompatibleSDKError`). Catch them with `instanceof` to render friendly CLI output without parsing message text. See `examples/pane-navigation/cli.ts` for a worked example.
1218
1245
 
1219
- ### One factory, three input shapes
1246
+ ### Primitives, not a wrapper
1220
1247
 
1221
- `createWorkflowCli` is the single factory. Pick whichever input shape matches how you organize your workflows:
1248
+ The SDK ships pure functions you compose into whatever CLI shape you want:
1222
1249
 
1223
- | Input | When to use |
1224
- | ------------------------------- | ---------------------------------------------------------------------------------------------------- |
1225
- | `createWorkflowCli(workflow)` | One workflow. Direct runs still use `-n/--name` + `-a/--agent`; the CLI exposes only that workflow's declared `--<input>` flags. |
1226
- | `createWorkflowCli([wf1, wf2])` | Multiple workflows inline. Uses the same `-n/--name` + `-a/--agent` dispatch and the interactive picker. |
1227
- | `createWorkflowCli(registry)` | Dynamic composition (loop-register, conditional registration). Same runtime shape as the array form. |
1250
+ | Primitive | Purpose |
1251
+ | ----------------------- | ------------------------------------------------------------------------------------------------------ |
1252
+ | `defineWorkflow` | Author a workflow with `.for(agent).run(...).compile()`. Pass `source: import.meta.path`. |
1253
+ | `createRegistry` | Build an immutable registry of workflows for iteration / lookup. |
1254
+ | `listWorkflows(reg)` | Snapshot every workflow in a registry. |
1255
+ | `getWorkflow(reg, …)` | Resolve `(agent, name)` → workflow. |
1256
+ | `getName / getAgent / getInputSchema / getDescription / getSource / getMinSDKVersion` | Read workflow metadata. |
1257
+ | `validateInputs(wf, raw)` | Run the same validation pipeline atomic uses (required, defaults, enum, integer). |
1258
+ | `runWorkflow({ workflow, inputs, detach? })` | Spawn the orchestrator tmux session and (optionally) attach. Resolves with `{ id, tmuxSessionName }`. |
1259
+ | `listSessions / getSession / stopSession / attachSession / detachSession` | Manage running tmux sessions on the shared atomic socket. |
1260
+ | `getSessionStatus / getSessionTranscript` | Read the orchestrator-written status snapshot or per-session messages from disk. |
1261
+ | `nextWindow / previousWindow / gotoOrchestrator` | **Pane navigation** — pure tmux verbs that update the session's current-window pointer. Never auto-attach; an attached client sees the change live, otherwise a subsequent `attachSession` lands on the new window. |
1262
+ | `MissingDependencyError / SessionNotFoundError / WorkflowNotCompiledError / InvalidWorkflowError / IncompatibleSDKError` | **Typed errors** thrown by the primitives above. Catch with `instanceof` to render friendly CLI messages without parsing message text. |
1228
1263
 
1229
- **Single workflow (most common)** — one file, three lines:
1264
+ **Single workflow (most common):**
1230
1265
 
1231
1266
  ```ts
1232
1267
  // src/claude-worker.ts
1233
- import { createWorkflowCli } from "@bastani/atomic/workflows";
1268
+ import { Command } from "@commander-js/extra-typings";
1269
+ import { getInputSchema, runWorkflow } from "@bastani/atomic/workflows";
1234
1270
  import workflow from "./workflows/review-to-merge/claude.ts";
1235
1271
 
1236
- await createWorkflowCli(workflow).run({ inputs: { target_branch: "main" } });
1237
- // defaults above; CLI flags override.
1272
+ const program = new Command();
1273
+ for (const input of getInputSchema(workflow)) {
1274
+ program.option(`--${input.name} <value>`, input.description ?? "");
1275
+ }
1276
+ program.action(async (rawOpts) => {
1277
+ const inputs = rawOpts as Record<string, string>;
1278
+ await runWorkflow({ workflow, inputs });
1279
+ });
1280
+ await program.parseAsync();
1238
1281
  ```
1239
1282
 
1240
1283
  Run it:
1241
1284
 
1242
1285
  ```bash
1243
- bun run src/claude-worker.ts -n review-to-merge -a claude --target_branch=release/v2
1286
+ bun run src/claude-worker.ts --target_branch=release/v2
1244
1287
  ```
1245
1288
 
1246
- **Multiple workflows — inline array:**
1289
+ **Multiple workflows — iterate a registry:**
1247
1290
 
1248
1291
  ```ts
1249
1292
  // src/cli.ts
1250
- import { createWorkflowCli } from "@bastani/atomic/workflows";
1293
+ import { Command } from "@commander-js/extra-typings";
1294
+ import {
1295
+ createRegistry,
1296
+ getInputSchema,
1297
+ getName,
1298
+ listWorkflows,
1299
+ runWorkflow,
1300
+ } from "@bastani/atomic/workflows";
1251
1301
  import reviewToMerge from "./workflows/review-to-merge/claude.ts";
1252
1302
  import genSpec from "./workflows/gen-spec/claude.ts";
1253
1303
 
1254
- await createWorkflowCli([reviewToMerge, genSpec]).run();
1255
- ```
1256
-
1257
- Run it:
1258
-
1259
- ```bash
1260
- bun run src/cli.ts -n review-to-merge -a claude
1261
- bun run src/cli.ts -a claude # interactive picker (TTY)
1262
- ```
1263
-
1264
- See [`examples/multi-workflow/`](./examples/multi-workflow) for a complete runnable version — two Claude workflows (`hello`, `goodbye`) registered under one `cli.ts`, with the `createRegistry()` variant shown side by side in a comment.
1265
-
1266
- **Dynamic composition — `createRegistry`:**
1304
+ const registry = createRegistry().register(reviewToMerge).register(genSpec);
1305
+ const program = new Command("my-app");
1267
1306
 
1268
- ```ts
1269
- import { createWorkflowCli, createRegistry } from "@bastani/atomic/workflows";
1307
+ for (const wf of listWorkflows(registry)) {
1308
+ const sub = program.command(getName(wf)).description(wf.description);
1309
+ for (const input of getInputSchema(wf)) {
1310
+ sub.option(`--${input.name} <value>`, input.description ?? "");
1311
+ }
1312
+ sub.action(async (rawOpts) => {
1313
+ await runWorkflow({ workflow: wf, inputs: rawOpts as Record<string, string> });
1314
+ });
1315
+ }
1270
1316
 
1271
- const registry = workflowFiles.reduce((r, wf) => r.register(wf), createRegistry());
1272
- await createWorkflowCli(registry).run();
1317
+ await program.parseAsync();
1273
1318
  ```
1274
1319
 
1275
- Need a listing subcommand? Use `toCommand(cli)` from `@bastani/atomic/workflows/commander` and attach your own `list` subcommand the same way `atomic workflow list` is wired up in `src/cli.ts`.
1276
-
1277
- ### One method: `run()`
1320
+ See [`examples/multi-workflow/`](./examples/multi-workflow) for a complete runnable versiontwo Claude workflows (`hello`, `goodbye`) registered under one `cli.ts`.
1278
1321
 
1279
- `WorkflowCli` exposes one method — `run(options?)`. Default parses `process.argv`; pass `argv: [...]` to parse an explicit list, or `argv: false` to skip parsing entirely. `inputs` merge as defaults under CLI flags; `argv: false` makes them final. `run()` also accepts `name` / `agent`, which layer the same way.
1322
+ ### Programmatic invocation
1280
1323
 
1281
- The `WorkflowCli` type is framework-agnostic no Commander imports in sight. If you want one, reach for the adapter below.
1282
-
1283
- Example — programmatic invocation without argv:
1324
+ `runWorkflow({ workflow, inputs })` is a plain async function you don't need a CLI at all:
1284
1325
 
1285
1326
  ```ts
1286
- // Single workflow: name + agent are still required when argv parsing is skipped.
1287
- await cli.run({
1288
- argv: false,
1289
- name: "review-to-merge",
1290
- agent: "claude",
1291
- inputs: { target_branch: "main" },
1292
- });
1327
+ import { runWorkflow } from "@bastani/atomic/workflows";
1328
+ import workflow from "./workflows/review-to-merge/claude.ts";
1293
1329
 
1294
- // Multi-workflow cli: name + agent required under argv: false.
1295
- await cli.run({
1296
- argv: false,
1297
- name: "review-to-merge",
1298
- agent: "claude",
1330
+ const { id, tmuxSessionName } = await runWorkflow({
1331
+ workflow,
1299
1332
  inputs: { target_branch: "main" },
1333
+ detach: true,
1300
1334
  });
1301
1335
  ```
1302
1336
 
1303
- ### Embedding under a parent CLI `toCommand` + `runCli`
1337
+ Combine with `getSessionStatus(tmuxSessionName)` and `attachSession(id)` to build your own monitoring UI on top of the SDK.
1338
+
1339
+ ### Embedding under a parent CLI — `runWorkflow` inside any Commander tree
1304
1340
 
1305
- For integration with a bigger Commander program, import the adapter from the dedicated subpath:
1341
+ The SDK no longer ships a Commander adapter it doesn't need one. Just call `runWorkflow` from inside any Commander action:
1306
1342
 
1307
1343
  ```ts
1308
- import { createWorkflowCli } from "@bastani/atomic/workflows";
1309
- import { toCommand, runCli } from "@bastani/atomic/workflows/commander";
1310
1344
  import { Command } from "@commander-js/extra-typings";
1345
+ import { getInputSchema, runWorkflow } from "@bastani/atomic/workflows";
1311
1346
  import workflow from "./workflows/deploy/claude.ts";
1312
1347
 
1313
- const cli = createWorkflowCli(workflow);
1314
-
1315
1348
  const program = new Command("my-app");
1316
- program.addCommand(toCommand(cli, "deploy"));
1349
+
1350
+ const deploy = program.command("deploy").description(workflow.description);
1351
+ for (const input of getInputSchema(workflow)) {
1352
+ deploy.option(`--${input.name} <value>`, input.description ?? "");
1353
+ }
1354
+ deploy.action(async (rawOpts) => {
1355
+ await runWorkflow({ workflow, inputs: rawOpts as Record<string, string> });
1356
+ });
1357
+
1317
1358
  program.command("hello").action(() => console.log("hi"));
1318
1359
 
1319
- // Replaces program.parseAsync(). runCli transparently handles detached
1320
- // re-entry — when the process is a tmux-spawned orchestrator, it drives
1321
- // runOrchestrator; otherwise it invokes your callback (argv parse + any
1322
- // bootstrap you want). PyTorch's init_process_group for rank-zero
1323
- // dispatch — no guards, no env-var checks in user code.
1324
- await runCli(cli, () => program.parseAsync());
1360
+ await program.parseAsync();
1325
1361
  ```
1326
1362
 
1327
- `toCommand(cli, "workflow")` is exactly how the internal `atomic workflow` command is wired (`src/commands/cli/workflow.ts`). Because the Commander dependency lives only on the subpath, a future `@bastani/atomic/workflows/yargs` adapter can ship alongside without touching the core SDK.
1363
+ There's no re-entry boilerplate the SDK ships its own internal orchestrator entry script and re-execs *that* with positional args (`workflowSource`, `agent`, base64-encoded inputs). Your CLI is never re-imported, so there's nothing to guard against orchestrator-mode env vars.
1328
1364
 
1329
- ### `entry` — for bundled apps and test harnesses
1365
+ ### `WorkflowPicker` component
1330
1366
 
1331
- `createWorkflowCli` accepts `{ entry?: string }`, defaulting to `process.argv[1]`. That's the file the runtime re-executes on `--detach` to resume the orchestrator, so it has to be the composition root. Override it when you bundle the app (`entry` should point at the bundle), when the composition root isn't argv[1] (tests, embedded CLIs), or with `import.meta.url` for ESM-native correctness.
1367
+ The interactive picker (the same one `atomic workflow -a claude` opens) is exposed as a component:
1332
1368
 
1333
1369
  ```ts
1334
- const cli = createWorkflowCli(workflow, { entry: import.meta.url });
1370
+ import { WorkflowPicker } from "@bastani/atomic/workflows/components";
1335
1371
  ```
1336
1372
 
1373
+ Mount it inside your own OpenTUI app or imperatively via `WorkflowPickerPanel.create({ agent, registry })`.
1374
+
1337
1375
  ### Registry rules
1338
1376
 
1339
1377
  - `createRegistry()` returns an **immutable** registry. Each `.register(wf)` call returns a **new** registry — the original is unchanged. Chain calls to accumulate workflows.
1340
1378
  - Each workflow is keyed by `${agent}/${name}` — the `(agent, name)` pair must be unique. Registering a duplicate throws immediately.
1341
- - `createWorkflowCli(registry)` inspects every registered workflow and builds a union of their declared inputs. Same-name / same-type flags are shared; same-name / different-type conflicts throw at construction time so ambiguity never reaches runtime.
1342
1379
  - Builtin workflows (`ralph`, `deep-research-codebase`, `open-claude-design`) are managed by `atomic`'s internal `createBuiltinRegistry()`. They are reserved — user-registered workflows with the same name will not shadow builtins when running the `atomic` CLI.
1343
1380
 
1344
1381
  ### Input precedence
1345
1382
 
1346
- CLI flags always win when parsing is active. Under them, the order is:
1383
+ `runWorkflow({ workflow, inputs })` runs `validateInputs(workflow, inputs)` for you, applying:
1347
1384
 
1348
- 1. `defineWorkflow` default values (on each `WorkflowInput`)
1349
- 2. Layer supplied at construction or invocation:
1350
- - `cli.run({ inputs })` for the single-workflow shape
1351
- - `createWorkflowCli(registry, { inputs })` / `cli.run({ inputs })` for the multi-workflow shape
1352
- 3. CLI flags — `--<field>=<value>` passed at runtime
1385
+ 1. `defineWorkflow` default values (on each `WorkflowInput`) when no value is provided
1386
+ 2. The first declared enum value when `required: true` and no value is provided
1387
+ 3. Whatever you pass in `inputs`
1353
1388
 
1354
- With `argv: false`, the CLI-flag layer is skipped your programmatic `inputs` become top-of-chain.
1389
+ CLI flags compose entirely at the calling-CLI layer the SDK only sees the final `inputs` map.
1355
1390
 
1356
1391
  ### Builtin workflows via the `atomic` CLI
1357
1392
 
1358
- The `atomic workflow` command still works for the three built-in workflows internally it's `toCommand(createWorkflowCli(createBuiltinRegistry()), "workflow")`:
1393
+ The `atomic workflow` command runs the built-in registry via the same primitives:
1359
1394
 
1360
1395
  ```bash
1361
1396
  atomic workflow -n ralph -a claude "Build the auth module"
@@ -1365,19 +1400,14 @@ atomic workflow -n open-claude-design -a claude
1365
1400
 
1366
1401
  These are not affected by your own `createRegistry()` — they are separate.
1367
1402
 
1368
- ### Migration from 0.x (directory-scanning) to current
1369
-
1370
- > This is a breaking change. The SDK no longer scans `.atomic/workflows/` directories.
1403
+ ### Migration from 0.x (directory-scanning) and the `createWorkflowCli` wrapper
1371
1404
 
1372
- 1. **Delete** `.atomic/workflows/` from your repo.
1373
- 2. **Create one entrypoint file per agent**, e.g. `src/claude-worker.ts`:
1374
- ```ts
1375
- import { createWorkflowCli } from "@bastani/atomic/workflows";
1376
- import workflow from "./workflows/my-workflow/claude.ts";
1405
+ > Two breaking changes: workflows must declare `source: import.meta.path`, and the `createWorkflowCli` / `toCommand` / `runCli` wrappers were removed in favour of primitives.
1377
1406
 
1378
- await createWorkflowCli(workflow).run();
1379
- ```
1380
- 3. **Update invocations**: replace `atomic workflow -n foo -a claude` with `bun run src/claude-worker.ts -n foo -a claude` for your custom workflows. For the Atomic builtin set (`ralph`, `deep-research-codebase`, `open-claude-design`) keep using `atomic workflow -n <name> -a <agent>`.
1407
+ 1. **Add `source: import.meta.path`** to every `defineWorkflow({ ... })` call. The SDK uses it to import the workflow module inside the orchestrator child process.
1408
+ 2. **Replace `createWorkflowCli(workflow).run()`** with a small Commander (or citty / yargs) entrypoint that calls `runWorkflow({ workflow, inputs })` — see the snippets above. The SDK no longer ships a CLI wrapper.
1409
+ 3. **Remove `handleOrchestratorReentry` / `runCli` calls** the SDK ships its own orchestrator entry script and the dev's CLI is never re-execed.
1410
+ 4. **Update invocations**: replace `atomic workflow -n foo -a claude` with `bun run src/claude-worker.ts --<input>=<value>` for your custom workflows. For the Atomic builtin set (`ralph`, `deep-research-codebase`, `open-claude-design`) keep using `atomic workflow -n <name> -a <agent>`.
1381
1411
 
1382
1412
  ---
1383
1413
 
@@ -1481,6 +1511,11 @@ Ensure the agent CLI is in your PATH. Atomic uses `Bun.which()`, which handles `
1481
1511
 
1482
1512
  ## FAQ
1483
1513
 
1514
+ <details>
1515
+ <summary><b>Why not markdown, a coding agent alone, or a general agent framework?</b></summary>
1516
+ Markdown is great for guidance: conventions, commands, repo notes, and checklists. Use Claude Code, OpenCode, or Copilot CLI directly for normal single-session coding. Atomic is for the point where the work needs branching, retries, parallel sessions, state, human approval, sandboxed execution, or reliable handoff between stages. General agent frameworks can do some of this, but you often rebuild coding-agent basics yourself: file editing, terminal interaction, MCP setup, hooks, session handling, and repo-specific context. Atomic starts from production coding agents and adds the workflow layer around them.
1517
+ </details>
1518
+
1484
1519
  <details>
1485
1520
  <summary><b>How does Atomic differ from Spec-Kit?</b></summary>
1486
1521
 
@@ -1507,9 +1542,9 @@ Ensure the agent CLI is in your PATH. Atomic uses `Bun.which()`, which handles `
1507
1542
  <details>
1508
1543
  <summary><b>How does Atomic differ from DeerFlow?</b></summary>
1509
1544
 
1510
- [DeerFlow](https://github.com/bytedance/deer-flow) is ByteDance's agent harness built on LangGraph/LangChain. Both are multi-agent orchestrators, but take different approaches:
1545
+ [DeerFlow](https://github.com/bytedance/deer-flow) is ByteDance's agent runtime built on LangGraph/LangChain. Both can run multi-agent work, but take different approaches:
1511
1546
 
1512
- **In short:** DeerFlow is a general-purpose agent orchestrator with a web UI. Atomic is narrowly focused on coding workflows. The key difference is that Atomic runs on top of production coding agents (Claude Code, OpenCode, Copilot CLI) rather than reimplementing coding tools through a generic API — you get each agent's native file editing, permissions, MCP integrations, and hooks out of the box. Atomic also gives you deterministic execution, which matters when encoding a team's dev process.
1547
+ **In short:** DeerFlow is a general-purpose agent system with a web UI. Atomic is narrowly focused on coding workflows. The key difference is that Atomic runs on top of production coding agents (Claude Code, OpenCode, Copilot CLI) rather than reimplementing coding tools through a generic API — you get each agent's native file editing, permissions, MCP integrations, and hooks out of the box. Atomic also gives you deterministic execution, which matters when encoding a team's dev process.
1513
1548
 
1514
1549
  | Aspect | DeerFlow | Atomic |
1515
1550
  | ----------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------- |
@@ -1531,9 +1566,9 @@ Ensure the agent CLI is in your PATH. Atomic uses `Bun.which()`, which handles `
1531
1566
  <details>
1532
1567
  <summary><b>How does Atomic differ from Hermes Agent?</b></summary>
1533
1568
 
1534
- [Hermes Agent](https://github.com/NousResearch/hermes-agent) is Nous Research's general-purpose AI agent with a self-improving learning loop. Both are open-source agent frameworks, but serve different use cases:
1569
+ [Hermes Agent](https://github.com/NousResearch/hermes-agent) is Nous Research's general-purpose AI agent with a self-improving learning loop. Both are open source agent projects, but serve different use cases:
1535
1570
 
1536
- **In short:** Hermes is a broad AI assistant that learns across sessions and connects to messaging platforms. Atomic is a coding-specific harness for engineering teams. It lets you encode your development process as deterministic TypeScript workflows that run identically across team members, machines, and CI. Atomic inherits production-hardened tools from Claude Code, OpenCode, and Copilot CLI — including their permission systems, MCP integrations, and hooks — giving you two independent security boundaries (devcontainer isolation + agent permissions). Fresh context per session keeps output sharp over multi-hour tasks. Developer-authored skills don't drift the way auto-generated ones can.
1571
+ **In short:** Hermes is a broad AI assistant that learns across sessions and connects to messaging platforms. Atomic is coding-specific workflow software for engineering teams. It lets you encode your development process as deterministic TypeScript workflows that run identically across team members, machines, and CI. Atomic inherits production-hardened tools from Claude Code, OpenCode, and Copilot CLI — including their permission systems, MCP integrations, and hooks — giving you two independent security boundaries (devcontainer isolation + agent permissions). Fresh context per session keeps output sharp over multi-hour tasks. Developer-authored skills don't drift the way auto-generated ones can.
1537
1572
 
1538
1573
  | Aspect | Hermes Agent | Atomic |
1539
1574
  | ------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |