@bastani/atomic 0.9.19-alpha.3 → 0.9.19-alpha.4

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 (159) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +8 -0
  3. package/dist/builtin/intercom/index.bundle.mjs +117 -26
  4. package/dist/builtin/intercom/package.json +1 -1
  5. package/dist/builtin/mcp/package.json +1 -1
  6. package/dist/builtin/subagents/CHANGELOG.md +12 -0
  7. package/dist/builtin/subagents/README.md +12 -12
  8. package/dist/builtin/subagents/package.json +1 -1
  9. package/dist/builtin/subagents/skills/subagent/SKILL.md +14 -14
  10. package/dist/builtin/subagents/src/extension/index.bundle.mjs +140 -58
  11. package/dist/builtin/web-access/package.json +1 -1
  12. package/dist/builtin/workflows/CHANGELOG.md +20 -0
  13. package/dist/builtin/workflows/README.md +14 -15
  14. package/dist/builtin/workflows/builtin/{chunk-mygmtz6e.js → chunk-9k3ywfgd.js} +1 -1
  15. package/dist/builtin/workflows/builtin/{chunk-r9qq7xfj.js → chunk-ahbntmx2.js} +1 -1
  16. package/dist/builtin/workflows/builtin/{chunk-zggjyg5z.js → chunk-n8zysf1t.js} +1 -1
  17. package/dist/builtin/workflows/builtin/goal.js +2 -2
  18. package/dist/builtin/workflows/builtin/index.js +3 -3
  19. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  20. package/dist/builtin/workflows/package.json +5 -5
  21. package/dist/builtin/workflows/src/extension/index.bundle.mjs +115 -174
  22. package/dist/builtin/workflows/src/index.js +19 -2
  23. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -1
  24. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +1 -1
  25. package/dist/core/agent-session-auto-compaction.js +1 -1
  26. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  27. package/dist/core/agent-session-compaction.js +1 -1
  28. package/dist/core/agent-session-compaction.js.map +1 -1
  29. package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
  30. package/dist/core/agent-session-custom-message-commit.js +33 -2
  31. package/dist/core/agent-session-custom-message-commit.js.map +1 -1
  32. package/dist/core/agent-session-message-queue.d.ts +1 -1
  33. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  34. package/dist/core/agent-session-message-queue.js +20 -6
  35. package/dist/core/agent-session-message-queue.js.map +1 -1
  36. package/dist/core/agent-session-methods.d.ts +4 -1
  37. package/dist/core/agent-session-methods.d.ts.map +1 -1
  38. package/dist/core/agent-session-methods.js.map +1 -1
  39. package/dist/core/agent-session-persistent-custom-messages.d.ts +1 -1
  40. package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
  41. package/dist/core/agent-session-persistent-custom-messages.js +13 -3
  42. package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
  43. package/dist/core/agent-session-post-tool-compaction.js +1 -1
  44. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  45. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  46. package/dist/core/agent-session-prompt.js +83 -0
  47. package/dist/core/agent-session-prompt.js.map +1 -1
  48. package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
  49. package/dist/core/agent-session-queue-pause.js +11 -0
  50. package/dist/core/agent-session-queue-pause.js.map +1 -1
  51. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  52. package/dist/core/agent-session-tool-hooks.js +2 -0
  53. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  54. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  55. package/dist/core/agent-session-tool-registry.js +12 -0
  56. package/dist/core/agent-session-tool-registry.js.map +1 -1
  57. package/dist/core/agent-session-transfer.d.ts.map +1 -1
  58. package/dist/core/agent-session-transfer.js +7 -0
  59. package/dist/core/agent-session-transfer.js.map +1 -1
  60. package/dist/core/agent-session-types.d.ts +2 -0
  61. package/dist/core/agent-session-types.d.ts.map +1 -1
  62. package/dist/core/agent-session-types.js +2 -0
  63. package/dist/core/agent-session-types.js.map +1 -1
  64. package/dist/core/agent-session.d.ts +4 -0
  65. package/dist/core/agent-session.d.ts.map +1 -1
  66. package/dist/core/agent-session.js +22 -0
  67. package/dist/core/agent-session.js.map +1 -1
  68. package/dist/core/extensions/context-types.d.ts +6 -0
  69. package/dist/core/extensions/context-types.d.ts.map +1 -1
  70. package/dist/core/extensions/context-types.js.map +1 -1
  71. package/dist/core/extensions/loader-virtual-modules.js +3 -3
  72. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  73. package/dist/core/extensions/runner-context.d.ts +1 -1
  74. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  75. package/dist/core/extensions/runner-context.js +9 -3
  76. package/dist/core/extensions/runner-context.js.map +1 -1
  77. package/dist/core/extensions/runner.js +1 -1
  78. package/dist/core/extensions/runner.js.map +1 -1
  79. package/dist/core/extensions/workflow-events.d.ts +1 -1
  80. package/dist/core/extensions/workflow-events.d.ts.map +1 -1
  81. package/dist/core/extensions/workflow-events.js.map +1 -1
  82. package/dist/core/sdk-exports.d.ts +1 -1
  83. package/dist/core/sdk-exports.d.ts.map +1 -1
  84. package/dist/core/sdk-exports.js +1 -1
  85. package/dist/core/sdk-exports.js.map +1 -1
  86. package/dist/core/settings-manager-basic-accessors.d.ts +5 -3
  87. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  88. package/dist/core/settings-manager-basic-accessors.js +23 -8
  89. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  90. package/dist/core/settings-manager.d.ts +1 -1
  91. package/dist/core/settings-manager.d.ts.map +1 -1
  92. package/dist/core/settings-manager.js.map +1 -1
  93. package/dist/core/settings-types.d.ts +5 -0
  94. package/dist/core/settings-types.d.ts.map +1 -1
  95. package/dist/core/settings-types.js.map +1 -1
  96. package/dist/core/slash-commands.d.ts.map +1 -1
  97. package/dist/core/slash-commands.js +4 -5
  98. package/dist/core/slash-commands.js.map +1 -1
  99. package/dist/core/tasks/agent-adapter.d.ts +5 -2
  100. package/dist/core/tasks/agent-adapter.d.ts.map +1 -1
  101. package/dist/core/tasks/agent-adapter.js +10 -3
  102. package/dist/core/tasks/agent-adapter.js.map +1 -1
  103. package/dist/core/tasks/completion.d.ts.map +1 -1
  104. package/dist/core/tasks/completion.js +5 -1
  105. package/dist/core/tasks/completion.js.map +1 -1
  106. package/dist/core/tools/bash-pty-native.d.ts +16 -2
  107. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  108. package/dist/core/tools/bash-pty-native.js +82 -0
  109. package/dist/core/tools/bash-pty-native.js.map +1 -1
  110. package/dist/core/tools/bash.d.ts +13 -2
  111. package/dist/core/tools/bash.d.ts.map +1 -1
  112. package/dist/core/tools/bash.js +48 -3
  113. package/dist/core/tools/bash.js.map +1 -1
  114. package/dist/core/tools/index.d.ts +4 -1
  115. package/dist/core/tools/index.d.ts.map +1 -1
  116. package/dist/core/tools/index.js +12 -0
  117. package/dist/core/tools/index.js.map +1 -1
  118. package/dist/core/tools/kill.d.ts +17 -0
  119. package/dist/core/tools/kill.d.ts.map +1 -0
  120. package/dist/core/tools/kill.js +49 -0
  121. package/dist/core/tools/kill.js.map +1 -0
  122. package/dist/core/tools/powershell.d.ts +84 -28
  123. package/dist/core/tools/powershell.d.ts.map +1 -1
  124. package/dist/core/tools/powershell.js +10 -3
  125. package/dist/core/tools/powershell.js.map +1 -1
  126. package/dist/core/workflow-stage-admission.d.ts +14 -0
  127. package/dist/core/workflow-stage-admission.d.ts.map +1 -1
  128. package/dist/core/workflow-stage-admission.js +63 -3
  129. package/dist/core/workflow-stage-admission.js.map +1 -1
  130. package/dist/index.d.ts +2 -2
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +1 -1
  133. package/dist/index.js.map +1 -1
  134. package/dist/modes/interactive/components/task-row.d.ts.map +1 -1
  135. package/dist/modes/interactive/components/task-row.js +8 -1
  136. package/dist/modes/interactive/components/task-row.js.map +1 -1
  137. package/docs/background-tasks.md +24 -1
  138. package/docs/compaction.md +20 -0
  139. package/docs/computer-use.md +390 -0
  140. package/docs/docs.json +1 -0
  141. package/docs/extensions.md +11 -1
  142. package/docs/herdr.md +2 -0
  143. package/docs/index.md +1 -0
  144. package/docs/intercom.md +10 -2
  145. package/docs/quickstart.md +1 -1
  146. package/docs/sdk.md +11 -1
  147. package/docs/settings.md +20 -0
  148. package/docs/subagents.md +7 -5
  149. package/docs/tmux.md +2 -0
  150. package/docs/tools.md +7 -1
  151. package/docs/usage.md +1 -1
  152. package/docs/workflows/api-reference.md +4 -3
  153. package/docs/workflows/authoring.md +3 -3
  154. package/docs/workflows/operations.md +36 -30
  155. package/docs/workflows/reliable-design.md +3 -3
  156. package/docs/workflows/verification.md +99 -40
  157. package/docs/workflows.md +4 -2
  158. package/npm-shrinkwrap.json +32 -32
  159. package/package.json +3 -3
