@bastani/atomic 0.5.20-0 → 0.5.21-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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: workflow-creator
3
- description: Create multi-agent workflows for Atomic CLI using defineWorkflow().run().compile() with ctx.stage() for session orchestration across Claude, Copilot, and OpenCode SDKs, AND invoke existing workflows on behalf of the user. Use whenever the user wants to create, edit, debug, or RUN workflows ("run the ralph workflow", "kick off deep-research-codebase", "start the gen-spec workflow"), build agent pipelines, define multi-stage automations, set up review loops, declare workflow inputs, run background/headless stages, or mentions .atomic/workflows/, defineWorkflow, ctx.stage, ctx.inputs, headless, background stages, the atomic workflow picker, or `atomic workflow -n`.
3
+ description: Create multi-agent workflows for Atomic CLI using defineWorkflow().run().compile() with ctx.stage() for session orchestration across Claude, Copilot, and OpenCode SDKs, AND invoke, monitor, and tear down existing workflows on behalf of the user. Use whenever the user wants to create, edit, debug, or RUN workflows ("run the ralph workflow", "kick off deep-research-codebase", "start the gen-spec workflow"), check on a running workflow ("is it done yet?", "what's the status?", "did it error out?"), kill a workflow or session, build agent pipelines, define multi-stage automations, set up review loops, declare workflow inputs, run background/headless stages, or mentions .atomic/workflows/, defineWorkflow, ctx.stage, ctx.inputs, headless, background stages, the atomic workflow picker, `atomic workflow -n`, `atomic workflow inputs`, `atomic workflow status`, or `atomic session kill`.
4
4
  ---
5
5
 
6
6
  # Workflow Creator
