@bastani/atomic 0.5.34-0 → 0.6.0-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.
- package/README.md +329 -50
- package/dist/commands/cli/session.d.ts +67 -0
- package/dist/commands/cli/session.d.ts.map +1 -0
- package/dist/commands/cli/workflow-status.d.ts +63 -0
- package/dist/commands/cli/workflow-status.d.ts.map +1 -0
- package/dist/sdk/commander.d.ts +74 -0
- package/dist/sdk/commander.d.ts.map +1 -0
- package/dist/sdk/components/workflow-picker-panel.d.ts +14 -17
- package/dist/sdk/components/workflow-picker-panel.d.ts.map +1 -1
- package/dist/sdk/define-workflow.d.ts +18 -9
- package/dist/sdk/define-workflow.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +4 -3
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/management-commands.d.ts +42 -0
- package/dist/sdk/management-commands.d.ts.map +1 -0
- package/dist/sdk/registry.d.ts +27 -0
- package/dist/sdk/registry.d.ts.map +1 -0
- package/dist/sdk/runtime/attached-footer.d.ts +1 -1
- package/dist/sdk/runtime/executor-env.d.ts +20 -0
- package/dist/sdk/runtime/executor-env.d.ts.map +1 -0
- package/dist/sdk/runtime/executor.d.ts +61 -10
- package/dist/sdk/runtime/executor.d.ts.map +1 -1
- package/dist/sdk/types.d.ts +147 -4
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/sdk/worker-shared.d.ts +42 -0
- package/dist/sdk/worker-shared.d.ts.map +1 -0
- package/dist/sdk/workflow-cli.d.ts +103 -0
- package/dist/sdk/workflow-cli.d.ts.map +1 -0
- package/dist/sdk/workflows/builtin-registry.d.ts +113 -0
- package/dist/sdk/workflows/builtin-registry.d.ts.map +1 -0
- package/dist/sdk/workflows/index.d.ts +5 -5
- package/dist/sdk/workflows/index.d.ts.map +1 -1
- package/package.json +12 -8
- package/src/cli.ts +85 -144
- package/src/commands/cli/chat/index.ts +10 -0
- package/src/commands/cli/workflow-command.test.ts +279 -938
- package/src/commands/cli/workflow-inputs.test.ts +41 -11
- package/src/commands/cli/workflow-inputs.ts +47 -12
- package/src/commands/cli/workflow-list.test.ts +234 -0
- package/src/commands/cli/workflow-list.ts +0 -0
- package/src/commands/cli/workflow.ts +11 -798
- package/src/scripts/constants.ts +2 -1
- package/src/sdk/commander.ts +161 -0
- package/src/sdk/components/workflow-picker-panel.tsx +78 -258
- package/src/sdk/define-workflow.test.ts +104 -11
- package/src/sdk/define-workflow.ts +47 -11
- package/src/sdk/errors.test.ts +16 -0
- package/src/sdk/index.ts +8 -8
- package/src/sdk/management-commands.ts +151 -0
- package/src/sdk/registry.ts +132 -0
- package/src/sdk/runtime/attached-footer.ts +1 -1
- package/src/sdk/runtime/executor-env.ts +45 -0
- package/src/sdk/runtime/executor.test.ts +37 -0
- package/src/sdk/runtime/executor.ts +147 -68
- package/src/sdk/types.ts +169 -4
- package/src/sdk/worker-shared.test.ts +163 -0
- package/src/sdk/worker-shared.ts +155 -0
- package/src/sdk/workflow-cli.ts +409 -0
- package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +1 -1
- package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +1 -1
- package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +1 -1
- package/src/sdk/workflows/builtin/open-claude-design/claude/index.ts +1 -1
- package/src/sdk/workflows/builtin/open-claude-design/copilot/index.ts +1 -1
- package/src/sdk/workflows/builtin/open-claude-design/opencode/index.ts +1 -1
- package/src/sdk/workflows/builtin/ralph/claude/index.ts +1 -1
- package/src/sdk/workflows/builtin/ralph/copilot/index.ts +1 -1
- package/src/sdk/workflows/builtin/ralph/opencode/index.ts +1 -1
- package/src/sdk/workflows/builtin-registry.ts +23 -0
- package/src/sdk/workflows/index.ts +10 -20
- package/src/services/system/auth.test.ts +63 -1
- package/.agents/skills/workflow-creator/SKILL.md +0 -334
- package/.agents/skills/workflow-creator/references/agent-sessions.md +0 -888
- package/.agents/skills/workflow-creator/references/computation-and-validation.md +0 -201
- package/.agents/skills/workflow-creator/references/control-flow.md +0 -470
- package/.agents/skills/workflow-creator/references/discovery-and-verification.md +0 -232
- package/.agents/skills/workflow-creator/references/failure-modes.md +0 -903
- package/.agents/skills/workflow-creator/references/getting-started.md +0 -275
- package/.agents/skills/workflow-creator/references/running-workflows.md +0 -235
- package/.agents/skills/workflow-creator/references/session-config.md +0 -384
- package/.agents/skills/workflow-creator/references/state-and-data-flow.md +0 -357
- package/.agents/skills/workflow-creator/references/user-input.md +0 -234
- package/.agents/skills/workflow-creator/references/workflow-inputs.md +0 -272
- package/dist/sdk/runtime/discovery.d.ts +0 -132
- package/dist/sdk/runtime/discovery.d.ts.map +0 -1
- package/dist/sdk/runtime/executor-entry.d.ts +0 -11
- package/dist/sdk/runtime/executor-entry.d.ts.map +0 -1
- package/dist/sdk/runtime/loader.d.ts +0 -70
- package/dist/sdk/runtime/loader.d.ts.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/src/commands/cli/workflow.test.ts +0 -317
- package/src/sdk/runtime/discovery.ts +0 -368
- package/src/sdk/runtime/executor-entry.ts +0 -18
- package/src/sdk/runtime/loader.ts +0 -267
package/README.md
CHANGED
|
@@ -9,27 +9,55 @@
|
|
|
9
9
|
[](./package.json)
|
|
10
10
|
[](./LICENSE)
|
|
11
11
|
|
|
12
|
-
**An open-source 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
|
+
**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.
|
|
13
13
|
|
|
14
14
|
> Define how your agent works. Start for yourself, scale to your team — across 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:
|
|
21
|
+
|
|
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) |
|
|
31
|
+
|
|
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.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
18
36
|
## Quick Start
|
|
19
37
|
|
|
20
|
-
Install, generate context, try Ralph, then write your own workflow — four steps, a few minutes.
|
|
38
|
+
Install, generate context, try Ralph, then write your own workflow — four steps, a few minutes. Steps 1–3 are the **CLI** path (pre-built autonomous behaviour). Step 4 is the **SDK** path (your own workflows). Skip straight to step 4 if you only want the library.
|
|
21
39
|
|
|
22
40
|
### Prerequisites
|
|
23
41
|
|
|
24
|
-
|
|
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:
|
|
43
|
+
|
|
44
|
+
- **[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
|
+
- **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.
|
|
46
|
+
- **macOS / Linux:** [tmux](https://github.com/tmux/tmux) — `brew install tmux` or your distro's package manager
|
|
47
|
+
- **Windows:** [psmux](https://github.com/psmux/psmux) — a PowerShell-native tmux-compatible shim, detected as `psmux` / `pmux` / `tmux` on `PATH`
|
|
48
|
+
- **At least one coding agent** installed and logged in — Atomic spawns the agent's own CLI at each stage and talks to it via its SDK, so the CLI has to be present and authenticated:
|
|
25
49
|
- [Claude Code](https://code.claude.com/docs/en/quickstart) — run `claude` and authenticate
|
|
26
50
|
- [OpenCode](https://opencode.ai) — run `opencode` and authenticate
|
|
27
51
|
- [GitHub Copilot CLI](https://github.com/features/copilot/cli) — run `copilot` and authenticate
|
|
28
|
-
- **Windows:** PowerShell 7+ ([install guide](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows))
|
|
52
|
+
- **Windows only:** PowerShell 7+ ([install guide](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows))
|
|
29
53
|
|
|
30
|
-
|
|
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.
|
|
31
55
|
|
|
32
|
-
|
|
56
|
+
### 1. Install — CLI + SDK share the same package
|
|
57
|
+
|
|
58
|
+
`@bastani/atomic` ships both surfaces. A **global** install gives you the `atomic` CLI; a **project-local** install gives you the SDK import. Most users do both, but either stands alone.
|
|
59
|
+
|
|
60
|
+
**CLI path** — bootstrap script installs [Bun](https://bun.sh/), the `atomic` binary, and shell completions in one step:
|
|
33
61
|
|
|
34
62
|
```bash
|
|
35
63
|
# macOS / Linux
|
|
@@ -41,8 +69,18 @@ irm https://raw.githubusercontent.com/flora131/atomic/main/install.ps1 | iex
|
|
|
41
69
|
|
|
42
70
|
Upgrade later with `bun update -g @bastani/atomic`.
|
|
43
71
|
|
|
72
|
+
**SDK-only path** — if you only want to `defineWorkflow(...)` in your own TypeScript project and never need the `atomic` binary, skip the bootstrap and just add the library:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
bun init -y # new project
|
|
76
|
+
bun add @bastani/atomic # the SDK
|
|
77
|
+
bun add @anthropic-ai/claude-agent-sdk # the provider SDK you target
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Skip steps 2–3 below (those use the CLI) and jump straight to [step 4](#4-build-your-own-workflow--sdk). You'll still need tmux/psmux + an authenticated agent CLI at runtime — see [Prerequisites](#prerequisites).
|
|
81
|
+
|
|
44
82
|
<details>
|
|
45
|
-
<summary><b>Alternative: Already have Bun? Install directly from npm</b></summary>
|
|
83
|
+
<summary><b>Alternative: Already have Bun? Install the CLI directly from npm</b></summary>
|
|
46
84
|
|
|
47
85
|
```bash
|
|
48
86
|
bun install -g @bastani/atomic
|
|
@@ -118,7 +156,7 @@ bun install -g @bastani/atomic
|
|
|
118
156
|
|
|
119
157
|
</details>
|
|
120
158
|
|
|
121
|
-
### 2. Generate context files
|
|
159
|
+
### 2. Generate context files — CLI
|
|
122
160
|
|
|
123
161
|
```bash
|
|
124
162
|
atomic chat -a <claude|opencode|copilot>
|
|
@@ -126,7 +164,7 @@ atomic chat -a <claude|opencode|copilot>
|
|
|
126
164
|
|
|
127
165
|
Then type `/init`. Atomic explores your codebase with sub-agents and writes `CLAUDE.md` / `AGENTS.md` so every future session starts with the right context.
|
|
128
166
|
|
|
129
|
-
### 3. Try Ralph (autonomous coding)
|
|
167
|
+
### 3. Try Ralph — CLI (autonomous coding)
|
|
130
168
|
|
|
131
169
|
Ralph plans, implements, reviews, and debugs a task on its own — up to 10 iterations, exiting after 2 consecutive clean reviews.
|
|
132
170
|
|
|
@@ -136,16 +174,15 @@ atomic workflow -n ralph -a claude "Build a REST API for user management"
|
|
|
136
174
|
|
|
137
175
|
> ⚠️ Workflows run with agent permission checks **disabled** so pipelines don't block on prompts. Run them in a [devcontainer](#containerized-execution) or [git worktree](https://git-scm.com/docs/git-worktree), not on your host. See [Security](#security-workflow-permissions-model).
|
|
138
176
|
|
|
139
|
-
### 4. Build your own workflow
|
|
177
|
+
### 4. Build your own workflow — SDK
|
|
140
178
|
|
|
141
179
|
Every team has a process — code review, CI checks, PR creation, approval, merge. Encode it as TypeScript once; everyone runs the same pipeline.
|
|
142
180
|
|
|
143
181
|
```bash
|
|
144
182
|
bun init && bun add @bastani/atomic
|
|
145
|
-
mkdir -p .atomic/workflows/review-to-merge/claude
|
|
146
183
|
```
|
|
147
184
|
|
|
148
|
-
|
|
185
|
+
Author the workflow in `src/workflows/review-to-merge/claude.ts`:
|
|
149
186
|
|
|
150
187
|
```ts
|
|
151
188
|
import { defineWorkflow } from "@bastani/atomic/workflows";
|
|
@@ -153,7 +190,7 @@ import { defineWorkflow } from "@bastani/atomic/workflows";
|
|
|
153
190
|
export default defineWorkflow({
|
|
154
191
|
name: "review-to-merge",
|
|
155
192
|
description: "Review → CI → PR → Notify → Approve → Merge",
|
|
156
|
-
}).for
|
|
193
|
+
}).for("claude")
|
|
157
194
|
.run(async (ctx) => {
|
|
158
195
|
// 1. Review
|
|
159
196
|
const review = await ctx.stage({ name: "review" }, {}, {}, async (s) => {
|
|
@@ -195,13 +232,22 @@ export default defineWorkflow({
|
|
|
195
232
|
.compile();
|
|
196
233
|
```
|
|
197
234
|
|
|
235
|
+
Wire it to a CLI in `src/claude-worker.ts` — three lines:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
import { createWorkflowCli } from "@bastani/atomic/workflows";
|
|
239
|
+
import workflow from "./workflows/review-to-merge/claude.ts";
|
|
240
|
+
|
|
241
|
+
await createWorkflowCli(workflow).run();
|
|
242
|
+
```
|
|
243
|
+
|
|
198
244
|
Run it:
|
|
199
245
|
|
|
200
246
|
```bash
|
|
201
|
-
|
|
247
|
+
bun run src/claude-worker.ts -n review-to-merge -a claude
|
|
202
248
|
```
|
|
203
249
|
|
|
204
|
-
|
|
250
|
+
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.
|
|
205
251
|
|
|
206
252
|
### Managing sessions
|
|
207
253
|
|
|
@@ -237,16 +283,18 @@ Better models make harnesses **more** important, not less. The more you trust an
|
|
|
237
283
|
|
|
238
284
|
### Example use cases
|
|
239
285
|
|
|
286
|
+
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.
|
|
287
|
+
|
|
240
288
|
**Add production monitoring.** Research observability gaps, implement missing metrics and health checks, review the changes.
|
|
241
289
|
|
|
242
290
|
```bash
|
|
243
|
-
|
|
291
|
+
bun run src/claude-worker.ts -n observability -a claude "add Prometheus metrics and health checks to all API endpoints"
|
|
244
292
|
```
|
|
245
293
|
|
|
246
294
|
**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.
|
|
247
295
|
|
|
248
296
|
```bash
|
|
249
|
-
|
|
297
|
+
bun run src/claude-worker.ts -n ux-personas -a claude --personas=50
|
|
250
298
|
```
|
|
251
299
|
|
|
252
300
|
**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.
|
|
@@ -256,12 +304,13 @@ atomic workflow -n ux-personas -a claude
|
|
|
256
304
|
## Table of Contents
|
|
257
305
|
|
|
258
306
|
- [Atomic](#atomic)
|
|
307
|
+
- [Two surfaces: CLI and SDK](#two-surfaces-cli-and-sdk)
|
|
259
308
|
- [Quick Start](#quick-start)
|
|
260
309
|
- [Prerequisites](#prerequisites)
|
|
261
|
-
- [1. Install](#1-install)
|
|
262
|
-
- [2. Generate context files](#2-generate-context-files)
|
|
263
|
-
- [3. Try Ralph (autonomous coding)](#3-try-ralph-autonomous-coding)
|
|
264
|
-
- [4. Build your own workflow](#4-build-your-own-workflow)
|
|
310
|
+
- [1. Install — CLI + SDK share the same package](#1-install--cli--sdk-share-the-same-package)
|
|
311
|
+
- [2. Generate context files — CLI](#2-generate-context-files--cli)
|
|
312
|
+
- [3. Try Ralph — CLI (autonomous coding)](#3-try-ralph--cli-autonomous-coding)
|
|
313
|
+
- [4. Build your own workflow — SDK](#4-build-your-own-workflow--sdk)
|
|
265
314
|
- [Managing sessions](#managing-sessions)
|
|
266
315
|
- [Why Atomic](#why-atomic)
|
|
267
316
|
- [Example use cases](#example-use-cases)
|
|
@@ -270,6 +319,7 @@ atomic workflow -n ux-personas -a claude
|
|
|
270
319
|
- [Core Features](#core-features)
|
|
271
320
|
- [Multi-Agent Support](#multi-agent-support)
|
|
272
321
|
- [Workflow SDK — Build Your Own Deterministic Harness](#workflow-sdk--build-your-own-deterministic-harness)
|
|
322
|
+
- [Runnable examples shipped with the repo](#runnable-examples-shipped-with-the-repo)
|
|
273
323
|
- [Builder API](#builder-api)
|
|
274
324
|
- [WorkflowContext (`ctx`) — top-level orchestrator](#workflowcontext-ctx--top-level-orchestrator)
|
|
275
325
|
- [SessionContext (`s`) — inside each session callback](#sessioncontext-s--inside-each-session-callback)
|
|
@@ -292,6 +342,15 @@ atomic workflow -n ux-personas -a claude
|
|
|
292
342
|
- [`atomic workflow` Flags](#atomic-workflow-flags)
|
|
293
343
|
- [`atomic completions` — Shell Completions](#atomic-completions--shell-completions)
|
|
294
344
|
- [Atomic-Provided Skills (invokable from any agent chat)](#atomic-provided-skills-invokable-from-any-agent-chat)
|
|
345
|
+
- [Building your own atomic-powered app](#building-your-own-atomic-powered-app)
|
|
346
|
+
- [One factory, three input shapes](#one-factory-three-input-shapes)
|
|
347
|
+
- [One method: `run()`](#one-method-run)
|
|
348
|
+
- [Embedding under a parent CLI — `toCommand` + `runCli`](#embedding-under-a-parent-cli--tocommand--runcli)
|
|
349
|
+
- [`entry` — for bundled apps and test harnesses](#entry--for-bundled-apps-and-test-harnesses)
|
|
350
|
+
- [Registry rules](#registry-rules)
|
|
351
|
+
- [Input precedence](#input-precedence)
|
|
352
|
+
- [Builtin workflows via the `atomic` CLI](#builtin-workflows-via-the-atomic-cli)
|
|
353
|
+
- [Migration from 0.x (directory-scanning) to current](#migration-from-0x-directory-scanning-to-current)
|
|
295
354
|
- [Configuration](#configuration)
|
|
296
355
|
- [`.atomic/settings.json`](#atomicsettingsjson)
|
|
297
356
|
- [Agent-Specific Files](#agent-specific-files)
|
|
@@ -339,14 +398,57 @@ Each agent gets its own configuration directory (`.claude/`, `.opencode/`, `.git
|
|
|
339
398
|
|
|
340
399
|
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.
|
|
341
400
|
|
|
342
|
-
Set up a workflow project (`bun init && bun add @bastani/atomic`),
|
|
401
|
+
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):
|
|
343
402
|
|
|
344
403
|
```bash
|
|
345
|
-
|
|
404
|
+
bun run src/claude-worker.ts -n <workflow-name> -a claude --prompt "describe this project"
|
|
346
405
|
```
|
|
347
406
|
|
|
348
407
|
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.
|
|
349
408
|
|
|
409
|
+
#### Runnable examples shipped with the repo
|
|
410
|
+
|
|
411
|
+
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.
|
|
412
|
+
|
|
413
|
+
| Example | What it demonstrates |
|
|
414
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
415
|
+
| `hello-world` | Minimal single-session workflow with structured inputs (greeting, style, optional notes) |
|
|
416
|
+
| `sequential-describe-summarize` | Two stages passing data via `s.save()` → `s.transcript(handle)` — the canonical handoff pattern |
|
|
417
|
+
| `parallel-hello-world` | `Promise.all()` fan-out and transcript merge |
|
|
418
|
+
| `headless-test` | Visible seed → 3 parallel headless stages → visible merge → headless verdict |
|
|
419
|
+
| `hil-favorite-color` | Human-in-the-loop prompt mid-workflow |
|
|
420
|
+
| `hil-favorite-color-headless` | HIL pause inside a headless stage |
|
|
421
|
+
| `structured-output-demo` | Per-SDK structured output (JSON-schema validation, Zod) |
|
|
422
|
+
| `reviewer-tool-test` | Custom reviewer tool wiring (Copilot — copilot-worker.ts only) |
|
|
423
|
+
| `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 |
|
|
424
|
+
| `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. |
|
|
425
|
+
| `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. |
|
|
426
|
+
|
|
427
|
+
Run any of them with:
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
# Single-workflow examples — one worker file per agent
|
|
431
|
+
bun run examples/<name>/<agent>-worker.ts -n <workflow-name> -a <agent> [--field=value | "<prompt>"]
|
|
432
|
+
|
|
433
|
+
# e.g.
|
|
434
|
+
bun run examples/hello-world/claude-worker.ts -n hello-world -a claude --greeting="Hello" --style=casual
|
|
435
|
+
bun run examples/sequential-describe-summarize/claude-worker.ts -n sequential-describe-summarize -a claude --topic="Bun"
|
|
436
|
+
bun run examples/review-fix-loop/claude-worker.ts -n review-fix-loop -a claude --topic="adopting Bun" --max_iterations=3
|
|
437
|
+
bun run examples/headless-test/copilot-worker.ts -n headless-test -a copilot "TypeScript"
|
|
438
|
+
|
|
439
|
+
# Multi-workflow — one cli.ts, dispatch by `-n/--name`
|
|
440
|
+
bun run examples/multi-workflow/cli.ts -n hello -a claude --who=Alex
|
|
441
|
+
bun run examples/multi-workflow/cli.ts -n goodbye -a claude --tone=melodramatic
|
|
442
|
+
bun run examples/multi-workflow/cli.ts -a claude # interactive picker (TTY)
|
|
443
|
+
|
|
444
|
+
# Commander embedding — workflow mounted as a subcommand under a parent CLI
|
|
445
|
+
bun run examples/commander-embed/cli.ts greet -n greet -a claude --who=Alex
|
|
446
|
+
bun run examples/commander-embed/cli.ts status # sibling Commander command
|
|
447
|
+
bun run examples/commander-embed/cli.ts --help # all commands
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Copy an example directory into your project as a starting point — swap the workflow import in each `<agent>-worker.ts` (or in `cli.ts` for the multi-workflow / commander-embed shapes) for your own definition and you're done.
|
|
451
|
+
|
|
350
452
|
<details>
|
|
351
453
|
<summary><b>Example: Sequential workflow (describe → summarize)</b></summary>
|
|
352
454
|
|
|
@@ -357,7 +459,7 @@ export default defineWorkflow({
|
|
|
357
459
|
name: "my-workflow",
|
|
358
460
|
description: "Two-session pipeline: describe -> summarize",
|
|
359
461
|
inputs: [{ name: "prompt", type: "text", required: true, description: "task prompt" }],
|
|
360
|
-
}).for
|
|
462
|
+
}).for("claude")
|
|
361
463
|
.run(async (ctx) => {
|
|
362
464
|
const prompt = ctx.inputs.prompt ?? "";
|
|
363
465
|
|
|
@@ -395,7 +497,7 @@ export default defineWorkflow({
|
|
|
395
497
|
name: "parallel-demo",
|
|
396
498
|
description: "describe -> [summarize-a, summarize-b] -> merge",
|
|
397
499
|
inputs: [{ name: "prompt", type: "text", required: true, description: "task prompt" }],
|
|
398
|
-
}).for
|
|
500
|
+
}).for("claude")
|
|
399
501
|
.run(async (ctx) => {
|
|
400
502
|
const prompt = ctx.inputs.prompt ?? "";
|
|
401
503
|
|
|
@@ -464,7 +566,7 @@ export default defineWorkflow({
|
|
|
464
566
|
description: "extra guidance for the spec writer (optional)",
|
|
465
567
|
},
|
|
466
568
|
],
|
|
467
|
-
}).for
|
|
569
|
+
}).for("claude")
|
|
468
570
|
.run(async (ctx) => {
|
|
469
571
|
const { research_doc, focus } = ctx.inputs;
|
|
470
572
|
const notes = ctx.inputs.notes ?? "";
|
|
@@ -480,16 +582,15 @@ export default defineWorkflow({
|
|
|
480
582
|
.compile();
|
|
481
583
|
```
|
|
482
584
|
|
|
483
|
-
|
|
585
|
+
Wire it into `src/claude-worker.ts` (three lines — see [step 4 of Quick Start](#4-build-your-own-workflow)) and run it:
|
|
484
586
|
|
|
485
587
|
```bash
|
|
486
|
-
#
|
|
487
|
-
|
|
588
|
+
# Scriptable; CI-friendly
|
|
589
|
+
bun run src/claude-worker.ts \
|
|
590
|
+
-n gen-spec \
|
|
591
|
+
-a claude \
|
|
488
592
|
--research_doc=research/docs/2026-04-11-auth.md \
|
|
489
593
|
--focus=standard
|
|
490
|
-
|
|
491
|
-
# Picker (fuzzy-search workflows, fill the form)
|
|
492
|
-
atomic workflow -a claude
|
|
493
594
|
```
|
|
494
595
|
|
|
495
596
|
</details>
|
|
@@ -506,7 +607,7 @@ export default defineWorkflow({
|
|
|
506
607
|
name: "headless-demo",
|
|
507
608
|
description: "seed -> [3 headless background] -> merge",
|
|
508
609
|
inputs: [{ name: "prompt", type: "text", required: true, description: "task prompt" }],
|
|
509
|
-
}).for
|
|
610
|
+
}).for("claude")
|
|
510
611
|
.run(async (ctx) => {
|
|
511
612
|
const prompt = ctx.inputs.prompt ?? "";
|
|
512
613
|
|
|
@@ -563,7 +664,7 @@ The graph shows `seed → merge` — headless stages are transparent to the topo
|
|
|
563
664
|
| **Session return values** | Session callbacks can return data: `const h = await ctx.stage(...); h.result` |
|
|
564
665
|
| **Transcript passing** | Access prior output via handle (`s.transcript(handle)`) or name (`s.transcript("name")`) |
|
|
565
666
|
| **Declared input schemas** | Add an `inputs: [...]` array and the CLI materialises `--<field>=<value>` flags with built-in validation |
|
|
566
|
-
| **Interactive picker** | `atomic workflow -a <agent>`
|
|
667
|
+
| **Interactive picker** | `atomic workflow -a <agent>` is the explicit no-`-n` discovery path; direct runs use `-n <name>` |
|
|
567
668
|
| **Nested sub-sessions** | `s.stage()` inside a callback spawns child sessions — visible as nested graph nodes |
|
|
568
669
|
| **Auto-inferred graph** | Topology derived from `await` / `Promise.all` patterns — no annotations |
|
|
569
670
|
| **Provider-agnostic** | Write raw SDK code for Claude, Copilot, or OpenCode inside each callback |
|
|
@@ -653,11 +754,11 @@ The runtime auto-creates `s.client` and `s.session` — use them directly inside
|
|
|
653
754
|
|
|
654
755
|
#### Key Rules
|
|
655
756
|
|
|
656
|
-
1. Every workflow
|
|
757
|
+
1. Every workflow definition must call `.run()` and `.compile()` on the builder
|
|
657
758
|
2. Session names must be unique within a workflow run
|
|
658
759
|
3. `transcript()` / `getMessages()` only access completed sessions (callback returned + saves flushed)
|
|
659
760
|
4. Each session runs in its own tmux window with the chosen agent
|
|
660
|
-
5.
|
|
761
|
+
5. Bind a workflow to a CLI with `createWorkflowCli(workflow)` (single workflow) or `createWorkflowCli(createRegistry().register(...))` (many workflows)
|
|
661
762
|
6. Set up your workflow project with `bun init && bun add @bastani/atomic`
|
|
662
763
|
7. Background (headless) stages use the same callback API — `s.client`, `s.session`, `s.save()`, return values all work identically
|
|
663
764
|
|
|
@@ -694,7 +795,7 @@ atomic chat -a claude "/research-codebase Research GraphRAG using microsoft/grap
|
|
|
694
795
|
atomic chat -a claude "/research-codebase Research GraphRAG using LlamaIndex's property graph."
|
|
695
796
|
```
|
|
696
797
|
|
|
697
|
-
Then run `/create-spec` on each output, spin up git worktrees, and run `atomic workflow -n ralph
|
|
798
|
+
Then run `/create-spec` on each output, spin up git worktrees, and run `atomic workflow -n ralph -a <agent>` in each — wake up to three complete implementations on separate branches. Research persists in `research/` and specs in `specs/`, so every investigation compounds into future context.
|
|
698
799
|
|
|
699
800
|
<details>
|
|
700
801
|
<summary><i>Why specialized research agents instead of one general-purpose agent?</i></summary>
|
|
@@ -948,7 +1049,7 @@ During `atomic chat`, there is no Atomic-owned TUI — `atomic chat -a <agent>`
|
|
|
948
1049
|
| Command | Description |
|
|
949
1050
|
| ------------------------------- | --------------------------------------------------------------- |
|
|
950
1051
|
| `atomic chat` | Spawn the native agent CLI inside a tmux session |
|
|
951
|
-
| `atomic workflow` | Run a multi-session workflow with the Atomic orchestrator panel |
|
|
1052
|
+
| `atomic workflow` | Run a named multi-session workflow with the Atomic orchestrator panel |
|
|
952
1053
|
| `atomic workflow list` | List available workflows, grouped by source |
|
|
953
1054
|
| `atomic session list` | List all running sessions on the atomic tmux socket |
|
|
954
1055
|
| `atomic session connect [name]` | Attach to a session (interactive picker when no name given) |
|
|
@@ -1011,7 +1112,7 @@ atomic chat -a claude --verbose # forward --verbose to claude
|
|
|
1011
1112
|
|
|
1012
1113
|
| Flag | Description |
|
|
1013
1114
|
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1014
|
-
| `-n, --name <name>` | Workflow name (
|
|
1115
|
+
| `-n, --name <name>` | Workflow name (required for direct runs; omit only for the interactive picker) |
|
|
1015
1116
|
| `-a, --agent <name>` | Agent: `claude`, `opencode`, `copilot` |
|
|
1016
1117
|
| `-d, --detach` | Start the workflow in the background without attaching — ideal for scripted / CI runs; attach later with `atomic workflow session connect <name>` |
|
|
1017
1118
|
| `--<field>=<value>` | Structured input for workflows that declare an `inputs` schema (also accepts `--<field> <value>`) |
|
|
@@ -1031,9 +1132,9 @@ atomic workflow -a claude
|
|
|
1031
1132
|
atomic workflow -n ralph -a claude "build a REST API for user management"
|
|
1032
1133
|
|
|
1033
1134
|
# 4. Run a structured-input workflow with one --<field> flag per declared input
|
|
1034
|
-
atomic workflow -n
|
|
1035
|
-
--
|
|
1036
|
-
--
|
|
1135
|
+
atomic workflow -n open-claude-design -a claude \
|
|
1136
|
+
--prompt="a dashboard for monitoring API latency" \
|
|
1137
|
+
--output-type=prototype
|
|
1037
1138
|
|
|
1038
1139
|
# 5. Run detached — orchestrator runs in the background; prints the session name
|
|
1039
1140
|
# and returns immediately. Attach any time with `atomic workflow session connect`.
|
|
@@ -1100,12 +1201,185 @@ Atomic ships skills — not slash commands. Skills are auto-discovered by Claude
|
|
|
1100
1201
|
| `ado-create-pr` | `/ado-create-pr` | Commit, push, and open an Azure DevOps PR through the `azure-devops` MCP server |
|
|
1101
1202
|
| `sl-commit` | `/sl-commit` | Create a Sapling commit |
|
|
1102
1203
|
| `sl-submit-diff` | `/sl-submit-diff` | Submit a Sapling commit as a Phabricator diff |
|
|
1103
|
-
| `workflow-creator` | natural language | Generate a multi-agent workflow
|
|
1204
|
+
| `workflow-creator` | natural language | Generate a multi-agent workflow definition using `defineWorkflow` + registry |
|
|
1104
1205
|
|
|
1105
1206
|
Native slash commands (`/help`, `/clear`, `/compact`, `/model`, `/theme`, `/agents`, `/mcp`, `/exit`) come from the underlying agent CLI, not Atomic.
|
|
1106
1207
|
|
|
1107
1208
|
---
|
|
1108
1209
|
|
|
1210
|
+
## Building your own atomic-powered app
|
|
1211
|
+
|
|
1212
|
+
`@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.
|
|
1213
|
+
|
|
1214
|
+
> **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.
|
|
1215
|
+
>
|
|
1216
|
+
> **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.
|
|
1217
|
+
|
|
1218
|
+
### One factory, three input shapes
|
|
1219
|
+
|
|
1220
|
+
`createWorkflowCli` is the single factory. Pick whichever input shape matches how you organize your workflows:
|
|
1221
|
+
|
|
1222
|
+
| Input | When to use |
|
|
1223
|
+
| ------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
1224
|
+
| `createWorkflowCli(workflow)` | One workflow. Direct runs still use `-n/--name` + `-a/--agent`; the CLI exposes only that workflow's declared `--<input>` flags. |
|
|
1225
|
+
| `createWorkflowCli([wf1, wf2])` | Multiple workflows inline. Uses the same `-n/--name` + `-a/--agent` dispatch and the interactive picker. |
|
|
1226
|
+
| `createWorkflowCli(registry)` | Dynamic composition (loop-register, conditional registration). Same runtime shape as the array form. |
|
|
1227
|
+
|
|
1228
|
+
**Single workflow (most common)** — one file, three lines:
|
|
1229
|
+
|
|
1230
|
+
```ts
|
|
1231
|
+
// src/claude-worker.ts
|
|
1232
|
+
import { createWorkflowCli } from "@bastani/atomic/workflows";
|
|
1233
|
+
import workflow from "./workflows/review-to-merge/claude.ts";
|
|
1234
|
+
|
|
1235
|
+
await createWorkflowCli(workflow).run({ inputs: { target_branch: "main" } });
|
|
1236
|
+
// defaults above; CLI flags override.
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
Run it:
|
|
1240
|
+
|
|
1241
|
+
```bash
|
|
1242
|
+
bun run src/claude-worker.ts -n review-to-merge -a claude --target_branch=release/v2
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
**Multiple workflows — inline array:**
|
|
1246
|
+
|
|
1247
|
+
```ts
|
|
1248
|
+
// src/cli.ts
|
|
1249
|
+
import { createWorkflowCli } from "@bastani/atomic/workflows";
|
|
1250
|
+
import reviewToMerge from "./workflows/review-to-merge/claude.ts";
|
|
1251
|
+
import genSpec from "./workflows/gen-spec/claude.ts";
|
|
1252
|
+
|
|
1253
|
+
await createWorkflowCli([reviewToMerge, genSpec]).run();
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
Run it:
|
|
1257
|
+
|
|
1258
|
+
```bash
|
|
1259
|
+
bun run src/cli.ts -n review-to-merge -a claude
|
|
1260
|
+
bun run src/cli.ts -a claude # interactive picker (TTY)
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
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.
|
|
1264
|
+
|
|
1265
|
+
**Dynamic composition — `createRegistry`:**
|
|
1266
|
+
|
|
1267
|
+
```ts
|
|
1268
|
+
import { createWorkflowCli, createRegistry } from "@bastani/atomic/workflows";
|
|
1269
|
+
|
|
1270
|
+
const registry = workflowFiles.reduce((r, wf) => r.register(wf), createRegistry());
|
|
1271
|
+
await createWorkflowCli(registry).run();
|
|
1272
|
+
```
|
|
1273
|
+
|
|
1274
|
+
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`.
|
|
1275
|
+
|
|
1276
|
+
### One method: `run()`
|
|
1277
|
+
|
|
1278
|
+
`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.
|
|
1279
|
+
|
|
1280
|
+
The `WorkflowCli` type is framework-agnostic — no Commander imports in sight. If you want one, reach for the adapter below.
|
|
1281
|
+
|
|
1282
|
+
Example — programmatic invocation without argv:
|
|
1283
|
+
|
|
1284
|
+
```ts
|
|
1285
|
+
// Single workflow: name + agent are still required when argv parsing is skipped.
|
|
1286
|
+
await cli.run({
|
|
1287
|
+
argv: false,
|
|
1288
|
+
name: "review-to-merge",
|
|
1289
|
+
agent: "claude",
|
|
1290
|
+
inputs: { target_branch: "main" },
|
|
1291
|
+
});
|
|
1292
|
+
|
|
1293
|
+
// Multi-workflow cli: name + agent required under argv: false.
|
|
1294
|
+
await cli.run({
|
|
1295
|
+
argv: false,
|
|
1296
|
+
name: "review-to-merge",
|
|
1297
|
+
agent: "claude",
|
|
1298
|
+
inputs: { target_branch: "main" },
|
|
1299
|
+
});
|
|
1300
|
+
```
|
|
1301
|
+
|
|
1302
|
+
### Embedding under a parent CLI — `toCommand` + `runCli`
|
|
1303
|
+
|
|
1304
|
+
For integration with a bigger Commander program, import the adapter from the dedicated subpath:
|
|
1305
|
+
|
|
1306
|
+
```ts
|
|
1307
|
+
import { createWorkflowCli } from "@bastani/atomic/workflows";
|
|
1308
|
+
import { toCommand, runCli } from "@bastani/atomic/workflows/commander";
|
|
1309
|
+
import { Command } from "@commander-js/extra-typings";
|
|
1310
|
+
import workflow from "./workflows/deploy/claude.ts";
|
|
1311
|
+
|
|
1312
|
+
const cli = createWorkflowCli(workflow);
|
|
1313
|
+
|
|
1314
|
+
const program = new Command("my-app");
|
|
1315
|
+
program.addCommand(toCommand(cli, "deploy"));
|
|
1316
|
+
program.command("hello").action(() => console.log("hi"));
|
|
1317
|
+
|
|
1318
|
+
// Replaces program.parseAsync(). runCli transparently handles detached
|
|
1319
|
+
// re-entry — when the process is a tmux-spawned orchestrator, it drives
|
|
1320
|
+
// runOrchestrator; otherwise it invokes your callback (argv parse + any
|
|
1321
|
+
// bootstrap you want). PyTorch's init_process_group for rank-zero
|
|
1322
|
+
// dispatch — no guards, no env-var checks in user code.
|
|
1323
|
+
await runCli(cli, () => program.parseAsync());
|
|
1324
|
+
```
|
|
1325
|
+
|
|
1326
|
+
`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.
|
|
1327
|
+
|
|
1328
|
+
### `entry` — for bundled apps and test harnesses
|
|
1329
|
+
|
|
1330
|
+
`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.
|
|
1331
|
+
|
|
1332
|
+
```ts
|
|
1333
|
+
const cli = createWorkflowCli(workflow, { entry: import.meta.url });
|
|
1334
|
+
```
|
|
1335
|
+
|
|
1336
|
+
### Registry rules
|
|
1337
|
+
|
|
1338
|
+
- `createRegistry()` returns an **immutable** registry. Each `.register(wf)` call returns a **new** registry — the original is unchanged. Chain calls to accumulate workflows.
|
|
1339
|
+
- Each workflow is keyed by `${agent}/${name}` — the `(agent, name)` pair must be unique. Registering a duplicate throws immediately.
|
|
1340
|
+
- `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.
|
|
1341
|
+
- 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.
|
|
1342
|
+
|
|
1343
|
+
### Input precedence
|
|
1344
|
+
|
|
1345
|
+
CLI flags always win when parsing is active. Under them, the order is:
|
|
1346
|
+
|
|
1347
|
+
1. `defineWorkflow` default values (on each `WorkflowInput`)
|
|
1348
|
+
2. Layer supplied at construction or invocation:
|
|
1349
|
+
- `cli.run({ inputs })` for the single-workflow shape
|
|
1350
|
+
- `createWorkflowCli(registry, { inputs })` / `cli.run({ inputs })` for the multi-workflow shape
|
|
1351
|
+
3. CLI flags — `--<field>=<value>` passed at runtime
|
|
1352
|
+
|
|
1353
|
+
With `argv: false`, the CLI-flag layer is skipped — your programmatic `inputs` become top-of-chain.
|
|
1354
|
+
|
|
1355
|
+
### Builtin workflows via the `atomic` CLI
|
|
1356
|
+
|
|
1357
|
+
The `atomic workflow` command still works for the three built-in workflows — internally it's `toCommand(createWorkflowCli(createBuiltinRegistry()), "workflow")`:
|
|
1358
|
+
|
|
1359
|
+
```bash
|
|
1360
|
+
atomic workflow -n ralph -a claude "Build the auth module"
|
|
1361
|
+
atomic workflow -n deep-research-codebase -a claude "How does auth work?"
|
|
1362
|
+
atomic workflow -n open-claude-design -a claude
|
|
1363
|
+
```
|
|
1364
|
+
|
|
1365
|
+
These are not affected by your own `createRegistry()` — they are separate.
|
|
1366
|
+
|
|
1367
|
+
### Migration from 0.x (directory-scanning) to current
|
|
1368
|
+
|
|
1369
|
+
> This is a breaking change. The SDK no longer scans `.atomic/workflows/` directories.
|
|
1370
|
+
|
|
1371
|
+
1. **Delete** `.atomic/workflows/` from your repo.
|
|
1372
|
+
2. **Create one entrypoint file per agent**, e.g. `src/claude-worker.ts`:
|
|
1373
|
+
```ts
|
|
1374
|
+
import { createWorkflowCli } from "@bastani/atomic/workflows";
|
|
1375
|
+
import workflow from "./workflows/my-workflow/claude.ts";
|
|
1376
|
+
|
|
1377
|
+
await createWorkflowCli(workflow).run();
|
|
1378
|
+
```
|
|
1379
|
+
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>`.
|
|
1380
|
+
|
|
1381
|
+
---
|
|
1382
|
+
|
|
1109
1383
|
## Configuration
|
|
1110
1384
|
|
|
1111
1385
|
### `.atomic/settings.json`
|
|
@@ -1120,17 +1394,22 @@ Resolution order:
|
|
|
1120
1394
|
"$schema": "https://raw.githubusercontent.com/flora131/atomic/main/assets/settings.schema.json",
|
|
1121
1395
|
"version": 1,
|
|
1122
1396
|
"scm": "github",
|
|
1123
|
-
"
|
|
1397
|
+
"providers": {
|
|
1398
|
+
"claude": {
|
|
1399
|
+
"chatFlags": ["--model", "claude-sonnet-4-6"],
|
|
1400
|
+
"envVars": { "CLAUDE_CODE_MAX_OUTPUT_TOKENS": "16384" }
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1124
1403
|
}
|
|
1125
1404
|
```
|
|
1126
1405
|
|
|
1127
1406
|
|
|
1128
|
-
| Field
|
|
1129
|
-
|
|
|
1130
|
-
| `$schema`
|
|
1131
|
-
| `version`
|
|
1132
|
-
| `scm`
|
|
1133
|
-
| `
|
|
1407
|
+
| Field | Type | Description |
|
|
1408
|
+
| ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1409
|
+
| `$schema` | string | JSON Schema URL for editor autocomplete |
|
|
1410
|
+
| `version` | number | Config schema version (currently `1`) |
|
|
1411
|
+
| `scm` | string | Source control provider — `github`, `azure-devops`, or `sapling`. Reconciles the GitHub / Azure DevOps MCP servers in agent configs on startup. |
|
|
1412
|
+
| `providers` | object | Per-provider overrides for `claude`, `opencode`, `copilot`. `chatFlags` replaces built-in defaults entirely; `envVars` are merged |
|
|
1134
1413
|
|
|
1135
1414
|
> Model selection and reasoning effort are managed by each underlying agent CLI (e.g. Claude Code's `/model`), not Atomic. Atomic's chat command spawns the agent's native TUI — use the agent's own controls.
|
|
1136
1415
|
|