@@ -45,7 +45,7 @@ After Atomic is running, use `/workflow reload` or the workflow tool's `reload`
45
45
 
46
46
  ### Workflow lifecycle notifications
47
47
 
48
- Workflow lifecycle notices are enabled by default. They send steer prompts into the main chat/model context when a run completes, fails, or ends blocked, and when a user starts, pauses, quits, or resumes one. Awaiting-input prompts are tracked for dedupe/restore, but they do not wake the main chat agent. Configure lifecycle tracking in the same extension config file:
48
+ Workflow lifecycle notices are enabled by default. They send steer prompts into the main chat/model context when a run completes, fails, or ends blocked, and when a user starts, quits, or resumes one. Awaiting-input prompts are tracked for dedupe/restore, but they do not wake the main chat agent. Configure lifecycle tracking in the same extension config file:
49
49
 
50
50
  ```json
51
51
  {
@@ -60,13 +60,13 @@ Set `enabled` to `false` to disable all lifecycle notices, or narrow `notifyOn`
60
60
 
61
61
  Treat blocked runs as continuable by default: resume, answer pending prompts, steer, or use a follow-up workflow. Explicit task-scoped inline/no-workflow requests override that default even for complex work. Safely hold/stop the affected run, reconcile completed work and in-flight effects, then continue inline without duplication; completed work is not undone. Keep safety, authorization and validation requirements. A `budget_exceeded` stop still requires approval before raising the chosen limit. See [verification and evidence](../coding-agent/docs/workflows/verification.md) for execution-mode scope, environment-aware browser/terminal/desktop verification, qlty setup and native GitHub attachments.
62
62
 
63
- Control notices report deliberate actions on a top-level run: `/workflow <name>` produces a `WORKFLOW STARTED` card (`▶`), `/workflow pause` a `WORKFLOW PAUSED` card (`⏸`, warning tone), `/workflow quit` a `WORKFLOW QUIT` card (`⏹`, warning tone, plus a `resumable` field), and `/workflow resume` a `WORKFLOW RESUMED` card (`▶`). All four travel the same steer delivery, capped-backoff retry, and card path as the failure notice. The paused and quit text says the stop was deliberate and user-requested and instructs the model not to resume the run or take the work over unless asked, hinting `/workflow resume <run-id>`; the resumed text does not, since the run is progressing again.
63
+ Control notices report deliberate actions on a top-level run: `/workflow <name>` produces a `WORKFLOW STARTED` card (`▶`), `/workflow quit` a `WORKFLOW QUIT` card (`⏹`, warning tone, plus a `resumable` field), and `/workflow resume` a `WORKFLOW RESUMED` card (`▶`). These travel the same steer delivery, capped-backoff retry, and card path as the failure notice. The quit text says the stop was deliberate and user-requested and instructs the model not to resume the run or take the work over unless asked, hinting `/workflow resume <run-id>`; the resumed text does not, since the run is progressing again.
64
64
 
65
- Only user actions notify. The matching `workflow({ action: "run" | "pause" | "quit" | "resume" })` tool calls stay silent, because the tool result already reports them to the agent, and `/workflow interrupt` raises nothing. Engine-internal transitions stay silent too — a notice exists only when a control path named an actor — which is what keeps answering a human-in-the-loop prompt, per-stage control, and the resume-acknowledgement pass from flooding the chat.
65
+ Only attributed user actions notify. The matching `workflow({ action: "run" | "pause" | "quit" | "resume" })` tool calls stay silent, because the tool result already reports them to the agent. `/workflow pause` does not attribute an actor or raise a main-chat control notice. Engine-internal transitions stay silent too — a notice exists only when a control path named an actor — which keeps answering a human-in-the-loop prompt and the resume-acknowledgement pass from flooding the chat. Workflow activity and lifecycle observation still report pause requests independently of chat notices.
66
66
 
67
- Each notice carries two attributions. *Origin* is who launched the run and renders on every kind as "which you started" or "which the user started"; it is recorded once at dispatch, persisted through session restore and durable resume, and inherited by a continuation from the run it continues. *Actor* is who performed this one event ("The user paused"). A run with no recorded origin omits the clause rather than guessing one.
67
+ Each notice carries two attributions. *Origin* is who launched the run and renders on every kind as "which you started" or "which the user started"; it is recorded once at dispatch, persisted through session restore and durable resume, and inherited by a continuation from the run it continues. *Actor* is who performed this one event ("The user resumed"). A run with no recorded origin omits the clause rather than guessing one.
68
68
 
69
- One request produces one notice. A whole-run pause or resume reports at run scope; a stage-scoped pause or resume that leaves siblings paused reports at stage scope, and one that stops or restarts the whole run reports the run instead. A quit reports the quit alone, never the pause it publishes on the way. Because control actions are reversible, they are deduplicated by run id together with the occurrence timestamp (`pausedAt`/`quitAt`/`resumedAt`), so pause → resume → pause → resume notifies four times while repeated snapshot invalidations at one unchanged state notify once. Resuming reports a resume and never a start, whoever asked for it. Resuming a failed or blocked run launches a continuation under a fresh run id and its notice names both; resuming a quit run reuses the original workflow id so durable checkpoints replay, so that notice names the one id. A run already started, paused, or quit when notifications install (restore, replay, `/reload`, session-preserving reinstall) is seeded as delivered and stays silent, and nested child runs never notify at top level.
69
+ One attributed request produces one notice. A whole-run resume reports at run scope; a stage-scoped resume reports at stage scope when siblings remain paused. A quit reports the quit alone, never the pause it publishes on the way. Notices are deduplicated by run id together with the occurrence timestamp (`quitAt`/`resumedAt`), so repeated snapshot invalidations at one unchanged state notify once. Resuming reports a resume and never a start, whoever asked for it. Resuming a failed or blocked run launches a continuation under a fresh run id and its notice names both; resuming a quit run reuses the original workflow id so durable checkpoints replay, so that notice names the one id. A run already started, paused, or quit when notifications install (restore, replay, `/reload`, session-preserving reinstall) is seeded as delivered and stays silent, and nested child runs never notify at top level.
70
70
 
71
71
  When a stage human-in-the-loop prompt is answered from the workflow TUI/stage chat, workflows also emits a separate display-only `workflows:hil-answer-notice` custom message. It records the answer for user-visible audit, but it does not wake the main agent, enter LLM context, or authorize answering later workflow prompts. Answers sent by the main-chat `workflow` tool do not emit this notice because the tool result already tells the main agent what happened.
72
72
 
@@ -267,7 +267,7 @@ export default workflow({
267
267
  });
268
268
  ```