@@ -208,7 +208,10 @@ Workflows that accept a free-form prompt should declare it explicitly: `{ name:
208
208
  | Named, with prompt | `atomic workflow -n hello -a claude "fix the bug"` | Scripted runs; requires the workflow to declare a `prompt` input |
209
209
  | Named, structured | `atomic workflow -n gen-spec -a claude --research_doc=notes.md` | Scripted structured runs |
210
210
  | Interactive picker | `atomic workflow -a claude` | Discovery; shows fuzzy list + form |
211
- | List | `atomic workflow -l` | Browse everything by source |
211
+ | List | `atomic workflow list` | Browse everything by source |
212
+ | Inspect inputs | `atomic workflow inputs <name> -a claude` | Print a workflow's input schema as JSON — agents use this instead of reading source |
213
+ | Status (one or all) | `atomic workflow status [<session-id>]` | Query state — `in_progress`, `error`, `completed`, `needs_review` (HIL pause). JSON by default |
214
+ | Kill non-interactively | `atomic session kill <id> -y` | Tear down a workflow/chat session without the confirmation prompt — the form agents use |
212
215
  | Detached (background) | `atomic workflow -n ralph -a claude -d "..."` | Scripted/CI runs where the caller shouldn't block on the TUI — the orchestrator keeps running on the atomic tmux socket; attach later with `atomic workflow session connect <name>` |
213
216
 
214
217
  Any of the named shapes above (positional or structured) accepts `-d` / `--detach` to run without attaching. Use it when you're automating from a script and want the CLI to return as soon as the session is spawned.
@@ -398,9 +401,18 @@ Once you've confirmed the workflow exists, you need to know two things about its
398
401
  1. **Does it declare a `prompt` input?** If so, it's free-form — you pass a positional string.
399
402
  2. **Does it declare structured inputs?** If so, you pass `--<field>=<value>` flags, one per required field.
400
403
 
401
- Read the workflow file at `.atomic/workflows/<name>/<agent>/index.ts` and inspect the `inputs` array. The `atomic workflow list` output is good for discovery but doesn't print the full schema for accurate field types, requireds, and enum values, read the source.
404
+ **Use `atomic workflow inputs <name> -a <agent>` to get the schema.** This prints a JSON envelope with every field's `name`, `type`, `required`, `default`, `description`, and (for enums) `values` exactly what AskUserQuestion needs. The `freeform: true` flag tells you whether the workflow takes a positional prompt vs. structured flags, with a synthetic `prompt` field included so the JSON shape is uniform either way.
402
405
 
403
- Once you know the schema, use the **AskUserQuestion tool** to collect any values the user hasn't already provided in their message. One question per missing input field. For enum fields, pass the declared `values` as multiple-choice options so the user sees exactly what's allowed. Keep questions tight and purposeful — if the user's message already answers a question, don't ask it again.
406
+ ```bash
407
+ atomic workflow inputs gen-spec -a claude
408
+ # {"workflow":"gen-spec","agent":"claude","freeform":false,
409
+ # "inputs":[{"name":"research_doc","type":"string","required":true,...},
410
+ # {"name":"focus","type":"enum","values":["minimal","standard","exhaustive"],"default":"standard"}]}
411
+ ```
412
+
413
+ Why this command instead of reading the source file: `inputs` is the contract the CLI actually validates against. It survives refactors, handles built-in workflows that aren't in the project tree, and never falls out of sync with the runtime. Reading TypeScript source is a fallback for the rare case where the command can't resolve the workflow.
414
+
415
+ Once you have the schema, use the **AskUserQuestion tool** to collect any values the user hasn't already provided in their message. One question per missing input field. For enum fields, pass the declared `values` as multiple-choice options so the user sees exactly what's allowed. Keep questions tight and purposeful — if the user's message already answers a question, don't ask it again.
404
416
 
405
417
  Skip AskUserQuestion entirely when:
406
418
  - The user already supplied every required value in their message ("run ralph on 'add OAuth to the API'" — the prompt is right there).
@@ -413,13 +425,46 @@ Skip AskUserQuestion entirely when:
413
425
  - Exact match in the list → continue.
414
426
  - Close match → confirm via AskUserQuestion before proceeding.
415
427
  - No match → tell the user what's available and offer to author it (see previous section). If they decline, stop.
416
- 3. **Discover the inputs schema** — read the workflow source file and inspect `inputs`.
428
+ 3. **Discover the inputs schema** — run `atomic workflow inputs <name> -a <agent>` and parse the JSON.
417
429
  4. **Ask for missing inputs** — use AskUserQuestion, one question per unanswered required field. Enums become multiple-choice.
418
430
  5. **Invoke** — build one of these commands:
419
431
  - Free-form: `atomic workflow -n <name> "<prompt>"`
420
432
  - Structured: `atomic workflow -n <name> --<field1>=<value1> --<field2>=<value2>`
421
433
  6. **Report the session name** the CLI printed and tell the user: "attach any time with `atomic workflow session connect <session>` — or `atomic workflow session list` to see what's running."
422
434
 
435
+ ### Monitoring a running workflow
436
+
437
+ Detached workflows return immediately with a session name; the actual work runs in the background on the atomic tmux socket. Use `atomic workflow status` to check whether the workflow is still running, has completed, errored out, or paused for human input — without attaching to its TUI.
438
+
439
+ ```bash
440
+ atomic workflow status atomic-wf-claude-gen-spec-a1b2c3d4
441
+ # {"id":"atomic-wf-claude-gen-spec-a1b2c3d4","overall":"in_progress","alive":true,
442
+ # "sessions":[{"name":"orchestrator","status":"running",...}],...}
443
+ ```
444
+
445
+ Four overall states the agent must handle distinctly:
446
+
447
+ | Status | Meaning | What you should do |
448
+ |---|---|---|
449
+ | `in_progress` | The orchestrator is running and no stage is paused | Wait, or report progress to the user |
450
+ | `needs_review` | At least one stage is paused for human input (HIL) — Copilot `ask_user`, OpenCode `question.asked`, Copilot/MCP elicitation | **Surface this to the user immediately** — they need to attach with `atomic workflow session connect <id>` to respond, otherwise the workflow stalls indefinitely |
451
+ | `completed` | Workflow finished successfully | Report success and summarize the output |
452
+ | `error` | Fatal error or a stage failed | Report the `fatalError` field and offer to investigate logs |
453
+
454
+ `needs_review` outranks `completed` so a HIL pause near the end is never reported as done while still waiting on a human. A dead orchestrator with a stale snapshot is automatically downgraded to `error`.
455
+
456
+ Omit the id to list every running workflow at once: `atomic workflow status`. Useful when checking on multiple parallel runs, or when the user just asks "what's running?".
457
+
458
+ ### Cleaning up sessions
459
+
460
+ When the user is done with a workflow — or you launched one detached and it's no longer needed — tear it down with `-y` so no confirmation prompt blocks you:
461
+
462
+ ```bash
463
+ atomic session kill atomic-wf-claude-gen-spec-a1b2c3d4 -y
464
+ ```
465
+
466
+ The `-y` flag is mandatory for agent use. Without it, the CLI calls `@clack/prompts confirm`, which expects a TTY and will hang indefinitely in a non-interactive context. Same flag works for `atomic workflow session kill` and `atomic chat session kill`. Without an id, `kill -y` tears down every in-scope session — only do that when the user has asked to stop everything.
467
+
423
468
  ### Worked examples
424
469
 
425
470
  **Example A — workflow exists, structured inputs**
@@ -428,10 +473,10 @@ Skip AskUserQuestion entirely when:
428
473
 
429
474
  1. Run `atomic workflow list`. Output includes `gen-spec` under local. Good.
430
475
  2. Target resolved exactly: `gen-spec`.
431
- 3. Read the workflow source inputs are `research_doc` (required string — already given), `focus` (required enum of `minimal|standard|exhaustive`, no default), `notes` (optional text).
476
+ 3. Run `atomic workflow inputs gen-spec -a claude`. Parse the JSON: `research_doc` (required string — already given), `focus` (required enum of `minimal|standard|exhaustive`, default `standard`), `notes` (optional text).
432
477
  4. Ask via AskUserQuestion once: "What focus level for the spec?" with choices `minimal`, `standard`, `exhaustive`. User picks `standard`. Skip `notes` since it's optional.
433
478
  5. Run: `atomic workflow -n gen-spec --research_doc=research/docs/2026-04-11-auth.md --focus=standard`
434
- 6. The CLI prints a session name like `atomic-wf-claude-gen-spec-a1b2c3d4`. Tell the user: "Started in the background. Attach with `atomic workflow session connect atomic-wf-claude-gen-spec-a1b2c3d4` or check progress with `atomic workflow session list`."
479
+ 6. The CLI prints a session name like `atomic-wf-claude-gen-spec-a1b2c3d4`. Tell the user: "Started in the background. Attach with `atomic workflow session connect atomic-wf-claude-gen-spec-a1b2c3d4`, check progress with `atomic workflow status atomic-wf-claude-gen-spec-a1b2c3d4`, or stop it with `atomic session kill atomic-wf-claude-gen-spec-a1b2c3d4 -y`."
435
480
 
436
481
  **Example B — workflow does not exist**
437
482
 
@@ -448,6 +493,9 @@ Skip AskUserQuestion entirely when:
448
493
 
449
494
  - **Skipping `atomic workflow list`** — leads to guessing and `workflow not found` errors. It's a one-line command; always run it.
450
495
  - **Inventing a workflow name** — if it's not in the list, it doesn't exist. Say so and offer to author it.
496
+ - **Reading the workflow source file to discover inputs** — use `atomic workflow inputs <name> -a <agent>` instead. JSON, no TS parsing required, always in sync with the runtime. Source-file reads are a fallback, not a default.
451
497
  - **Asking everything at once** — let AskUserQuestion drive one question per field. Enum fields are multiple-choice, not free text.
452
498
  - **Re-asking what the user already said** — read their message first.
453
- - **Forgetting to report the session name** — the user needs it to reattach.
499
+ - **Forgetting to report the session name** — the user needs it to reattach and to query status later.
500
+ - **Leaving `needs_review` unreported** — when `atomic workflow status` returns `needs_review`, surface it to the user right away. The workflow is blocked on human input and will sit forever otherwise.
501
+ - **Calling `session kill` without `-y`** — the prompt hangs in a non-interactive context. Always pass `-y` from an agent.
@@ -4,7 +4,7 @@
4
4
  * executor interface with the React-based session graph TUI.
5
5
  */
6
6
  import { type CliRenderer } from "@opentui/core";
7
- import type { PanelSession, PanelOptions } from "./orchestrator-panel-types.ts";
7
+ import type { PanelSession, PanelOptions, SessionData } from "./orchestrator-panel-types.ts";
8
8
  export declare class OrchestratorPanel {
9
9
  private store;
10
10
  private renderer;
@@ -54,5 +54,27 @@ export declare class OrchestratorPanel {
54
54
  waitForAbort(): Promise<void>;
55
55
  /** Tear down the terminal renderer and release resources. Idempotent. */
56
56
  destroy(): void;
57
+ /**
58
+ * Subscribe to store mutations. Returned function unsubscribes.
59
+ *
60
+ * Used by the orchestrator process to mirror the in-memory panel
61
+ * state to a `status.json` file on disk so out-of-process consumers
62
+ * (e.g. `atomic workflow status`) can read the live workflow state.
63
+ */
64
+ subscribe(fn: () => void): () => void;
65
+ /**
66
+ * Read-only snapshot of the fields needed by the on-disk status
67
+ * writer. Defined here (not in PanelStore) because the store keeps
68
+ * full mutable references; this projection drops the renderer-only
69
+ * promise resolvers and version counter.
70
+ */
71
+ getSnapshot(): {
72
+ workflowName: string;
73
+ agent: string;
74
+ prompt: string;
75
+ fatalError: string | null;
76
+ completionReached: boolean;
77
+ sessions: readonly SessionData[];
78
+ };
57
79
  }
58
80
  //# sourceMappingURL=orchestrator-panel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator-panel.d.ts","sourceRoot":"","sources":["../../../src/sdk/components/orchestrator-panel.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC;;;GAGG;AAEH,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAOpE,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAIhF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO;IAsCP;;;;;OAKG;WACU,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQtE,0EAA0E;IAC1E,MAAM,CAAC,kBAAkB,CACvB,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,YAAY,GACpB,iBAAiB;IAOpB;;;OAGG;IACH,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,YAAY,EAAE,EACxB,MAAM,EAAE,MAAM,GACb,IAAI;IAIP,iDAAiD;IACjD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhC,gEAAgE;IAChE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,8EAA8E;IAC9E,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjD,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,0DAA0D;IAC1D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAUjD,8EAA8E;IAC9E,qBAAqB,IAAI,IAAI;IAI7B,8EAA8E;IAC9E,sBAAsB,IAAI,IAAI;IAI9B,0EAA0E;IAC1E,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAInE,+CAA+C;IAC/C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrC;;;OAGG;IACH,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;OAGG;IACH,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B,yEAAyE;IACzE,OAAO,IAAI,IAAI;CAOhB"}
1
+ {"version":3,"file":"orchestrator-panel.d.ts","sourceRoot":"","sources":["../../../src/sdk/components/orchestrator-panel.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC;;;GAGG;AAEH,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAOpE,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAI7F,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO;IAsCP;;;;;OAKG;WACU,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQtE,0EAA0E;IAC1E,MAAM,CAAC,kBAAkB,CACvB,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,YAAY,GACpB,iBAAiB;IAOpB;;;OAGG;IACH,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,YAAY,EAAE,EACxB,MAAM,EAAE,MAAM,GACb,IAAI;IAIP,iDAAiD;IACjD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhC,gEAAgE;IAChE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,8EAA8E;IAC9E,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjD,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,0DAA0D;IAC1D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAUjD,8EAA8E;IAC9E,qBAAqB,IAAI,IAAI;IAI7B,8EAA8E;IAC9E,sBAAsB,IAAI,IAAI;IAI9B,0EAA0E;IAC1E,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAInE,+CAA+C;IAC/C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrC;;;OAGG;IACH,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;OAGG;IACH,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B,yEAAyE;IACzE,OAAO,IAAI,IAAI;IAQf;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAIrC;;;;;OAKG;IACH,WAAW,IAAI;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,iBAAiB,EAAE,OAAO,CAAC;QAC3B,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;KAClC;CAUF"}
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Workflow status snapshot — bridges the in-process panel state with
3
+ * out-of-process consumers (e.g. `atomic workflow status`).
4
+ *
5
+ * The orchestrator subscribes to its `PanelStore` and writes a fresh
6
+ * snapshot to `~/.atomic/sessions/<workflowRunId>/status.json` every
7
+ * time the store mutates. Consumers read that file to derive the
8
+ * overall workflow state without needing IPC into the orchestrator.
9
+ */
10
+ import type { SessionData, SessionStatus } from "../components/orchestrator-panel-types.ts";
11
+ /** File name used for the status snapshot inside each workflow's session directory. */
12
+ export declare const STATUS_FILE_NAME = "status.json";
13
+ /** High-level workflow state surfaced to the agent / CLI consumer. */
14
+ export type WorkflowOverallStatus = "in_progress" | "error" | "completed" | "needs_review";
15
+ /** Per-session entry mirrored from the orchestrator's panel store. */
16
+ export interface WorkflowStatusSession {
17
+ name: string;
18
+ status: SessionStatus;
19
+ parents: string[];
20
+ error?: string;
21
+ startedAt: number | null;
22
+ endedAt: number | null;
23
+ }
24
+ /**
25
+ * Snapshot persisted to disk for `atomic workflow status` to read.
26
+ * Schema is versioned so future readers can stay backwards-compatible.
27
+ */
28
+ export interface WorkflowStatusSnapshot {
29
+ schemaVersion: 1;
30
+ workflowRunId: string;
31
+ tmuxSession: string;
32
+ workflowName: string;
33
+ agent: string;
34
+ prompt: string;
35
+ /** Overall state derived from per-session status + completion flags. */
36
+ overall: WorkflowOverallStatus;
37
+ /** True when the orchestrator has shown its completion banner. */
38
+ completionReached: boolean;
39
+ /** Fatal-error message set via `panel.showFatalError`, if any. */
40
+ fatalError: string | null;
41
+ /** Wall-clock time of the snapshot in ISO-8601 format. */
42
+ updatedAt: string;
43
+ sessions: WorkflowStatusSession[];
44
+ }
45
+ /**
46
+ * Inputs the writer needs to render a snapshot — a strict subset of
47
+ * `PanelStore` so the writer doesn't depend on the renderer module.
48
+ */
49
+ export interface StatusWriterInputs {
50
+ workflowRunId: string;
51
+ tmuxSession: string;
52
+ workflowName: string;
53
+ agent: string;
54
+ prompt: string;
55
+ fatalError: string | null;
56
+ completionReached: boolean;
57
+ sessions: readonly SessionData[];
58
+ }
59
+ /**
60
+ * Derive the overall workflow state from per-session statuses + the
61
+ * orchestrator-level completion / fatal-error flags.
62
+ *
63
+ * Precedence (highest first):
64
+ * 1. `error` — fatal error or any session ended in error
65
+ * 2. `needs_review` — at least one session is awaiting human input (HIL)
66
+ * 3. `completed` — completion banner reached and nothing errored
67
+ * 4. `in_progress` — default
68
+ *
69
+ * `needs_review` outranks `completed` so an agent that pauses for HIL
70
+ * right at the end is never reported as done while still waiting.
71
+ */
72
+ export declare function deriveOverallStatus(input: {
73
+ sessions: readonly SessionData[];
74
+ completionReached: boolean;
75
+ fatalError: string | null;
76
+ }): WorkflowOverallStatus;
77
+ /** Build a snapshot from the writer inputs (pure — exported for tests). */
78
+ export declare function buildSnapshot(input: StatusWriterInputs, now?: () => Date): WorkflowStatusSnapshot;
79
+ /** Absolute path of the status file for a given workflow run directory. */
80
+ export declare function statusFilePath(sessionDir: string): string;
81
+ /**
82
+ * Write a snapshot to `<sessionDir>/status.json`. Uses an atomic
83
+ * write-then-rename so concurrent readers never see partial JSON.
84
+ * Errors are swallowed — the orchestrator must keep running even if
85
+ * the status file can't be persisted.
86
+ */
87
+ export declare function writeSnapshot(sessionDir: string, snapshot: WorkflowStatusSnapshot): Promise<void>;
88
+ /**
89
+ * Read a snapshot from disk. Returns `null` when the file doesn't
90
+ * exist or fails to parse — callers fall back to deriving status from
91
+ * the live tmux session list.
92
+ */
93
+ export declare function readSnapshot(sessionDir: string): Promise<WorkflowStatusSnapshot | null>;
94
+ /**
95
+ * Extract the `workflowRunId` (the trailing 8-hex segment) from a
96
+ * tmux session name shaped `atomic-wf-<agent>-<name>-<id>`. Returns
97
+ * `null` for non-workflow sessions or names that don't end in a
98
+ * UUID-style suffix.
99
+ */
100
+ export declare function workflowRunIdFromTmuxName(name: string): string | null;
101
+ //# sourceMappingURL=status-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-writer.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/status-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAE5F,uFAAuF;AACvF,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C,sEAAsE;AACtE,MAAM,MAAM,qBAAqB,GAC7B,aAAa,GACb,OAAO,GACP,WAAW,GACX,cAAc,CAAC;AAEnB,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,CAAC,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,qBAAqB,CAAC;IAC/B,kEAAkE;IAClE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kEAAkE;IAClE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,qBAAqB,CAQxB;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAC3B,KAAK,EAAE,kBAAkB,EACzB,GAAG,GAAE,MAAM,IAAuB,GACjC,sBAAsB,CAyBxB;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,sBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAUxC;AAeD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQrE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/atomic",
3
- "version": "0.5.20-0",
3
+ "version": "0.5.21-0",
4
4
  "description": "Configuration management CLI and SDK for coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/cli.ts CHANGED
@@ -9,11 +9,13 @@
9
9
  * atomic chat session list List running chat/workflow sessions
10
10
  * atomic chat session connect <id> Attach to a session
11
11
  * atomic workflow list List available workflows
12
+ * atomic workflow inputs <name> -a <agent> Print a workflow's input schema (JSON)
13
+ * atomic workflow status [<id>] Query workflow status (JSON)
12
14
  * atomic workflow session list List running sessions
13
15
  * atomic workflow session connect <id> Attach to a session
14
16
  * atomic session list List all running sessions
15
17
  * atomic session connect [id] Interactive session picker
16
- * atomic session kill [id] Kill a session (or all when no id)
18
+ * atomic session kill [id] [-y] Kill a session (or all when no id); -y skips prompt
17
19
  * atomic config set <key> <value> Set configuration value
18
20
  * atomic --version Show version
19
21
  * atomic --help Show help
@@ -88,9 +90,16 @@ function addSessionSubcommand(parent: Command, scope: "chat" | "workflow" | "all
88
90
  collectAgent,
89
91
  [] as string[],
90
92
  )
93
+ .option("-y, --yes", "Skip the confirmation prompt (for non-interactive callers like agents)")
91
94
  .action(async (sessionId, localOpts) => {
92
95
  const { sessionKillCommand } = await import("./commands/cli/session.ts");
93
- const exitCode = await sessionKillCommand(sessionId, localOpts.agent, scope);
96
+ const exitCode = await sessionKillCommand(
97
+ sessionId,
98
+ localOpts.agent,
99
+ scope,
100
+ undefined,
101
+ { yes: localOpts.yes === true },
102
+ );
94
103
  process.exit(exitCode);
95
104
  });
96
105
 
@@ -220,9 +229,12 @@ Examples:
220
229
  $ atomic workflow -n gen-spec -a claude --research_doc=notes.md --focus=standard
221
230
  Run a structured-input workflow
222
231
  $ atomic workflow -n ralph -a claude -d "fix bug" Run detached in the background
232
+ $ atomic workflow inputs <name> -a claude Print a workflow's input schema (JSON)
233
+ $ atomic workflow status List status for all running workflows
234
+ $ atomic workflow status <id> Query a single workflow's status
223
235
  $ atomic workflow session list List running sessions
224
236
  $ atomic workflow session connect <id> Attach to a session
225
- $ atomic workflow session kill [id] Kill a workflow session (or all)`,
237
+ $ atomic workflow session kill [id] -y Kill a workflow session (or all), no prompt`,
226
238
  )
227
239
  .action(async (localOpts, cmd) => {
228
240
  const { workflowCommand } = await import("./commands/cli/workflow.ts");
@@ -249,6 +261,48 @@ Examples:
249
261
  process.exit(exitCode);
250
262
  });
251
263
 
264
+ // Workflow inputs subcommand: atomic workflow inputs <name> -a <agent>
265
+ // Exposes the declared input schema so an orchestrating agent can build
266
+ // a valid `atomic workflow -n ...` invocation without reading source.
267
+ workflowCmd
268
+ .command("inputs")
269
+ .description("Print a workflow's declared input schema (JSON by default)")
270
+ .argument("<name>", "Workflow name")
271
+ .requiredOption("-a, --agent <name>", `Agent backend (${agentChoices})`)
272
+ .option("--format <format>", "Output format: json | text", "json")
273
+ .action(async (name, localOpts) => {
274
+ const { workflowInputsCommand } = await import(
275
+ "./commands/cli/workflow-inputs.ts"
276
+ );
277
+ const exitCode = await workflowInputsCommand({
278
+ name,
279
+ agent: localOpts.agent,
280
+ format: localOpts.format === "text" ? "text" : "json",
281
+ });
282
+ process.exit(exitCode);
283
+ });
284
+
285
+ // Workflow status subcommand: atomic workflow status [<id>]
286
+ // Returns one of in_progress | error | completed | needs_review.
287
+ // Defaults to JSON so agents can parse it without screen-scraping.
288
+ workflowCmd
289
+ .command("status")
290
+ .description(
291
+ "Query workflow status (in_progress, error, completed, needs_review)",
292
+ )
293
+ .argument("[session_id]", "Workflow tmux session id (omit to list all)")
294
+ .option("--format <format>", "Output format: json | text", "json")
295
+ .action(async (sessionId, localOpts) => {
296
+ const { workflowStatusCommand } = await import(
297
+ "./commands/cli/workflow-status.ts"
298
+ );
299
+ const exitCode = await workflowStatusCommand({
300
+ id: sessionId,
301
+ format: localOpts.format === "text" ? "text" : "json",
302
+ });
303
+ process.exit(exitCode);
304
+ });
305
+
252
306
  // Workflow session subcommands: atomic workflow session list / connect
253
307
  addSessionSubcommand(workflowCmd, "workflow");
254
308
 
@@ -711,4 +711,47 @@ describe("sessionKillCommand", () => {
711
711
  process.stdout.write = origWrite;
712
712
  }
713
713
  });
714
+
715
+ // (l) -y on named kill: skip prompt and kill immediately
716
+ test("yes flag skips the prompt for a named kill and calls killSession", async () => {
717
+ const now = new Date().toISOString();
718
+ tmuxMocks.listSessions.mockReturnValue([
719
+ { name: "target-session", windows: 1, created: now, attached: false, type: "chat" as const },
720
+ ]);
721
+ const origWrite = process.stdout.write;
722
+ process.stdout.write = (() => true) as typeof process.stdout.write;
723
+ try {
724
+ const code = await sessionKillCommand(
725
+ "target-session",
726
+ [],
727
+ "all",
728
+ makeDeps(),
729
+ { yes: true },
730
+ );
731
+ expect(code).toBe(0);
732
+ expect(tmuxMocks.confirm).not.toHaveBeenCalled();
733
+ expect(tmuxMocks.killSession).toHaveBeenCalledWith("target-session");
734
+ } finally {
735
+ process.stdout.write = origWrite;
736
+ }
737
+ });
738
+
739
+ // (m) -y on kill-all: skip prompt and kill every in-scope session
740
+ test("yes flag skips the prompt for kill-all and kills every in-scope session", async () => {
741
+ const now = new Date().toISOString();
742
+ tmuxMocks.listSessions.mockReturnValue([
743
+ { name: "session-a", windows: 1, created: now, attached: false, type: "chat" as const, agent: "claude" },
744
+ { name: "session-b", windows: 1, created: now, attached: false, type: "workflow" as const, agent: "opencode" },
745
+ ]);
746
+ const origWrite = process.stdout.write;
747
+ process.stdout.write = (() => true) as typeof process.stdout.write;
748
+ try {
749
+ const code = await sessionKillCommand(undefined, [], "all", makeDeps(), { yes: true });
750
+ expect(code).toBe(0);
751
+ expect(tmuxMocks.confirm).not.toHaveBeenCalled();
752
+ expect(tmuxMocks.killSession).toHaveBeenCalledTimes(2);
753
+ } finally {
754
+ process.stdout.write = origWrite;
755
+ }
756
+ });
714
757
  });
@@ -277,13 +277,19 @@ export async function sessionPickerCommand(agents: string[] = [], scope: Session
277
277
  *
278
278
  * - If `sessionId` is provided: confirm and kill that one session.
279
279
  * - If `sessionId` is omitted: confirm and kill all sessions in scope.
280
+ *
281
+ * Pass `yes: true` (the `-y/--yes` flag on the CLI) to skip the
282
+ * confirmation prompt — useful for orchestrating agents that need to
283
+ * tear down a workflow session non-interactively.
280
284
  */
281
285
  export async function sessionKillCommand(
282
286
  sessionId: string | undefined,
283
287
  agents: string[] = [],
284
288
  scope: SessionScope = "all",
285
289
  deps: SessionDeps = defaultDeps,
290
+ options: { yes?: boolean } = {},
286
291
  ): Promise<number> {
292
+ const skipConfirm = options.yes === true;
287
293
  const paint = createPainter();
288
294
 
289
295
  if (!deps.isTmuxInstalled()) {
@@ -318,10 +324,12 @@ export async function sessionKillCommand(
318
324
  return 1;
319
325
  }
320
326
 
321
- const answer = await deps.confirm({
322
- message: `Kill session '${sessionId}'?`,
323
- initialValue: false,
324
- });
327
+ const answer = skipConfirm
328
+ ? true
329
+ : await deps.confirm({
330
+ message: `Kill session '${sessionId}'?`,
331
+ initialValue: false,
332
+ });
325
333
 
326
334
  if (deps.isCancel(answer)) {
327
335
  cancel("Cancelled.");
@@ -353,10 +361,12 @@ export async function sessionKillCommand(
353
361
 
354
362
  const noun = targets.length === 1 ? "session" : "sessions";
355
363
  const scopePrefix = scope === "all" ? "" : `${scope} `;
356
- const answer = await deps.confirm({
357
- message: `Kill all ${targets.length} ${scopePrefix}${noun}?`,
358
- initialValue: false,
359
- });
364
+ const answer = skipConfirm
365
+ ? true
366
+ : await deps.confirm({
367
+ message: `Kill all ${targets.length} ${scopePrefix}${noun}?`,
368
+ initialValue: false,
369
+ });
360
370
 
361
371
  if (deps.isCancel(answer)) {
362
372
  cancel("Cancelled.");