@bastani/atomic 0.9.19-alpha.2 → 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.
- package/CHANGELOG.md +42 -0
- package/dist/builtin/intercom/CHANGELOG.md +15 -0
- package/dist/builtin/intercom/broker/broker.ts +8 -0
- package/dist/builtin/intercom/broker/client.ts +18 -0
- package/dist/builtin/intercom/broker/send-handler.ts +9 -0
- package/dist/builtin/intercom/index.bundle.mjs +161 -30
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/types.ts +2 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +18 -0
- package/dist/builtin/subagents/README.md +14 -14
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +14 -14
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +142 -60
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +33 -0
- package/dist/builtin/workflows/README.md +14 -15
- package/dist/builtin/workflows/builtin/{chunk-mygmtz6e.js → chunk-9k3ywfgd.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-r9qq7xfj.js → chunk-ahbntmx2.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-zggjyg5z.js → chunk-n8zysf1t.js} +1 -1
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/package.json +5 -5
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +171 -207
- package/dist/builtin/workflows/src/index.js +33 -6
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -1
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +1 -1
- package/dist/core/agent-session-auto-compaction.js +1 -1
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-compaction.js +1 -1
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +33 -2
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts +1 -1
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +22 -8
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +7 -1
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.d.ts +1 -1
- package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.js +13 -3
- package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
- package/dist/core/agent-session-post-tool-compaction.js +1 -1
- package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +83 -0
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
- package/dist/core/agent-session-queue-pause.js +11 -0
- package/dist/core/agent-session-queue-pause.js.map +1 -1
- package/dist/core/agent-session-tasks.d.ts +5 -0
- package/dist/core/agent-session-tasks.d.ts.map +1 -1
- package/dist/core/agent-session-tasks.js +8 -1
- package/dist/core/agent-session-tasks.js.map +1 -1
- package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
- package/dist/core/agent-session-tool-hooks.js +2 -0
- package/dist/core/agent-session-tool-hooks.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +12 -0
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-transfer.d.ts.map +1 -1
- package/dist/core/agent-session-transfer.js +7 -0
- package/dist/core/agent-session-transfer.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +2 -0
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js +2 -0
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +4 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +22 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +6 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/loader-api.d.ts.map +1 -1
- package/dist/core/extensions/loader-api.js +3 -0
- package/dist/core/extensions/loader-api.js.map +1 -1
- package/dist/core/extensions/loader-host-modules.d.ts +1 -1
- package/dist/core/extensions/loader-host-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-host-modules.js +2 -1
- package/dist/core/extensions/loader-host-modules.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +4 -1
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/runner-context.d.ts +1 -1
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +9 -3
- package/dist/core/extensions/runner-context.js.map +1 -1
- package/dist/core/extensions/runner.js +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/workflow-events.d.ts +1 -1
- package/dist/core/extensions/workflow-events.d.ts.map +1 -1
- package/dist/core/extensions/workflow-events.js.map +1 -1
- package/dist/core/retry-policy.d.ts +1 -0
- package/dist/core/retry-policy.d.ts.map +1 -1
- package/dist/core/retry-policy.js +2 -1
- package/dist/core/retry-policy.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +1 -1
- package/dist/core/sdk-exports.d.ts.map +1 -1
- package/dist/core/sdk-exports.js +1 -1
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +6 -3
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +25 -8
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-types.d.ts +6 -0
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +4 -5
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tasks/agent-adapter.d.ts +14 -2
- package/dist/core/tasks/agent-adapter.d.ts.map +1 -1
- package/dist/core/tasks/agent-adapter.js +45 -4
- package/dist/core/tasks/agent-adapter.js.map +1 -1
- package/dist/core/tasks/completion.d.ts.map +1 -1
- package/dist/core/tasks/completion.js +5 -1
- package/dist/core/tasks/completion.js.map +1 -1
- package/dist/core/tasks/pause.d.ts +4 -0
- package/dist/core/tasks/pause.d.ts.map +1 -0
- package/dist/core/tasks/pause.js +49 -0
- package/dist/core/tasks/pause.js.map +1 -0
- package/dist/core/tasks/supervisor.d.ts +3 -1
- package/dist/core/tasks/supervisor.d.ts.map +1 -1
- package/dist/core/tasks/supervisor.js +48 -22
- package/dist/core/tasks/supervisor.js.map +1 -1
- package/dist/core/tools/bash-pty-native.d.ts +16 -2
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
- package/dist/core/tools/bash-pty-native.js +82 -0
- package/dist/core/tools/bash-pty-native.js.map +1 -1
- package/dist/core/tools/bash.d.ts +15 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +49 -4
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/index.d.ts +4 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +12 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/kill.d.ts +17 -0
- package/dist/core/tools/kill.d.ts.map +1 -0
- package/dist/core/tools/kill.js +49 -0
- package/dist/core/tools/kill.js.map +1 -0
- package/dist/core/tools/powershell.d.ts +84 -28
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js +11 -3
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/resource-selectors.d.ts +1 -1
- package/dist/core/tools/resource-selectors.d.ts.map +1 -1
- package/dist/core/tools/resource-selectors.js +7 -4
- package/dist/core/tools/resource-selectors.js.map +1 -1
- package/dist/core/workflow-stage-admission.d.ts +14 -0
- package/dist/core/workflow-stage-admission.d.ts.map +1 -1
- package/dist/core/workflow-stage-admission.js +63 -3
- package/dist/core/workflow-stage-admission.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +3 -2
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/task-row.d.ts.map +1 -1
- package/dist/modes/interactive/components/task-row.js +8 -1
- package/dist/modes/interactive/components/task-row.js.map +1 -1
- package/docs/background-tasks.md +31 -2
- package/docs/compaction.md +20 -0
- package/docs/computer-use.md +390 -0
- package/docs/development.md +23 -74
- package/docs/docs.json +1 -0
- package/docs/extensions.md +15 -1
- package/docs/herdr.md +26 -77
- package/docs/index.md +1 -0
- package/docs/intercom.md +14 -2
- package/docs/models/evals.md +2 -0
- package/docs/models/model-selection.md +10 -7
- package/docs/quickstart.md +1 -1
- package/docs/sdk.md +11 -1
- package/docs/settings.md +24 -0
- package/docs/subagents.md +10 -6
- package/docs/tmux.md +2 -0
- package/docs/tools.md +11 -1
- package/docs/usage.md +1 -1
- package/docs/workflows/api-reference.md +5 -4
- package/docs/workflows/authoring.md +3 -3
- package/docs/workflows/operations.md +44 -33
- package/docs/workflows/reliable-design.md +3 -3
- package/docs/workflows/verification.md +99 -40
- package/docs/workflows.md +4 -2
- package/npm-shrinkwrap.json +59 -59
- package/package.json +3 -3
package/docs/settings.md
CHANGED
|
@@ -188,6 +188,7 @@ On a genuine first run, Atomic previews available themes and asks whether to opt
|
|
|
188
188
|
| `compaction.compression_ratio` | number | `0.5` | Fraction of compactable transcript **lines to keep** (`0 < value < 1`) |
|
|
189
189
|
| `compaction.preserve_recent` | number | `2` | Exact number of newest context-visible messages kept outside the compactable region; `0` keeps none |
|
|
190
190
|
| `compaction.query` | string | last user message | Optional relevance focus for selecting older lines to retain |
|
|
191
|
+
| `compaction.modelOverrides` | object | `{}` | Exact `"provider/modelId"` keys with optional `reserveTokens` and `preserve_recent` overrides |
|
|
191
192
|
|
|
192
193
|
```json
|
|
193
194
|
{
|
|
@@ -203,6 +204,25 @@ On a genuine first run, Atomic previews available themes and asks whether to opt
|
|
|
203
204
|
|
|
204
205
|
The model emits numbered line ranges only; Atomic reconstructs retained text mechanically. `preserve_recent` is enforced client-side and is not a provider parameter. Atomic does not widen this exact message count to a user-turn boundary or force a final logical turn to remain outside compaction.
|
|
205
206
|
|
|
207
|
+
Per-model budgets use exact, case-sensitive provider/model IDs (including any slashes in the model ID), not patterns or reasoning suffixes:
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"compaction": {
|
|
212
|
+
"reserveTokens": 16384,
|
|
213
|
+
"preserve_recent": 2,
|
|
214
|
+
"modelOverrides": {
|
|
215
|
+
"anthropic/claude-sonnet-4-5": { "reserveTokens": 32768, "preserve_recent": 4 },
|
|
216
|
+
"openai/gpt-5": { "preserve_recent": 0 }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Each field resolves independently: the active model's override, then the ordinary compaction setting, then the built-in default. Global and trusted-project settings merge overrides per model and per field. Model switches take effect on the next compaction check or manual call; borrowing a fallback planner does not change the selected budgets. Explicit manual `preserve_recent` parameters still take precedence.
|
|
223
|
+
|
|
224
|
+
Both fields must be non-negative safe integers, including ordinary settings. Invalid ordinary values are reported even if a model override exists; malformed matching entries and invalid override values are reported when that model is used. `enabled`, `compression_ratio`, and `query` remain ordinary settings, not per-model overrides. Unlike upstream pi's token-based recent-history budget, Atomic uses the exact-message `preserve_recent` setting, not `keepRecentTokens`, and retains its verbatim line compactor.
|
|
225
|
+
|
|
206
226
|
### Branch Summary
|
|
207
227
|
|
|
208
228
|
| Setting | Type | Default | Description |
|
|
@@ -223,10 +243,13 @@ The model emits numbered line ranges only; Atomic reconstructs retained text mec
|
|
|
223
243
|
| `retry.enabled` | boolean | `true` | Enable automatic agent-level retry on transient errors |
|
|
224
244
|
| `retry.maxRetries` | number | `3` | Maximum agent-level retry attempts |
|
|
225
245
|
| `retry.baseDelayMs` | number | `2000` | Base delay for agent-level exponential backoff (2s, 4s, 8s) |
|
|
246
|
+
| `retry.maxAgentDelayMs` | number | `60000` | Maximum agent-level backoff delay (60s); `0` retries immediately |
|
|
226
247
|
| `retry.provider.timeoutMs` | number | SDK default | Provider/SDK request timeout in milliseconds |
|
|
227
248
|
| `retry.provider.maxRetries` | number | `0` | Provider/SDK retry attempts. Leave unset/`0` to let Atomic's agent-level retry handle transient failures |
|
|
228
249
|
| `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay before failing (60s) |
|
|
229
250
|
|
|
251
|
+
Agent-level retries use exponential backoff capped by `retry.maxAgentDelayMs`, including the shared main-chat and workflow retry policy and summary calls. This is independent of provider retry limits. Legacy `retry.maxDelayMs` still migrates to `retry.provider.maxRetryDelayMs`, not the agent cap.
|
|
252
|
+
|
|
230
253
|
When a provider requests a retry delay longer than `retry.provider.maxRetryDelayMs` (e.g., Google's "quota will reset after 5h"), the request fails immediately with an informative error instead of waiting silently. Set to `0` to disable the cap.
|
|
231
254
|
|
|
232
255
|
`retry.provider.maxRetries` follows upstream Pi's behavior and defaults to `0` SDK/provider retries. Atomic still performs agent-level retries via `retry.maxRetries`; set `retry.provider.maxRetries` explicitly only when you want the underlying provider SDK to retry before Atomic observes the failure.
|
|
@@ -237,6 +260,7 @@ When a provider requests a retry delay longer than `retry.provider.maxRetryDelay
|
|
|
237
260
|
"enabled": true,
|
|
238
261
|
"maxRetries": 3,
|
|
239
262
|
"baseDelayMs": 2000,
|
|
263
|
+
"maxAgentDelayMs": 60000,
|
|
240
264
|
"provider": {
|
|
241
265
|
"timeoutMs": 3600000,
|
|
242
266
|
"maxRetries": 0,
|
package/docs/subagents.md
CHANGED
|
@@ -71,6 +71,8 @@ Runtime-created session contexts bind single launches to their actual session or
|
|
|
71
71
|
|
|
72
72
|
The agent may choose foreground-first or background observation for each authorized call without asking the user merely to select a mode. When a foreground observation expires, the returned task is still running. Wait for terminal completion before using its result in dependent work. See [Choosing how long to wait](/background-tasks#choose-how-long-to-wait) for shell and subagent defaults and the separate execution-timeout behavior.
|
|
73
73
|
|
|
74
|
+
User steering or an incoming Intercom ask/send admitted to the waiting parent releases its active subagent observations, including both foreground launches and `action: "wait"`. This applies to main chat and live workflow-stage chat. The parent can handle the queued message and reply without cancelling the child, closing its owner, or interrupting another owner's waits. User input yields with reason `input-needed`; Intercom coordination yields with reason `intercom-coordination`. The original task can be observed again after handling the message.
|
|
75
|
+
|
|
74
76
|
An Intercom peer-message yield keeps the original execution alive. Terminal completion is recorded separately and admitted as a readable `task-completion` custom message. Background completions show a visible notification in main or owning workflow-stage chat, without requiring the parent model to reply. Its text names the available agent/task, outcome, error, and response excerpt; the receipt remains in structured details. Failed delivery retains the same persisted completion identity for retry. Parallel launches admit accepted slots independently of foreground/background observation and keep execution queued under the configured concurrency limit. Intercom yields do not skip queued siblings. Existing unbound SDK callers retain their legacy result fields.
|
|
75
77
|
|
|
76
78
|
Durable `ctx.tool` callbacks wait for tasks admitted inside their callback before checkpointing, even when the launching observation yielded. Session lifetime closure cancels session-owned work; stage generation closure, not pane detach or fallback session replacement, owns stage tasks.
|
|
@@ -81,7 +83,9 @@ In a parallel run, `intercom.ask`, `contact_supervisor({ reason: "need_decision"
|
|
|
81
83
|
|
|
82
84
|
`intercom.send` and `contact_supervisor` progress updates return after delivery without waiting for a reply. An exact-child Intercom handshake can release the parallel call's foreground observations so the supervisor can handle the message. This is not execution cancellation: active siblings keep running, queued siblings start once capacity is available, and worktrees stay owned until their children exit. Background calls use the same communication path without needing to release an observation.
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
To update a working child, use ordinary Intercom `send` or `ask` with its exact connected name or full session ID from `intercom list`. Foreground and background children treat it as a priority interrupt: the child's current model call or cancellable tool is cancelled and the message is handled next in the same child execution, without relaunching its task or repeating the original prompt. Tools that ignore cancellation finish first, and completed side effects are kept. Multiple updates stay in arrival order. A reply to an incoming ask uses ordinary `intercom.reply`; this does not change the single-child parent-targeted handoff described below.
|
|
87
|
+
|
|
88
|
+
Targeted `kill` stops only the selected child and cannot be resumed. Explicit batch cancellation and session/workflow-stage lifetime closure still stop the intended owned children, including pending reply waits. A late or duplicate reply cannot revive a terminal child. Ordinary Intercom group restrictions and the authorized cross-group `contact_supervisor` route are unchanged.
|
|
85
89
|
|
|
86
90
|
Completed, failed, interrupted, and cancelled noninteractive children cannot answer new Intercom asks, even when their retained registration still says `idle`. Such asks fail immediately with an explicit terminal-child error; an admitted ask also fails if its child terminates before replying. Launch a fresh child with the required context for follow-up work. This does not restrict live interactive idle sessions or workflow-stage post-mortem conversations, and does not change `send` delivery semantics.
|
|
87
91
|
|
|
@@ -161,16 +165,16 @@ Tool examples:
|
|
|
161
165
|
subagent({ agent: "codebase-analyzer", task: "Trace the auth flow with file references.", wait: { kind: "foreground", budgetMs: 30000 } })
|
|
162
166
|
```
|
|
163
167
|
|
|
164
|
-
Use `
|
|
168
|
+
Use `subagent({ action: "kill", id: "<task-or-run-id>" })` to terminally stop a live child. Killed children cannot be resumed; launch a fresh child with an explicit context handoff for follow-up work. The former `interrupt` action is no longer accepted. Replace subagent calls using `action: "interrupt"` with `action: "kill"`. Workflow controls use `pause`; host cancellation APIs are unchanged.
|
|
165
169
|
|
|
166
170
|
If the parent turn is cancelled while a foreground in-process child is still running, the child stops through the existing abort/interrupted state. That outcome is terminal and non-retryable: it does not count as a failure, never looks completed, and preserves any fallback metadata already recorded before abort. Parent receipts, Intercom summaries, and progress present the child as cancelled; persisted metadata records `interrupted` with abort cause rather than a new public status. Atomic recovers bounded, clearly labelled partial findings in this order:
|
|
167
171
|
1. A modified run-scoped `progress.md`
|
|
168
172
|
2. The last assistant message that contains actual text
|
|
169
173
|
3. A cancellation notice with session, progress, and output artifact references
|
|
170
174
|
|
|
171
|
-
A thinking-only aborted final message is skipped so earlier text can still be recovered. Session, Progress, and Output paths are cited only when those files exist when the cancelled envelope or receipt is built. A parallel set shares one `progress.md`; recovery attributes that file to the first progress-enabled child so siblings are not each given a copy of the same findings. A mixed parallel set that contains both a
|
|
175
|
+
A thinking-only aborted final message is skipped so earlier text can still be recovered. Session, Progress, and Output paths are cited only when those files exist when the cancelled envelope or receipt is built. A parallel set shares one `progress.md`; recovery attributes that file to the first progress-enabled child so siblings are not each given a copy of the same findings. A mixed parallel set that contains both a killed child and a parent cancellation preserves the cancellation summary.
|
|
172
176
|
|
|
173
|
-
For owner-bound task IDs, status and
|
|
177
|
+
For owner-bound task IDs, status and kill resolve the same task owner as launch and wait. Legacy run IDs use the live registry and status watch; `list` and `get` remain read-only definition management actions. Neither identifier revives a completed execution. Owner-bound completions use persisted delivery identities; unbound callers retain their legacy result and artifact behavior.
|
|
174
178
|
|
|
175
179
|
In-process status results use compact rows such as `∀ debugger_1 · Running`, matching the other subagent tool cards. The collapsed card shows up to six children and an omitted count; expanding the tool result shows every child, full paths, parent, task, depth, loaded/cold residency, and any recorded termination cause or session file. Multiple runs have separate labels. The configured tool-expansion shortcut appears below the compact rows. This is a status snapshot, not an animated live monitor; inspection does not start or resume work. Model-facing status text and canonical identifiers remain unchanged.
|
|
176
180
|
|
|
@@ -217,7 +221,7 @@ Observation yields do not release these worktrees. Cancelling a queued child bef
|
|
|
217
221
|
|
|
218
222
|
Fresh child sessions use normal Atomic package discovery when an agent omits `extensions`, so bundled lightweight MCP and web-access wrappers are available just as they are in the parent. An explicit `extensions` field, including an empty list, switches optional extensions to allowlist mode and excludes unlisted optional builtins; mandatory bundled Intercom remains loaded. The child does not inherit the parent's normal optional discovery set.
|
|
219
223
|
|
|
220
|
-
Top-level parallel calls support up to 50 subagents after expanding each task's optional `count`. The extension's `parallel.maxTasks` setting defaults to 50 and can enforce a lower task limit; `parallel.concurrency` independently controls how many of those children run at once,
|
|
224
|
+
Top-level parallel calls support up to 50 subagents after expanding each task's optional `count`. The extension's `parallel.maxTasks` setting defaults to 50 and can enforce a lower task limit; `parallel.concurrency` defaults to 3 and independently controls how many of those children run at once. Explicit configuration overrides that default, and per-call `concurrency` takes precedence over configuration. The separate Rust turn limiter still admits at most four running turns per parent.
|
|
221
225
|
|
|
222
226
|
When one assistant response emits several sibling execution-mode `subagent` tool calls, Atomic collects that synchronous burst before starting a child and runs it as one indexed parallel set. Each original tool call still receives one result containing only the children it requested, and its live result, progress, control, and artifact updates are projected to that same route without sibling data. The TUI redraws the shared run as one aggregate parallel widget rather than retaining one widget per original call. A single call keeps its original SINGLE or PARALLEL mode, calls awaited in sequence remain separate runs, and management actions bypass collection. An execution call that arrives after a child has started still receives the existing in-progress rejection. Prefer one explicit `{ tasks: [...] }` call when planning parallel work; burst collection handles sibling calls emitted by a model.
|
|
223
227
|
|
|
@@ -246,7 +250,7 @@ Child-safety boundaries are enforced by typed admission policy and the bundled s
|
|
|
246
250
|
- In-process child sessions load bundled extensions through normal discovery. The `subagent` tool may therefore be registered when the child's active tool selection permits it, including the default no-allowlist case; an explicit allowlist may omit it. Tool presence does not grant fanout. The bundled subagents skill remains parent-only and is stripped from child prompts, including fanout-authorized children.
|
|
247
251
|
- Child context is filtered to remove parent orchestration artifacts, old control/status messages, and prior parent `subagent` tool calls/results.
|
|
248
252
|
- Children are instructed that they are not the parent orchestrator and must complete their assigned task directly rather than delegating.
|
|
249
|
-
- Delegation is exactly one level deep and is not configurable. A session admitted as a subagent child is refused every launch and `
|
|
253
|
+
- Delegation is exactly one level deep and is not configurable. A session admitted as a subagent child is refused every launch and `kill`; only `list`, `get`, and `status` stay available. A management-restricted child is also refused `create`, `update`, and `delete`.
|
|
250
254
|
- The rule is enforced twice: the subagent executor refuses a child before any run starts, and the Rust admission door refuses a child deeper than the single permitted level. Admitted depth is typed admission state, never inherited from process environment state.
|
|
251
255
|
|
|
252
256
|
This keeps the parent session responsible for orchestration.
|
package/docs/tmux.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Atomic works inside tmux, but tmux strips modifier information from certain keys by default. Without configuration, `SHIFT+Enter` and `CTRL+Enter` are usually indistinguishable from plain `Enter`.
|
|
4
4
|
|
|
5
|
+
For terminal automation, prefer Herdr when eligible, with tmux or native Windows psmux as fallbacks. See [Computer use](/computer-use#terminal-automation-with-herdr) for tool selection and safe session control. This page covers Atomic's keyboard setup inside tmux.
|
|
6
|
+
|
|
5
7
|
## Recommended Configuration
|
|
6
8
|
|
|
7
9
|
Add to `~/.tmux.conf`:
|
package/docs/tools.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Built-in tools
|
|
2
2
|
|
|
3
|
-
Atomic enables these coding tools in normal sessions by default: `read`, `write`, `edit`, `bash`, `find`, and `search`.
|
|
3
|
+
Atomic enables these coding tools in normal sessions by default: `read`, `write`, `edit`, `bash`, `kill`, `find`, and `search`.
|
|
4
4
|
|
|
5
5
|
## Hashline editing anchors
|
|
6
6
|
|
|
@@ -32,12 +32,22 @@ When explicitly enabled in settings, built-in bash interceptor rules block commo
|
|
|
32
32
|
|
|
33
33
|
Shell internal-URL expansion is intentionally conservative: commands containing a resolved URL must use only plain unquoted words, spaces/tabs, and basic `;`, `|`, or `&` operators. For example, `printf %s local://notes.txt` is supported and the resolved path is shell-quoted automatically, including paths containing spaces or shell metacharacters. Quotes anywhere in such a command, substitutions, escapes, newlines, redirections and heredocs are rejected before execution; use a filesystem path instead for those forms. Commands without resolved internal URLs retain normal shell syntax. URL expansion in structured `cwd` and `env` values is unchanged.
|
|
34
34
|
|
|
35
|
+
The `powershell` tool uses PowerShell single-quoted literals for resolved paths, doubling both ASCII apostrophes and PowerShell's smart single-quote delimiters (U+2018–U+201B). Bash keeps POSIX quoting, including when Bash runs on Windows. SDK adapters using `createBashToolDefinition` with custom PowerShell operations can set `shellDialect: "powershell"` for generated path literals; this option does not select the executable or rewrite deliberate shell code.
|
|
36
|
+
|
|
37
|
+
Configured command prefixes and SDK `spawnHook` rewrites remain executable shell syntax, not a sandbox. Balanced setup commands such as quoted exports remain supported. A prefix that leaves a quote, substitution, or heredoc open across the following command can invalidate the generated path quoting; automatic URL expansion does not validate that composed shell context. Do not combine URL expansion with such wrappers. Use structured `cwd` and `env` for path data instead.
|
|
38
|
+
|
|
35
39
|
```json
|
|
36
40
|
{
|
|
37
41
|
"bashInterceptor": { "enabled": true }
|
|
38
42
|
}
|
|
39
43
|
```
|
|
40
44
|
|
|
45
|
+
## `kill`
|
|
46
|
+
|
|
47
|
+
`kill({ id: taskId })` stops an owned background shell task launched by `bash` or `powershell`, including a command that automatically yielded. Pass its returned task ID verbatim, not a PID. The tool is owner-scoped in main and workflow-stage chat and does not cancel subagents or another owner's work.
|
|
48
|
+
|
|
49
|
+
The result reports the cancellation decision and current execution and cleanup states. A request is not confirmation of termination. Repeated requests preserve the original cancellation decision; already-completed work retains its outcome. Cleanup failures are reported explicitly. See [Background tasks](/background-tasks#stop-a-shell-task-from-a-tool-call) for states, retained output, and `/tasks` controls.
|
|
50
|
+
|
|
41
51
|
## `find` and `search`
|
|
42
52
|
|
|
43
53
|
`find` finds filesystem paths by glob; use `search` when you need content matches instead of path matches. `find.paths` is required and accepts file, directory (including a filesystem root), internal URL, or glob paths; copied quoted paths are normalized, exact filesystem paths with spaces/commas/semicolons are preserved before delimiter expansion, comma/semicolon-joined paths are split when at least one part resolves, whitespace-joined paths are split only when every part resolves, hidden files are included by default, `.gitignore` is respected by default (including nested `.gitignore` files outside a Git checkout), broad scans keep `node_modules`/`.git` pruned even with `gitignore:false` unless `node_modules` is explicitly present in the requested path or glob, results are capped at 200 by default, and timeout defaults to 5 seconds. Local `find` prefers the bundled Rust native `glob` implementation derived from oh-my-pi, falling back to the packaged `fd` helper only when native bindings are unavailable. Results include `scopePath`, `fileCount`, `files`, truncation/missing-path metadata, and streamed `onUpdate` snapshots during long scans.
|
package/docs/usage.md
CHANGED
|
@@ -51,7 +51,7 @@ Type `/` in the editor to open command completion. Extensions can register custo
|
|
|
51
51
|
| `/model` | Switch models and automatically save the startup default |
|
|
52
52
|
| `/thinking` | Switch thinking level and automatically save the startup default |
|
|
53
53
|
| `/scoped-models` | Enable/disable models for CTRL+P cycling |
|
|
54
|
-
| `/workflow` | List/run workflows; manage runs (connect/inspect/pause/
|
|
54
|
+
| `/workflow` | List/run workflows; manage runs (connect/inspect/pause/quit/resume); reload workflow resources |
|
|
55
55
|
| `/settings` | Theme, message delivery, transport, and other preferences |
|
|
56
56
|
| `/resume` | Pick from previous sessions |
|
|
57
57
|
| `/new` | Start a new session |
|
|
@@ -405,7 +405,7 @@ ctx.tool<TValue extends WorkflowSerializableValue>(
|
|
|
405
405
|
|
|
406
406
|
Runs arbitrary TypeScript code as a tracked, non-attachable durable workflow graph node and caches its serializable result by call order plus the content hash of `name` and `args`. The node is created before `fn` runs and may appear before, between, after, or without model stages. A completed call replays without rerunning `fn`, so use this primitive for workflow-owned durable side effects; keep pure computation as ordinary TypeScript.
|
|
407
407
|
|
|
408
|
-
**Cancellation and deadlines.** Every callback receives a `WorkflowToolContext` whose `signal` aborts when the run is cancelled, when the run is gracefully quit, or when this single node is aborted with `workflow({ action: "quit"|"
|
|
408
|
+
**Cancellation and deadlines.** Every callback receives a `WorkflowToolContext` whose `signal` aborts when the run is cancelled, when the run is gracefully quit, or when this single node is aborted with `workflow({ action: "quit"|"pause", runId, stageId: "<tool node id or name>" })`. Forward it to `fetch`, a child process, or any client that accepts an `AbortSignal` so a stuck call can be stopped:
|
|
409
409
|
|
|
410
410
|
```ts
|
|
411
411
|
await ctx.tool(
|
|
@@ -571,7 +571,7 @@ readonly excludedTools?: readonly string[];
|
|
|
571
571
|
|
|
572
572
|
`tools` is an allowlist across built-in and bundled extension tools. `excludedTools` and `noTools: "all"` still win for every tool except mandatory ordinary `intercom`, which remains registered and active.
|
|
573
573
|
|
|
574
|
-
The bundled `subagent` tool is available by default on the same terms as main chat. A workflow stage is a top-level session, so it may delegate once; the children it launches may not delegate or control another child. Delegation is exactly one level deep and nothing configures it
|
|
574
|
+
The bundled `subagent` tool is available by default on the same terms as main chat. A workflow stage is a top-level session, so it may delegate once; the children it launches may not delegate or control another child. Delegation is exactly one level deep and nothing configures it: there is no config option, agent frontmatter field, or tool parameter for the level. The in-process admission door carries each child's issued depth in its typed child policy, the executor refuses any launch or `kill` from a session that was itself admitted as a child, and the Rust `SubagentControl` admission door refuses a child deeper than the single permitted level. That depth is never carried through process environment. Bundled subagent definitions from `@bastani/subagents` are available to that tool. Explicitly list tools such as `subagent`, `web_search`, `fetch_content`, or `intercom` when using an allowlist; in-process child sessions load the bundled resources while suppressing the workflow extension lifecycle.
|
|
575
575
|
|
|
576
576
|
Workflow stages use the same upstream-compatible `bash` tool as normal Atomic sessions. Enabled commands run through the configured shell with the stage process permissions. There is no command-text allow/deny option: expose or hide shell access with these tool fields, prefer narrow custom tools for repeatable operations, and use a container, VM, or other sandbox for stronger isolation.
|
|
577
577
|
|
|
@@ -736,7 +736,7 @@ readonly concurrency?: number;
|
|
|
736
736
|
readonly failFast?: boolean;
|
|
737
737
|
```
|
|
738
738
|
|
|
739
|
-
`WorkflowParallelOptions` uses `concurrency` to bound active tasks in an authored `ctx.parallel(...)`. When omitted, the runtime uses the workflow's `defaultConcurrency` setting, which defaults to `
|
|
739
|
+
`WorkflowParallelOptions` uses `concurrency` to bound active tasks in an authored `ctx.parallel(...)`. When omitted, the runtime uses the workflow's `defaultConcurrency` setting, which defaults to `3`; explicit configuration and per-call concurrency remain honored. Parallel execution is fail-fast unless `failFast` is explicitly `false`.
|
|
740
740
|
|
|
741
741
|
### Stage prompt options (`StagePromptOptions`)
|
|
742
742
|
|
|
@@ -955,6 +955,7 @@ interface WorkflowTaskResult extends WorkflowTaskContext {
|
|
|
955
955
|
readonly sessionFile?: string;
|
|
956
956
|
readonly artifacts?: readonly WorkflowArtifact[];
|
|
957
957
|
readonly model?: string;
|
|
958
|
+
readonly thinkingLevel?: string;
|
|
958
959
|
readonly attemptedModels?: readonly string[];
|
|
959
960
|
readonly modelAttempts?: readonly WorkflowModelAttempt[];
|
|
960
961
|
readonly warnings?: readonly string[];
|
|
@@ -988,7 +989,7 @@ When a stage explicitly configures `model` or `fallbackModels`, each recorded at
|
|
|
988
989
|
```typescript
|
|
989
990
|
interface WorkflowDetails extends WorkflowSerializableObject {
|
|
990
991
|
readonly mode: "named" | "single" | "parallel" | "chain" | "inspection" | "control";
|
|
991
|
-
readonly action?: "list" | "get" | "inputs" | "run" | "status" | "
|
|
992
|
+
readonly action?: "list" | "get" | "inputs" | "run" | "status" | "pause" | "resume";
|
|
992
993
|
readonly runId?: string;
|
|
993
994
|
readonly status: "accepted" | "running" | WorkflowExitStatus | "failed" | "killed" | "noop";
|
|
994
995
|
readonly context?: "fresh" | "fork";
|
|
@@ -409,7 +409,7 @@ The two streaming modes have distinct, deterministic timing:
|
|
|
409
409
|
- **`steer`** is delivered at the next steering boundary: after the current assistant response has finished executing its whole tool batch, and before the next model request. It is not injected between two tool calls emitted by the same assistant response.
|
|
410
410
|
- **`followUp`** is delivered only when the agent would otherwise stop — no further tool-driven turns and no steering messages left.
|
|
411
411
|
|
|
412
|
-
Each queue is FIFO in admission order. There is no global FIFO *across* the two queues: steering keeps its semantic priority even when a follow-up was submitted earlier. A controlled pause
|
|
412
|
+
Each queue is FIFO in admission order. There is no global FIFO *across* the two queues: steering keeps its semantic priority even when a follow-up was submitted earlier. A controlled pause hold delays eligibility but preserves both the queue class and the order within it. An abort, kill, or fatal provider failure ends the turn without consuming what is still queued.
|
|
413
413
|
|
|
414
414
|
A message you type into an attached stage chat and submit with Enter defaults to `steer`, matching normal (non-workflow) session steering, so a mid-run correction lands at the next steering boundary rather than at the end of the turn. Ctrl+F queues a follow-up instead. This is a property of the interactive surface, not of the API: an authored `stage.sendUserMessage()` call that names no `deliverAs` still defaults to follow-up while the stage is streaming.
|
|
415
415
|
|
|
@@ -474,7 +474,7 @@ export default workflow({
|
|
|
474
474
|
|
|
475
475
|
`ctx.exit()` accepts `status: "completed" | "skipped" | "cancelled" | "blocked" | "failed"`; `status` defaults to `"completed"`. Choose `completed` when the objective was met and declared outputs are complete and trustworthy; `skipped` when a precondition made the run a valid no-op; `cancelled` when the work is no longer wanted, which is a decision rather than a defect; `blocked` when valid progress needs a changed condition or a later decision; and `failed` when required work was attempted and definitively could not complete. A bounded reviewer or repair loop that does not converge is `blocked`, not `failed`.
|
|
476
476
|
|
|
477
|
-
`reason` from a valid author exit is persisted and shown in status surfaces and lifecycle notices, including the default `/workflow status` list and `/workflow status <runId>` detail, so do not put secrets in it. An exit rejected during validation is finalized as an ordinary failed run rather than an accepted author exit. `outputs` may contain a partial subset of declared outputs; provided keys still must be declared in the workflow's `outputs` object, match their TypeBox schema, and be JSON-serializable. `failed` exits default to `resumable: false`; set `resumable: true` only when a later durable retry is intended. `resumable` is valid only with `status: "failed"`; supplying it for another status records a non-resumable authoring failure. A durable retry keeps the failed handle in the resume catalog and re-dispatches the workflow with completed checkpoints replayed. The low-level `resumeRun()` helper only inspects terminal runs; it reports the durable retry path instead of silently claiming that it resumed. The other exit statuses keep their existing non-resumable author-exit behavior. Public `pause
|
|
477
|
+
`reason` from a valid author exit is persisted and shown in status surfaces and lifecycle notices, including the default `/workflow status` list and `/workflow status <runId>` detail, so do not put secrets in it. An exit rejected during validation is finalized as an ordinary failed run rather than an accepted author exit. `outputs` may contain a partial subset of declared outputs; provided keys still must be declared in the workflow's `outputs` object, match their TypeBox schema, and be JSON-serializable. `failed` exits default to `resumable: false`; set `resumable: true` only when a later durable retry is intended. `resumable` is valid only with `status: "failed"`; supplying it for another status records a non-resumable authoring failure. A durable retry keeps the failed handle in the resume catalog and re-dispatches the workflow with completed checkpoints replayed. The low-level `resumeRun()` helper only inspects terminal runs; it reports the durable retry path instead of silently claiming that it resumed. The other exit statuses keep their existing non-resumable author-exit behavior. Public `pause` and `quit`, plus internal destructive cancellation, keep their distinct behavior.
|
|
478
478
|
|
|
479
479
|
An author-initiated failed exit returns to a parent as `{ exited: true, status: "failed" }` with its reason and partial outputs; it does not throw. An unintentional child failure still throws, so check `child.exited === true` before reading required child outputs and use the discriminator to branch. The lifecycle terminal notice uses the same steer/trigger-turn delivery path and references partial outputs so the launching agent does not need a separate status call.
|
|
480
480
|
|
|
@@ -631,7 +631,7 @@ export default workflow({
|
|
|
631
631
|
|
|
632
632
|
Passing a definition directly to `ctx.workflow(...)` uses the child definition's normalized name for replay metadata and the default boundary label.
|
|
633
633
|
|
|
634
|
-
`ctx.workflow(workflowDefinition)` starts a nested workflow behind a parent boundary stage named `workflow:<workflow-name>` by default. User-facing status and graph views flatten a valid child graph into the parent run recursively, so composition behaves like inlining the child workflow code: child stages, HIL prompt nodes, and deeper imported workflows appear in one expanded graph. When Atomic hides a valid import boundary, every boundary parent connects to every child root, and every child terminal connects to each downstream dependent of the boundary. Every visible child node keeps a distinct virtual graph ID and its exact `{ runId, stageId }` control target, even when sibling or repeated child workflows reuse local stage IDs or names. Attach, send, pause,
|
|
634
|
+
`ctx.workflow(workflowDefinition)` starts a nested workflow behind a parent boundary stage named `workflow:<workflow-name>` by default. User-facing status and graph views flatten a valid child graph into the parent run recursively, so composition behaves like inlining the child workflow code: child stages, HIL prompt nodes, and deeper imported workflows appear in one expanded graph. When Atomic hides a valid import boundary, every boundary parent connects to every child root, and every child terminal connects to each downstream dependent of the boundary. Every visible child node keeps a distinct virtual graph ID and its exact `{ runId, stageId }` control target, even when sibling or repeated child workflows reuse local stage IDs or names. Attach, send, pause, resume, stage selection, and post-mortem chat therefore route to the nested run and stage that actually own the node. Implementation-owned child runs are not shown as separate top-level `/workflow status` entries. The returned child result has:
|
|
635
635
|
|
|
636
636
|
| Field | Meaning |
|
|
637
637
|
|---|---|
|