269
269
 
270
- The child executes as a nested workflow behind a parent boundary stage named `workflow:<workflow-name>` by default, but user-facing status and graph views recursively replace that boundary with a valid, non-empty child graph whose run reciprocally identifies the parent run and boundary stage. Every boundary parent connects to every child root, and every child terminal connects to each downstream dependent. Repeated or sibling children keep distinct virtual node ids and exact `{ runId, stageId }` control targets even when local stage ids or names collide, so attach, send, pause, interrupt, resume, stage selection, and post-mortem chat reach the true owning run and stage. Implementation-owned child runs stay out of top-level `/workflow status` lists.
270
+ The child executes as a nested workflow behind a parent boundary stage named `workflow:<workflow-name>` by default, but user-facing status and graph views recursively replace that boundary with a valid, non-empty child graph whose run reciprocally identifies the parent run and boundary stage. Every boundary parent connects to every child root, and every child terminal connects to each downstream dependent. Repeated or sibling children keep distinct virtual node ids and exact `{ runId, stageId }` control targets even when local stage ids or names collide, so attach, send, pause, resume, stage selection, and post-mortem chat reach the true owning run and stage. Implementation-owned child runs stay out of top-level `/workflow status` lists.
271
271
 
272
272
  For durable runs, Atomic writes and awaits a versioned boundary-start identity before child code can run. That record fixes the boundary id, child run id, owning root/parent, source order and parents, replay scope, alias, workflow, and a deterministic fingerprint of the child definition plus exact validated inputs across pause, process restart, cached replay, and completed inspection. Distinct-input parallel calls therefore keep their own cache even when restart reverses dispatch order; repeated identical calls share the fingerprint but retain a per-invocation ordinal. A completed child boundary and its `ctx.tool` side effects replay exactly once from the root's scoped checkpoints; only incomplete work continues.
273
273
 
@@ -655,8 +655,7 @@ Tradeoff: `Type.Unsafe<T>()` does not deeply validate at runtime — it trusts t
655
655
  | `/workflow status [run-id]` | Show active plus retained terminal/current-session runs, or details for one run |
656
656
  | `/workflow connect [run-id]` | Open a workflow run graph |
657
657
  | `/workflow attach [run-id] [stage]` | Open live stage chat or explicit terminal post-mortem chat |
658
- | `/workflow pause [run-id] [stage]` | Pause a live run or stage |
659
- | `/workflow interrupt [run-id\|--all]` | Pause active/named/all active runs so they can resume |
658
+ | `/workflow pause [run-id\|--all]` | Pause active/named/all active runs so they can resume |
660
659
  | `/workflow quit [run-id\|--all]` | Gracefully pause live workflow runs so they can resume later |
661
660
  | `/workflow resume <run-id>` | Resume paused work or re-open a run snapshot |
662
661
  | `/workflow reload` | Reload discovered workflow resources and package-manifest entries in-process |
@@ -664,7 +663,7 @@ Tradeoff: `Type.Unsafe<T>()` does not deeply validate at runtime — it trusts t
664
663
 
665
664
  Input overrides are bare `key=value` tokens (no leading `--`). Values are JSON-parsed when possible, so numbers, booleans, and quoted strings work as expected (e.g. `count=3`, `flag=true`, `prompt="multi word value"`). A whole-object override can be passed as a single JSON token (e.g. `{"prompt":"...","count":3}`). Runtime validation is strict: unknown input keys, missing required values, type mismatches, and invalid `select` choices fail before a named workflow run starts.
666
665
 
667
- Named workflow launches always run as **background tasks** in interactive sessions. Run `/workflow connect <run>` to see agents working and chat with and steer each stage. Foreground launches are reserved for explicit user requests or technical requirements, with notice before launch. Press **F2** to open the same live graph viewer; HIL prompts (`ctx.ui.input/confirm/select/editor/custom`) appear as awaiting-input graph nodes. Press Enter on a focused node, click a visible graph node, or choose one from the switcher to open a `ctx.tool` node's one read-only agent-chat-style tool message block, never a modal dialog or editable transcript. Tool nodes remain non-attachable: their graph card body is always the constant `durable tool`, and the message block is collapsed by default with the tool name/call and a compact bounded result or error preview. The configured `app.tools.expand` action (`ctrl+o` by default) toggles full bounded args, result or error, callback source, timing, and cached/replayed markers. `↑`/`↓`, `PageUp`/`PageDown`, `Home`/`End`, the wheel, and the scrollbar scroll the block; Escape or `ctrl+x` returns to the graph. It is read-only and offers no attach, steer, interrupt, or resume action. `ctrl+x` is the workflow hierarchy chord: attached stage chats show **ctrl+x return to graph**, while graph surfaces show **ctrl+x leave graph · return to main chat**. Workflow surfaces consume it before configurable editor/tool actions. Composer and prompt drafts survive leaving a stage, and pending custom questions remain pending for reattachment. `ctrl+d` and `q` are not workflow navigation controls; ordinary editor/prompt Ctrl+D behavior and printable prompt `q` remain available. `esc`, `ctrl+c`, and graph `h` close/hide behavior are unchanged. While the graph pane is active, vertical wheel/trackpad gestures pan vertically and horizontal gestures pan wide graphs left and right when the terminal reports them, without falling through to the main chat or terminal scrollback. Focused graph and stage-chat overlays receive those gestures through the fullscreen application route. Fullscreen pi-tui owns application selection, so drag and multi-click selection also work over workflow overlays; copied text uses OSC 52, and terminals that refuse OSC 52 writes rely on the modifier-drag bypass (Shift/Option, as provided by the terminal). `ctrl+t` is not a workflow control: focused workflow overlays leave it to the host `app.thinking.toggle` action, while inline tree selectors keep `app.tree.filter.noTools`. Human input is detected when those runtime `ctx.ui.*` calls execute; workflows no longer have a declaration-time HIL flag.
666
+ Named workflow launches always run as **background tasks** in interactive sessions. Run `/workflow connect <run>` to see agents working and chat with and steer each stage. Foreground launches are reserved for explicit user requests or technical requirements, with notice before launch. Press **F2** to open the same live graph viewer; HIL prompts (`ctx.ui.input/confirm/select/editor/custom`) appear as awaiting-input graph nodes. Press Enter on a focused node, click a visible graph node, or choose one from the switcher to open a `ctx.tool` node's one read-only agent-chat-style tool message block, never a modal dialog or editable transcript. Tool nodes remain non-attachable: their graph card body is always the constant `durable tool`, and the message block is collapsed by default with the tool name/call and a compact bounded result or error preview. The configured `app.tools.expand` action (`ctrl+o` by default) toggles full bounded args, result or error, callback source, timing, and cached/replayed markers. `↑`/`↓`, `PageUp`/`PageDown`, `Home`/`End`, the wheel, and the scrollbar scroll the block; Escape or `ctrl+x` returns to the graph. It is read-only and offers no attach, steer, pause, or resume action. `ctrl+x` is the workflow hierarchy chord: attached stage chats show **ctrl+x return to graph**, while graph surfaces show **ctrl+x leave graph · return to main chat**. Workflow surfaces consume it before configurable editor/tool actions. Composer and prompt drafts survive leaving a stage, and pending custom questions remain pending for reattachment. `ctrl+d` and `q` are not workflow navigation controls; ordinary editor/prompt Ctrl+D behavior and printable prompt `q` remain available. `esc`, `ctrl+c`, and graph `h` close/hide behavior are unchanged. While the graph pane is active, vertical wheel/trackpad gestures pan vertically and horizontal gestures pan wide graphs left and right when the terminal reports them, without falling through to the main chat or terminal scrollback. Focused graph and stage-chat overlays receive those gestures through the fullscreen application route. Fullscreen pi-tui owns application selection, so drag and multi-click selection also work over workflow overlays; copied text uses OSC 52, and terminals that refuse OSC 52 writes rely on the modifier-drag bypass (Shift/Option, as provided by the terminal). `ctrl+t` is not a workflow control: focused workflow overlays leave it to the host `app.thinking.toggle` action, while inline tree selectors keep `app.tree.filter.noTools`. Human input is detected when those runtime `ctx.ui.*` calls execute; workflows no longer have a declaration-time HIL flag.
668
667
 
669
668
  Typing into an attached stage chat and pressing Enter steers: the message is consumed after the current assistant response finishes its tool batch and before the next model request, matching normal session steering. Ctrl+F queues a follow-up, consumed only when the agent would otherwise stop. Queued entries belong to the stage session rather than the pane, so leaving the stage and reattaching restores the pending `Steering:` / `Follow-up:` rows, and a detached stage node carries a `✉ N queued` badge in the graph.
670
669
 
@@ -672,13 +671,13 @@ At normal widths, the persistent `BACKGROUND` panel and interactive `/workflow s
672
671
 
673
672
  Named launches return only after startup admission, while the admitted workflow body and stages remain background work. Pre-body setup failures (including invalid input-bound reusable worktrees) are returned immediately from the original tool call as structured failed results with the concrete error and allocated run id; Atomic does not first claim that the workflow started, and it removes the unadmitted run so corrected inputs can be retried immediately. Failures after admission continue to use normal background status and lifecycle notices.
674
673
 
675
- Graceful quit is idempotent for already-paused runs and preserves unresolved `ctx.ui` prompts in DBOS. Pausing or interrupting a stage also holds every queued steering and follow-up item in place: no queued turn, late context-bearing delivery, or workflow continuation starts while the stage is paused, and the existing `resume` action releases the items once in their existing per-queue order without queue release itself starting a provider turn. Stable author-callsite-and-composed-nested-scope reservations are created before prompting and released by exact current-format token generation after answer checkpoint, rejection, or abort. Answering while quit/paused cannot advance workflow code until explicit resume.
674
+ Graceful quit is idempotent for already-paused runs and preserves unresolved `ctx.ui` prompts in DBOS. Pausing a stage also holds every queued steering and follow-up item in place: no queued turn, late context-bearing delivery, or workflow continuation starts while the stage is paused, and the existing `resume` action releases the items once in their existing per-queue order without queue release itself starting a provider turn. Stable author-callsite-and-composed-nested-scope reservations are created before prompting and released by exact current-format token generation after answer checkpoint, rejection, or abort. Answering while quit/paused cannot advance workflow code until explicit resume.
676
675
 
677
676
  Workflow durability uses DBOS/Postgres as its only persistent backend. Atomic initializes it lazily on the first workflow action, reuses that process-wide instance, and awaits readiness before durable execution or control. `DBOS_SYSTEM_DATABASE_URL` selects an existing database when supplied. Otherwise Atomic first provisions its embedded Postgres (npm-distributed binaries, directly spawned under `~/.atomic/postgres` on port 5439, shared across sessions) and tries DBOS's reusable `dbos-db` Docker container if embedded provisioning fails without leaving retained-process cleanup pending. Linux root execution clears inherited supplementary groups before dropping Postgres to an unprivileged primary GID/UID; when that account cannot traverse the installed binaries, Atomic publishes one exact package-content runtime generation under a root-owned cache, where it stays readable/executable but not writable by Postgres. Reuse and publication re-snapshot the current source, validate the deterministic path after rename, and fail closed on source mutation, corruption, or setup-lease displacement without accumulating unbounded repair copies. If DBOS still cannot become ready, Atomic shows interactive and RPC actions a display-only warning notification that is not added to agent/model context, then runs against one process-local in-memory backend. Print and other headless actions without a usable UI write the same actionable warning to the console instead. Workflow execution continues, but its state does not survive the process and `/workflow resume` after exit has nothing to restore. Once DBOS is ready, query or write failures fail the workflow action and do not switch backends. Abrupt Atomic exit releases the retained native process lease without killing Postgres. Orderly shutdown sends fast shutdown and waits on that exact retained process; sessions attached to an already-running cluster never own or stop it. Concurrent Atomic sessions safely share one database: unique per-process executor ids, owner/heartbeat metadata on running workflows, and first-writer-wins claims on contended status transitions prevent double dispatch. Running workflows never appear as resume targets in any session; stale-heartbeat (crashed) ones surface as red `crashed` rows, paused rows render yellow, failed/blocked red, completed green, and the open picker live-updates on local changes plus a bounded cross-session poll.
678
677
 
679
678
  DBOS is the only durable catalog for resume, completed inspection, deletion, and targeted lookup. Session JSONL files remain chat transcripts only. Atomic reads one current durable format and does not convert prior local state or pre-current DBOS records. A completed current-format child checkpoint created before boundary-start or invocation-fingerprint identity existed is shown only when its child checkpoints reciprocally prove the same root, parent run, boundary, child owner, and scope. Active checkpoints without a provable invocation fingerprint, and malformed, duplicate, stale, nonreciprocal, mixed, aliased, cyclic, orphaned, or unsupported topology, fail closed before cache exposure or child/control dispatch: Atomic does not invent a child link or execute child code to repair it.
680
679
 
681
- Nested `ctx.workflow(...)` calls are displayed as an expanded graph within the top-level run. `/workflow status` and run pickers list only top-level user-launched workflows, not implementation-owned child runs. After a fresh process starts, active and completed graphs retain source stage ids, order, parent edges, lifecycle status, boundary ownership, and exact `{ runId, stageId }` control targets. The `workflow` tool's `stages`, `stage`, `transcript`, `answer`, `pause`, `interrupt`, and `resume` actions route a uniquely identified visible child stage to that nested owner, and ambiguous local ids or names are rejected. Run-level `quit` still targets the selected top-level run or all live top-level runs. Completed graph inspection is read-only even when no stage transcript remains. `/workflow attach <root-run> <nested-stage>` remains the explicit user-driven path for retained post-mortem chat and routes to the true child owner without resuming or mutating execution. (`stages`, `stage`, `transcript`, and `answer` are `workflow` tool actions, not `/workflow` slash subcommands; the slash command exposes `connect`, `attach`, `pause`, `list`, `status`, `interrupt`, `quit`, `resume`, `reload`, and `inputs`.)
680
+ Nested `ctx.workflow(...)` calls are displayed as an expanded graph within the top-level run. `/workflow status` and run pickers list only top-level user-launched workflows, not implementation-owned child runs. After a fresh process starts, active and completed graphs retain source stage ids, order, parent edges, lifecycle status, boundary ownership, and exact `{ runId, stageId }` control targets. The `workflow` tool's `stages`, `stage`, `transcript`, `answer`, `pause`, and `resume` actions route a uniquely identified visible child stage to that nested owner, and ambiguous local ids or names are rejected. Run-level `quit` still targets the selected top-level run or all live top-level runs. Completed graph inspection is read-only even when no stage transcript remains. `/workflow attach <root-run> <nested-stage>` remains the explicit user-driven path for retained post-mortem chat and routes to the true child owner without resuming or mutating execution. (`stages`, `stage`, `transcript`, and `answer` are `workflow` tool actions, not `/workflow` slash subcommands; the slash command exposes `connect`, `attach`, `pause`, `list`, `status`, `quit`, `resume`, `reload`, and `inputs`.)
682
681
 
683
682
  Raw stage-chat prompt answer replay is live-memory only. `StageSnapshot.promptAnswerState` reports whether continuation can replay a raw stage-chat answer (`available`), must ask again because the private ledger entry is gone (`unavailable`), or must ask again because multiple matching prompt nodes are ambiguous (`ambiguous`). Raw answers stay in a private `PromptAnswerRecord` ledger, are never serialized to snapshots or persistence, and remain resident in memory until the answer is cleared, the run is removed, or the store is cleared. Durable `ctx.ui` responses are separate DBOS checkpoints: resume returns those cached responses without asking again, and graph-backed UI re-materializes the answered prompt node from metadata. Replay keys include prompt kind, message text, select choices, input/editor initial value, custom prompt identity hash, and hashed author callsite, so changing any of those inputs may intentionally re-ask on continuation. Empty `ctx.ui.select(..., [])` calls throw before creating a prompt node. Arbitrary custom-widget answers cannot be supplied with `workflow answer`; focus the `custom` awaiting-input node in the interactive graph instead.
684
683
 
@@ -689,13 +688,13 @@ Raw stage-chat prompt answer replay is live-memory only. `StageSnapshot.promptAn
689
688
  ```json
690
689
  {
691
690
  "name": "workflow",
692
- "description": "Run named builtin, project, user, or package workflows; custom definitions may import reusable project/package workflows or builtin definitions from @bastani/atomic/workflows/builtin and nest them with ctx.workflow(...), including deeper composition within the configured maxDepth; Requests to do the task 'quickly' or 'inline' mean no workflow creation or launch, including hidden/nested replacements. when workflow execution fits but another shape would better achieve the task, author a custom TypeScript workflow({...}) inline with normal coding tools, reload it, and run it; after successfully creating and reloading a newly authored custom workflow, report the folder containing its generated code as 'Custom workflow created. You can inspect its code at: <workflow-folder-path>'; do this only for newly created custom workflows, never builtin or pre-existing workflows; discover with list/get/inputs/models, list session runs with status (no runId; statusFilter narrows the list), inspect status/stages/stage details, answer pending prompts only while the root workflow is nonterminal, pause/resume/interrupt/quit runs, and reload workflow resources. When steering or communication is useful, use Intercom. Before steering a stage, join its invocation group. Use the Intercom `groups` action to discover it. Workflow invocation groups are named `workflow:<rootRunId>`. Then address the stage as `workflow:<rootRunId>/<segment>[/<segment>...]`; each segment may be a stage name, run id, or glob (`*` matches one segment and `**` any depth). Use `intercom list` inside the invocation group to see live, pending, and possible future targets. Live delivery is immediate; a known stage that has not started is queued and receives the message before its first model turn. Name and pattern sends remain sticky for every future matching stage until the root run terminates. When shared scope or acceptance criteria change, broadcast one authoritative update to `workflow:<rootRunId>/**` (or a narrower path pattern) rather than enumerating stages. A syntactically valid target outside the known set queues with a `notInKnownSet` warning and settles undeliverable at terminal only if never delivered. Use `ask` only for a reply-capable live session. Treat a blocked run as continuable by default unless the user requests inline/no-workflow execution: then safely hold/stop it, reconcile completed work and in-flight side effects, and continue inline without duplication. Otherwise resume resumable blocks, answer pending prompts, steer past the obstacle, or start a follow-up workflow past a terminal block; resolve material ambiguity from user intent and repository evidence without bypassing safety or authorization. For action 'run' and 'resume', budget accepts per-field duration, token, cost, and warning overrides; fields resolve over the workflow declaration and config, and 0 disables a field. Before launching, share an estimated duration without confidence labels. Proceed with inherited budget limits without asking the user to choose a budget before each launch. Pass budget only for a user-specified limit; otherwise omit it and inherit the declaration and config. An estimate is not a budget. For primitive prompt answers, use booleans or the documented confirm labels, exact case-insensitive select labels or 1-based indexes, and text strings for input/editor; an invalid answer remains pending and returns guidance instead of choosing a default. For large stage handoffs, write context to files/artifacts, pass paths via reads, and prompt downstream agents to 'Read the file at <path>...' instead of injecting large previous text. Wrap critical parts of run inputs and steering messages in <keepContext>...</keepContext> so compaction preserves them verbatim in the stages that inherit them; tag role constraints, prohibitions, must-hold criteria, and identifiers, not background or bulk reference material. For transcripts, prefer status/stages/stage to get sessionFile/transcriptPath, quote the exact path without rewriting separators (Windows backslashes are valid), then search it with rg/grep and read small ranges; transcript is path-only by default when sessionFile/transcriptPath exists, explicit tail/limit returns bounded previews, and missing transcript paths fall back to a small preview. Use action 'models' to inspect models in the configured catalog; the result is a configured-auth snapshot showing what's present in the registry with configured authentication, not proof of credentials, entitlements, OAuth freshness, or live provider access. When authoring a workflow that should dynamically select a model, first call workflow({ action: 'models' }) to inspect the configured catalog, then select from the returned provider/id entries considering the isCurrent marker and available thinking levels.",
691
+ "description": "Run named builtin, project, user, or package workflows; custom definitions may import reusable project/package workflows or builtin definitions from @bastani/atomic/workflows/builtin and nest them with ctx.workflow(...), including deeper composition within the configured maxDepth; Requests to do the task 'quickly' or 'inline' mean no workflow creation or launch, including hidden/nested replacements. when workflow execution fits but another shape would better achieve the task, author a custom TypeScript workflow({...}) inline with normal coding tools, reload it, and run it; after successfully creating and reloading a newly authored custom workflow, report the folder containing its generated code as 'Custom workflow created. You can inspect its code at: <workflow-folder-path>'; do this only for newly created custom workflows, never builtin or pre-existing workflows; discover with list/get/inputs/models, list session runs with status (no runId; statusFilter narrows the list), inspect status/stages/stage details, answer pending prompts only while the root workflow is nonterminal, pause/resume/quit runs, and reload workflow resources. When steering or communication is useful, use Intercom. Before steering a stage, join its invocation group. Use the Intercom `groups` action to discover it. Workflow invocation groups are named `workflow:<rootRunId>`. Then address the stage as `workflow:<rootRunId>/<segment>[/<segment>...]`; each segment may be a stage name, run id, or glob (`*` matches one segment and `**` any depth). Use `intercom list` inside the invocation group to see live, pending, and possible future targets. Live delivery is immediate; a known stage that has not started is queued and receives the message before its first model turn. Name and pattern sends remain sticky for every future matching stage until the root run terminates. When shared scope or acceptance criteria change, broadcast one authoritative update to `workflow:<rootRunId>/**` (or a narrower path pattern) rather than enumerating stages. A syntactically valid target outside the known set queues with a `notInKnownSet` warning and settles undeliverable at terminal only if never delivered. Use `ask` only for a reply-capable live session. Treat a blocked run as continuable by default unless the user requests inline/no-workflow execution: then safely hold/stop it, reconcile completed work and in-flight side effects, and continue inline without duplication. Otherwise resume resumable blocks, answer pending prompts, steer past the obstacle, or start a follow-up workflow past a terminal block; resolve material ambiguity from user intent and repository evidence without bypassing safety or authorization. For action 'run' and 'resume', budget accepts per-field duration, token, cost, and warning overrides; fields resolve over the workflow declaration and config, and 0 disables a field. Before launching, share an estimated duration without confidence labels. Proceed with inherited budget limits without asking the user to choose a budget before each launch. Pass budget only for a user-specified limit; otherwise omit it and inherit the declaration and config. An estimate is not a budget. For primitive prompt answers, use booleans or the documented confirm labels, exact case-insensitive select labels or 1-based indexes, and text strings for input/editor; an invalid answer remains pending and returns guidance instead of choosing a default. For large stage handoffs, write context to files/artifacts, pass paths via reads, and prompt downstream agents to 'Read the file at <path>...' instead of injecting large previous text. Wrap critical parts of run inputs and steering messages in <keepContext>...</keepContext> so compaction preserves them verbatim in the stages that inherit them; tag role constraints, prohibitions, must-hold criteria, and identifiers, not background or bulk reference material. For transcripts, prefer status/stages/stage to get sessionFile/transcriptPath, quote the exact path without rewriting separators (Windows backslashes are valid), then search it with rg/grep and read small ranges; transcript is path-only by default when sessionFile/transcriptPath exists, explicit tail/limit returns bounded previews, and missing transcript paths fall back to a small preview. Use action 'models' to inspect models in the configured catalog; the result is a configured-auth snapshot showing what's present in the registry with configured authentication, not proof of credentials, entitlements, OAuth freshness, or live provider access. When authoring a workflow that should dynamically select a model, first call workflow({ action: 'models' }) to inspect the configured catalog, then select from the returned provider/id entries considering the isCurrent marker and available thinking levels.",
693
692
  "parameters": {
694
693
  "workflow": "string (optional) — workflow ID or normalized name",
695
694
  "inputs": "object (optional) — key/value map of workflow inputs",
696
695
  "budget": "optional run-only object: maxDurationMs/maxTokens non-negative integers; maxCost/warnAtPercent non-negative numbers; 0 disables a field",
697
- "action": "'run' | 'list' | 'get' | 'inputs' | 'models' | 'status' | 'stages' | 'stage' | 'transcript' | 'answer' | 'pause' | 'interrupt' | 'quit' | 'resume' | 'reload'",
698
- "runId": "optional full 36-character run id; prefixes are rejected; control actions default to the active run where safe; use '--all' or all:true for pause/interrupt/quit all",
696
+ "action": "'run' | 'list' | 'get' | 'inputs' | 'models' | 'status' | 'stages' | 'stage' | 'transcript' | 'answer' | 'pause' | 'quit' | 'resume' | 'reload'",
697
+ "runId": "optional full 36-character run id; prefixes are rejected; control actions default to the active run where safe; use '--all' or all:true for pause/quit all",
699
698
  "stageId": "optional exact stage id or exact stage name for stage-scoped actions; prefixes and partial names are rejected; cannot be combined with all:true",
700
699
  "statusFilter": "optional filter for stages or the no-runId status run listing: pending/running/awaiting_input/paused/blocked/completed/failed/skipped/cancelled/killed/all; for the status listing, run statuses match directly and awaiting_input selects runs with a pending human prompt",
701
700
  "format": "optional agent-facing output format: text or json",
@@ -707,7 +706,7 @@ Raw stage-chat prompt answer replay is live-memory only. `StageSnapshot.promptAn
707
706
  "message": "optional string payload for answer, or text forwarded by resume",
708
707
  "promptId": "optional pending prompt identifier for answer",
709
708
  "reason": "optional human-readable reload reason",
710
- "all": "optional boolean for pause/interrupt/quit all; cannot be combined with stageId"
709
+ "all": "optional boolean for pause/quit all; cannot be combined with stageId"
711
710
  }
712
711
  }
713
712
  ```
@@ -36,7 +36,7 @@ import {
36
36
  reviewerFailureText,
37
37
  summarizeReviewConvergence,
38
38
  reverify_consolidated_batch
39
- } from "./chunk-zggjyg5z.js";
39
+ } from "./chunk-n8zysf1t.js";
40
40
  import {
41
41
  VERIFICATION_SCALE
42
42
  } from "./chunk-n1910xc4.js";
@@ -38,7 +38,7 @@ import {
38
38
  reviewerFailureText,
39
39
  summarizeReviewConvergence,
40
40
  reverify_consolidated_batch
41
- } from "./chunk-zggjyg5z.js";
41
+ } from "./chunk-n8zysf1t.js";
42
42
  import {
43
43
  fold_usage
44
44
  } from "./chunk-tgt0s5e5.js";
@@ -979,7 +979,7 @@ class WorkflowObservationRuntime {
979
979
  const run = this.runs().find((candidate) => candidate.id === runId);
980
980
  if (!run)
981
981
  return;
982
- if ((action === "quit" || action === "kill" || action === "interrupt") && this.liveRunIds.has(runId))
982
+ if ((action === "quit" || action === "kill" || action === "pause") && this.liveRunIds.has(runId))
983
983
  this.stoppingRunIds.add(runId);
984
984
  if (action === "resume")
985
985
  this.stoppingRunIds.delete(runId);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  goal_default
3
- } from "./chunk-mygmtz6e.js";
4
- import"./chunk-zggjyg5z.js";
3
+ } from "./chunk-9k3ywfgd.js";
4
+ import"./chunk-n8zysf1t.js";
5
5
  import"./chunk-p8jjwfg6.js";
6
6
  import"./chunk-z0d03ktm.js";
7
7
  import"./chunk-n1910xc4.js";
@@ -14,11 +14,11 @@ import {
14
14
  import {
15
15
  generate_and_filter_default
16
16
  } from "./chunk-t6x2d78s.js";
17
- import"./chunk-zggjyg5z.js";
17
+ import"./chunk-n8zysf1t.js";
18
18
  import"./chunk-z0d03ktm.js";
19
19
  import {
20
20
  goal_default
21
- } from "./chunk-mygmtz6e.js";
21
+ } from "./chunk-9k3ywfgd.js";
22
22
  import {
23
23
  open_claude_design_default
24
24
  } from "./chunk-62v3gg9f.js";
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-6w6cvk6b.js";
28
28
  import {
29
29
  ralph_default
30
- } from "./chunk-r9qq7xfj.js";
30
+ } from "./chunk-ahbntmx2.js";
31
31
  import {
32
32
  tournament_default
33
33
  } from "./chunk-hbnwv56f.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ralph_default
3
- } from "./chunk-r9qq7xfj.js";
4
- import"./chunk-zggjyg5z.js";
3
+ } from "./chunk-ahbntmx2.js";
4
+ import"./chunk-n8zysf1t.js";
5
5
  import"./chunk-p8jjwfg6.js";
6
6
  import"./chunk-z0d03ktm.js";
7
7
  import"./chunk-n1910xc4.js";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.19-alpha.3",
3
+ "version": "0.9.19-alpha.4",
4
4
  "private": true,
5
5
  "description": "Atomic extension for multi-stage workflow authoring and execution.",
6
6
  "contributors": [
@@ -61,10 +61,10 @@
61
61
  "LICENSE"
62
62
  ],
63
63
  "scripts": {
64
- "test": "bun run test:unit",
65
- "test:unit": "bun test ../../test/unit",
66
- "test:integration": "bun test ../../test/integration",
67
- "test:all": "bun run test:unit && bun run test:integration",
64
+ "test": "npm --prefix ../.. run test:unit --",
65
+ "test:unit": "npm --prefix ../.. run test:unit --",
66
+ "test:integration": "npm --prefix ../.. run test:integration --",
67
+ "test:all": "npm --prefix ../.. run test:all --",
68
68
  "typecheck": "tsc --noEmit -p ../../tsconfig.json",
69
69
  "lint": "tsc --noEmit -p ../../tsconfig.json"
70
70
  },