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

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 (164) hide show
  1. package/CHANGELOG.md +35 -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 +18 -0
  7. package/dist/builtin/subagents/README.md +15 -15
  8. package/dist/builtin/subagents/agents/debugger.md +2 -2
  9. package/dist/builtin/subagents/package.json +1 -1
  10. package/dist/builtin/subagents/skills/subagent/SKILL.md +26 -26
  11. package/dist/builtin/subagents/src/extension/index.bundle.mjs +140 -58
  12. package/dist/builtin/web-access/package.json +1 -1
  13. package/dist/builtin/workflows/CHANGELOG.md +27 -0
  14. package/dist/builtin/workflows/README.md +14 -15
  15. package/dist/builtin/workflows/builtin/{chunk-mygmtz6e.js → chunk-1nbq96fh.js} +19 -19
  16. package/dist/builtin/workflows/builtin/{chunk-zggjyg5z.js → chunk-n8zysf1t.js} +1 -1
  17. package/dist/builtin/workflows/builtin/{chunk-r9qq7xfj.js → chunk-vhmnzdj9.js} +37 -37
  18. package/dist/builtin/workflows/builtin/{chunk-62v3gg9f.js → chunk-yeee2jrc.js} +11 -11
  19. package/dist/builtin/workflows/builtin/goal.js +2 -2
  20. package/dist/builtin/workflows/builtin/index.js +4 -4
  21. package/dist/builtin/workflows/builtin/open-claude-design.js +1 -1
  22. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  23. package/dist/builtin/workflows/package.json +5 -5
  24. package/dist/builtin/workflows/src/extension/index.bundle.mjs +180 -239
  25. package/dist/builtin/workflows/src/index.js +19 -2
  26. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -1
  27. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +1 -1
  28. package/dist/core/agent-session-auto-compaction.js +1 -1
  29. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  30. package/dist/core/agent-session-compaction.js +1 -1
  31. package/dist/core/agent-session-compaction.js.map +1 -1
  32. package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
  33. package/dist/core/agent-session-custom-message-commit.js +33 -2
  34. package/dist/core/agent-session-custom-message-commit.js.map +1 -1
  35. package/dist/core/agent-session-message-queue.d.ts +1 -1
  36. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  37. package/dist/core/agent-session-message-queue.js +20 -6
  38. package/dist/core/agent-session-message-queue.js.map +1 -1
  39. package/dist/core/agent-session-methods.d.ts +4 -1
  40. package/dist/core/agent-session-methods.d.ts.map +1 -1
  41. package/dist/core/agent-session-methods.js.map +1 -1
  42. package/dist/core/agent-session-persistent-custom-messages.d.ts +1 -1
  43. package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
  44. package/dist/core/agent-session-persistent-custom-messages.js +13 -3
  45. package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
  46. package/dist/core/agent-session-post-tool-compaction.js +1 -1
  47. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  48. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  49. package/dist/core/agent-session-prompt.js +83 -0
  50. package/dist/core/agent-session-prompt.js.map +1 -1
  51. package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
  52. package/dist/core/agent-session-queue-pause.js +11 -0
  53. package/dist/core/agent-session-queue-pause.js.map +1 -1
  54. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  55. package/dist/core/agent-session-tool-hooks.js +2 -0
  56. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  57. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  58. package/dist/core/agent-session-tool-registry.js +12 -0
  59. package/dist/core/agent-session-tool-registry.js.map +1 -1
  60. package/dist/core/agent-session-transfer.d.ts.map +1 -1
  61. package/dist/core/agent-session-transfer.js +7 -0
  62. package/dist/core/agent-session-transfer.js.map +1 -1
  63. package/dist/core/agent-session-types.d.ts +2 -0
  64. package/dist/core/agent-session-types.d.ts.map +1 -1
  65. package/dist/core/agent-session-types.js +2 -0
  66. package/dist/core/agent-session-types.js.map +1 -1
  67. package/dist/core/agent-session.d.ts +4 -0
  68. package/dist/core/agent-session.d.ts.map +1 -1
  69. package/dist/core/agent-session.js +22 -0
  70. package/dist/core/agent-session.js.map +1 -1
  71. package/dist/core/extensions/context-types.d.ts +6 -0
  72. package/dist/core/extensions/context-types.d.ts.map +1 -1
  73. package/dist/core/extensions/context-types.js.map +1 -1
  74. package/dist/core/extensions/loader-virtual-modules.js +3 -3
  75. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  76. package/dist/core/extensions/runner-context.d.ts +1 -1
  77. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  78. package/dist/core/extensions/runner-context.js +9 -3
  79. package/dist/core/extensions/runner-context.js.map +1 -1
  80. package/dist/core/extensions/runner.js +1 -1
  81. package/dist/core/extensions/runner.js.map +1 -1
  82. package/dist/core/extensions/workflow-events.d.ts +1 -1
  83. package/dist/core/extensions/workflow-events.d.ts.map +1 -1
  84. package/dist/core/extensions/workflow-events.js.map +1 -1
  85. package/dist/core/sdk-exports.d.ts +1 -1
  86. package/dist/core/sdk-exports.d.ts.map +1 -1
  87. package/dist/core/sdk-exports.js +1 -1
  88. package/dist/core/sdk-exports.js.map +1 -1
  89. package/dist/core/settings-manager-basic-accessors.d.ts +5 -3
  90. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  91. package/dist/core/settings-manager-basic-accessors.js +23 -8
  92. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  93. package/dist/core/settings-manager.d.ts +1 -1
  94. package/dist/core/settings-manager.d.ts.map +1 -1
  95. package/dist/core/settings-manager.js.map +1 -1
  96. package/dist/core/settings-types.d.ts +5 -0
  97. package/dist/core/settings-types.d.ts.map +1 -1
  98. package/dist/core/settings-types.js.map +1 -1
  99. package/dist/core/slash-commands.d.ts.map +1 -1
  100. package/dist/core/slash-commands.js +4 -5
  101. package/dist/core/slash-commands.js.map +1 -1
  102. package/dist/core/tasks/agent-adapter.d.ts +5 -2
  103. package/dist/core/tasks/agent-adapter.d.ts.map +1 -1
  104. package/dist/core/tasks/agent-adapter.js +10 -3
  105. package/dist/core/tasks/agent-adapter.js.map +1 -1
  106. package/dist/core/tasks/completion.d.ts.map +1 -1
  107. package/dist/core/tasks/completion.js +5 -1
  108. package/dist/core/tasks/completion.js.map +1 -1
  109. package/dist/core/tools/bash-pty-native.d.ts +16 -2
  110. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  111. package/dist/core/tools/bash-pty-native.js +82 -0
  112. package/dist/core/tools/bash-pty-native.js.map +1 -1
  113. package/dist/core/tools/bash.d.ts +13 -2
  114. package/dist/core/tools/bash.d.ts.map +1 -1
  115. package/dist/core/tools/bash.js +48 -3
  116. package/dist/core/tools/bash.js.map +1 -1
  117. package/dist/core/tools/index.d.ts +4 -1
  118. package/dist/core/tools/index.d.ts.map +1 -1
  119. package/dist/core/tools/index.js +12 -0
  120. package/dist/core/tools/index.js.map +1 -1
  121. package/dist/core/tools/kill.d.ts +17 -0
  122. package/dist/core/tools/kill.d.ts.map +1 -0
  123. package/dist/core/tools/kill.js +49 -0
  124. package/dist/core/tools/kill.js.map +1 -0
  125. package/dist/core/tools/powershell.d.ts +84 -28
  126. package/dist/core/tools/powershell.d.ts.map +1 -1
  127. package/dist/core/tools/powershell.js +10 -3
  128. package/dist/core/tools/powershell.js.map +1 -1
  129. package/dist/core/workflow-stage-admission.d.ts +14 -0
  130. package/dist/core/workflow-stage-admission.d.ts.map +1 -1
  131. package/dist/core/workflow-stage-admission.js +63 -3
  132. package/dist/core/workflow-stage-admission.js.map +1 -1
  133. package/dist/index.d.ts +2 -2
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +1 -1
  136. package/dist/index.js.map +1 -1
  137. package/dist/modes/interactive/components/task-row.d.ts.map +1 -1
  138. package/dist/modes/interactive/components/task-row.js +8 -1
  139. package/dist/modes/interactive/components/task-row.js.map +1 -1
  140. package/docs/background-tasks.md +24 -1
  141. package/docs/compaction.md +20 -0
  142. package/docs/computer-use.md +390 -0
  143. package/docs/docs.json +1 -0
  144. package/docs/extensions.md +11 -1
  145. package/docs/herdr.md +2 -0
  146. package/docs/index.md +1 -0
  147. package/docs/intercom.md +10 -2
  148. package/docs/providers.md +1 -1
  149. package/docs/quickstart.md +1 -1
  150. package/docs/sdk.md +11 -1
  151. package/docs/settings.md +20 -0
  152. package/docs/subagents.md +8 -6
  153. package/docs/tmux.md +2 -0
  154. package/docs/tools.md +7 -1
  155. package/docs/usage.md +1 -1
  156. package/docs/workflows/api-reference.md +4 -3
  157. package/docs/workflows/authoring.md +3 -3
  158. package/docs/workflows/builtins.md +9 -6
  159. package/docs/workflows/operations.md +36 -30
  160. package/docs/workflows/reliable-design.md +3 -3
  161. package/docs/workflows/verification.md +99 -40
  162. package/docs/workflows.md +4 -2
  163. package/npm-shrinkwrap.json +32 -32
  164. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,41 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.9.19-alpha.5] - 2026-09-11
6
+
7
+ ### Changed
8
+
9
+ - Open Claude Design now starts with Claude Fable 5.1 at medium effort, followed by Copilot Fable 5.1 and Astra at medium effort, with the same Fable-first order on OpenRouter.
10
+ - Tuned bundled debugger, Goal, and Ralph reasoning efforts: debugger uses Astra/Fable at medium and Sol at high; Goal and Ralph reviewers use Astra/Sol at high; orchestration, Ralph research, and design use Fable at medium and Sol at high in their fallbacks. Ralph prompt refinement and other bundled agents retain their existing configurations.
11
+
12
+ ## [0.9.19-alpha.4] - 2026-09-10
13
+
14
+ ### Breaking Changes
15
+
16
+ - Workflow controls, completion, help, and status hints use `/workflow pause`, `/workflow quit`, and `/workflow resume`. The workflow tool supports run, stage, and individual durable-tool pause targets; `/workflow pause [run-id|--all]` controls runs. Workflow lifecycle control events report `action: "pause"` for pause requests.
17
+ - Renamed the bundled subagent `interrupt` action to `kill`. Migrate `subagent({ action: "interrupt", id })` to `subagent({ action: "kill", id })`, including calls using `runId`. The old action is no longer accepted. Kill terminally stops the child and cannot be resumed; follow-up work requires a fresh launch. Workflow controls use `/workflow pause`; parent cancellation behavior is unchanged.
18
+
19
+ ### Added
20
+
21
+ - Added a model row to the `/workflow connect` graph node cards showing each stage's effective model and thinking level, including canonical fast model identity, with model-name truncation preserving the suffixes. Cards retain duration, status and dependencies in a six-row layout, reflect live fallbacks, and restore identity through durable resume ([#1859](https://github.com/bastani-inc/atomic/pull/1859) by [@sina85](https://github.com/sina85)).
22
+ - Added `{ action: "wait", id, budgetMs }` to Bash and PowerShell for observing existing asynchronous tasks without rerunning commands. The observation budget is optional. Waits retain output and terminal metadata, follow owner observation policy, and release on cancellation or incoming messages without stopping execution or extending task lifetime.
23
+ - Added the agent-callable `kill({ id })` tool for owned background bash and PowerShell tasks in main and workflow-stage chat. It cancels by task ID, preserves retained output and original outcomes, reports current cleanup state, and rejects other owners' tasks and subagents.
24
+ - Added exact per-model overrides through `compaction.modelOverrides` for `compaction.reserveTokens` and Atomic's `compaction.preserve_recent` message count. Each field falls back to ordinary settings and then built-in defaults, with non-negative safe-integer validation. Manual, automatic, and post-tool compaction use the active model's budgets while retaining verbatim line compaction.
25
+
26
+ ### Fixed
27
+
28
+ - First-loaded TypeScript extensions share the live host's classes and singletons when native import falls back to transformation, avoiding duplicate host evaluation and slow startup.
29
+ - Fixed repeated yielded shell waits replaying the first output page instead of progressing through retained output while the task is still running ([#2972](https://github.com/bastani-inc/atomic/pull/2972)).
30
+ - Preserved an explicit subagent kill when parent cancellation arrives during execution-capacity waiting, and kept grouped Intercom cancellation status consistent when a killed child has parent-cancelled siblings.
31
+ - Embedded Postgres now starts on Windows administrative accounts. PostgreSQL refuses to run for a member of the Administrators or Power Users groups, so Atomic launches the retained server process with the same restricted access token `pg_ctl` uses, keeping exact-process shutdown semantics; non-administrative Windows accounts are unchanged. Postgres processes that exit during startup (including that administrator refusal on older builds) now fail fast with the actual server log instead of a readiness timeout.
32
+ - Preserved embedded Postgres startup logs on regular Windows accounts, honored Unicode environment overrides on administrative launches, and prevented Windows handle leaks across repeated launches.
33
+ - Preserved `PATH` lookup and relative executable paths for administrative Windows Postgres launches. Invalid launch inputs containing embedded NUL characters now fail before starting a process rather than using truncated paths, arguments, or environment values.
34
+ - Fixed custom Windows Postgres `.cmd` and `.bat` launchers failing with arguments on administrative accounts, including launcher paths containing spaces. Batch arguments retain their existing quoting and line-break rejection.
35
+ - Fixed explicit `cmd.exe` Postgres launchers and safe verbatim working directories on Windows administrative accounts. Concurrent Postgres launches no longer keep one another's log files open or expose them to unrelated commands starting at the same time.
36
+ - Incoming Intercom send and ask messages now act as a priority interrupt queue for working subagents and live workflow stages: the receiver's current model call or cancellable tool is cancelled immediately and the message is processed within the same task, session, and stage generation. Admission survives consumed preflight input and overlapping SDK interrupt turns. Completed tool side effects are never replayed, the original task prompt is not repeated, multiple arrivals stay in arrival order with duplicate suppression, and exact ask/reply correlation survives the cancelled turn. Explicit user abort, host stop, and terminal/closed receivers still win: late input never restarts finished work.
37
+ - Fixed a deadlock where an extension event hook awaiting an ordinary context-only message could wait behind an inbound Intercom delivery that was itself waiting for that event hook.
38
+ - Inbound delivery retries after a transient persistence failure keep their original arrival position and remain part of both child and workflow-stage settlement, and a card appended before a failed flush is completed on retry instead of being appended a second time.
39
+
5
40
  ## [0.9.19-alpha.3] - 2026-09-09
6
41
 
7
42
  ### Fixed
@@ -4,6 +4,14 @@ All notable changes to the `pi-intercom` extension will be documented in this fi
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.9.19-alpha.4] - 2026-09-10
8
+
9
+ ### Fixed
10
+
11
+ - Route lazy initialization, event-relay, and rejected-candidate cleanup diagnostics through the owning interactive session's notifications, including during shutdown, instead of leaking console output and stacks. Retryable initialization uses warning color; non-interactive console diagnostics (including RPC), original failures, acknowledgements, and retry behavior are preserved even when an error cannot be rendered.
12
+ - `send` and `ask` to a working subagent or live workflow stage are delivered as a priority interrupt: the recipient's active model call or cancellable tool is cancelled immediately and the message is processed in the same task instead of waiting for the next natural turn or being refused as busy. Completed side effects are not undone or replayed. Arrival order holds across persistence retries for both receiver kinds; duplicate suppression, exact reply correlation, terminal-child and closed-stage rejection, unrelated headless protection, and group restrictions are unchanged.
13
+ - A cancelled turn that produced no reply no longer consumes the pending ask's reply context, so replies to consecutive asks stay correlated with the right sender and message.
14
+
7
15
  ## [0.9.19-alpha.3] - 2026-09-09
8
16
 
9
17
  ### Fixed
@@ -1989,6 +1989,11 @@ class ReplyTracker {
1989
1989
  endTurn() {
1990
1990
  this.currentTurnContext = null;
1991
1991
  }
1992
+ restoreTurnContext() {
1993
+ if (this.currentTurnContext)
1994
+ this.pendingTurnContexts.unshift(this.currentTurnContext);
1995
+ this.currentTurnContext = null;
1996
+ }
1992
1997
  reset() {
1993
1998
  this.pendingAsks.clear();
1994
1999
  this.pendingTurnContexts.length = 0;
@@ -4579,10 +4584,15 @@ function registerIntercomLifecycle(pi, deps) {
4579
4584
  hasActiveSession = false;
4580
4585
  await cleanupRuntime("Session shutting down");
4581
4586
  });
4582
- pi.on("turn_end", () => {
4587
+ pi.on("turn_end", (event) => {
4583
4588
  if (!deps.getLiveContext())
4584
4589
  return;
4585
- activeReplyTracker().endTurn();
4590
+ const message = event.message;
4591
+ const cancelledBeforeReply = message?.role === "assistant" && message.stopReason === "aborted" && message.content?.length === 0;
4592
+ if (cancelledBeforeReply)
4593
+ activeReplyTracker().restoreTurnContext();
4594
+ else
4595
+ activeReplyTracker().endTurn();
4586
4596
  deps.scheduleInboundFlush();
4587
4597
  });
4588
4598
  pi.on("agent_start", () => {
@@ -5674,7 +5684,7 @@ function createIncomingMessageSender(input) {
5674
5684
  if (!input.canDeliver(generation)) {
5675
5685
  return Promise.reject(new Error("Intercom session retired before inbound delivery"));
5676
5686
  }
5677
- if (delivery === "trigger" && trackReplyContext) {
5687
+ if ((delivery === "trigger" || delivery === "interrupt") && trackReplyContext) {
5678
5688
  input.queueTurnContext(turnContext ?? { from: entry.from, message: entry.message, receivedAt: Date.now() });
5679
5689
  }
5680
5690
  const baseOptions = {
@@ -5682,7 +5692,7 @@ function createIncomingMessageSender(input) {
5682
5692
  persistWhenStreaming: true,
5683
5693
  ...stageAdmissionBarrier ? { stageAdmissionBarrier } : {}
5684
5694
  };
5685
- const options = delivery === "trigger" ? { ...baseOptions, triggerTurn: true } : delivery === "followUp" ? { ...baseOptions, deliverAs: "followUp" } : baseOptions;
5695
+ const options = delivery === "interrupt" ? { ...baseOptions, triggerTurn: true, deliverAs: "interrupt" } : delivery === "trigger" ? { ...baseOptions, triggerTurn: true } : delivery === "followUp" ? { ...baseOptions, deliverAs: "followUp" } : baseOptions;
5686
5696
  return Promise.resolve(input.pi.sendMessage(buildIncomingCustomMessage(entry), options));
5687
5697
  };
5688
5698
  }
@@ -6034,13 +6044,15 @@ function retryStableDelivery(options) {
6034
6044
  function admitWorkflowStageInbound(ctx, deliver, firstRefusal, onAdmissionFailure) {
6035
6045
  if (ctx.orchestrationContext?.kind !== "workflow-stage")
6036
6046
  return false;
6047
+ const boundary = ctx.orchestrationContext.messageAdmission?.boundary;
6048
+ const run = (barrier) => boundary?.runMessageDelivery(() => deliver(barrier), () => deliver(), true) ?? Promise.resolve(deliver(barrier));
6037
6049
  try {
6038
6050
  let busy = false;
6039
6051
  try {
6040
6052
  busy = ctx.isIdle?.() === false;
6041
6053
  } catch {}
6042
6054
  if (!busy || !firstRefusal)
6043
- return Promise.resolve(deliver());
6055
+ return run();
6044
6056
  let firstRefusalPromise;
6045
6057
  const admissionBarrier = () => {
6046
6058
  firstRefusalPromise ??= (async () => {
@@ -6053,12 +6065,29 @@ function admitWorkflowStageInbound(ctx, deliver, firstRefusal, onAdmissionFailur
6053
6065
  })();
6054
6066
  return firstRefusalPromise;
6055
6067
  };
6056
- return Promise.resolve(deliver(admissionBarrier));
6068
+ return run(admissionBarrier);
6057
6069
  } catch (error) {
6058
6070
  return Promise.reject(error);
6059
6071
  }
6060
6072
  }
6061
6073
 
6074
+ // dist/builtin/intercom/active-session-admission.ts
6075
+ function admitActiveSessionInbound(ctx, deliver, firstRefusal, onAdmissionFailure) {
6076
+ const executionEnded = ctx.subagentPolicy?.executionEnded;
6077
+ if (executionEnded !== undefined) {
6078
+ if (executionEnded.aborted || ctx.subagentPolicy?.messageAdmission?.isOpen() === false) {
6079
+ return Promise.reject(new Error("Subagent execution is terminal and cannot accept messages"));
6080
+ }
6081
+ try {
6082
+ return ctx.subagentPolicy?.messageAdmission?.run(deliver) ?? Promise.resolve(deliver());
6083
+ } catch (error) {
6084
+ return Promise.reject(error);
6085
+ }
6086
+ }
6087
+ return admitWorkflowStageInbound(ctx, deliver, firstRefusal, onAdmissionFailure);
6088
+ }
6089
+ var init_active_session_admission = () => {};
6090
+
6062
6091
  // dist/builtin/intercom/workflow-reply-tracker.ts
6063
6092
  function bindWorkflowReplyTracker(ctx, current) {
6064
6093
  const state = ctx.orchestrationContext?.messageAdmission?.extensionState;
@@ -6112,7 +6141,7 @@ async function settleOpenStageDeliveryFailure(input, error) {
6112
6141
  input.admission.release(input.reservation, failure);
6113
6142
  return;
6114
6143
  }
6115
- const delivered = await sendWorkflowStageDeliveryFailure(input.entry, failure, input.tracker, input.currentClient, () => input.currentClient()?.isConnected() === true, "Running workflow stage could not admit intercom ask");
6144
+ const delivered = await sendWorkflowStageDeliveryFailure(input.entry, failure, input.tracker, input.currentClient, () => input.currentClient()?.isConnected() === true, input.failurePrefix ?? "Running workflow stage could not admit intercom ask");
6116
6145
  if (delivered)
6117
6146
  input.commit();
6118
6147
  else
@@ -6479,17 +6508,18 @@ function piIntercomExtension(pi, testOverrides = {}) {
6479
6508
  tracker: replyTracker,
6480
6509
  replyContext,
6481
6510
  currentClient: () => client,
6482
- commit
6511
+ commit,
6512
+ failurePrefix: liveContext.subagentPolicy?.executionEnded === undefined ? undefined : "Subagent could not admit intercom ask"
6483
6513
  });
6484
- const stageDelivery = admitWorkflowStageInbound(liveContext, (admissionBarrier) => {
6514
+ const activeDelivery = admitActiveSessionInbound(liveContext, (admissionBarrier) => {
6485
6515
  replyTracker.queueTurnContext(replyContext);
6486
6516
  return retryStableDelivery({
6487
- deliver: () => sendIncomingMessage(entry, "trigger", messageGeneration, false, undefined, admissionBarrier),
6488
- isCurrent: () => Boolean(getLiveContext(liveContext, messageGeneration))
6517
+ deliver: () => sendIncomingMessage(entry, "interrupt", messageGeneration, false, undefined, admissionBarrier),
6518
+ isCurrent: () => Boolean(getLiveContext(liveContext, messageGeneration)) && liveContext.subagentPolicy?.executionEnded?.aborted !== true && liveContext.subagentPolicy?.messageAdmission?.isOpen() !== false
6489
6519
  });
6490
6520
  }, () => foregroundDetachHandoff.claim(from, message, messageGeneration, () => Boolean(getLiveContext(liveContext, messageGeneration))), release);
6491
- if (stageDelivery !== false) {
6492
- stageDelivery.then(commit, release);
6521
+ if (activeDelivery !== false) {
6522
+ activeDelivery.then(commit, release);
6493
6523
  return;
6494
6524
  }
6495
6525
  return (async () => {
@@ -6499,7 +6529,7 @@ function piIntercomExtension(pi, testOverrides = {}) {
6499
6529
  release(new Error("Intercom session retired before inbound delivery"));
6500
6530
  return;
6501
6531
  }
6502
- if (!activeContext.isIdle()) {
6532
+ if (!activeContext.isIdle() && !activeContext.getAgentTaskHost?.().hasActiveTaskWaits) {
6503
6533
  if (!activeContext.hasUI) {
6504
6534
  const activeClient = client;
6505
6535
  if (!message.replyTo && activeClient?.isConnected()) {
@@ -6542,6 +6572,13 @@ function piIntercomExtension(pi, testOverrides = {}) {
6542
6572
  });
6543
6573
  return;
6544
6574
  }
6575
+ if (!activeContext.isIdle()) {
6576
+ const disposition = await foregroundDetachHandoff.claim(from, message, messageGeneration, () => Boolean(getLiveContext(liveContext, messageGeneration)));
6577
+ if (disposition === "abandoned") {
6578
+ release(new Error("Intercom session retired during foreground-owner admission"));
6579
+ return;
6580
+ }
6581
+ }
6545
6582
  replyTracker.queueTurnContext(replyContext);
6546
6583
  await retryStableDelivery({ deliver: () => sendIncomingMessage(entry, "trigger", messageGeneration, false), isCurrent: () => Boolean(getLiveContext(liveContext, messageGeneration)) });
6547
6584
  commit();
@@ -7118,6 +7155,7 @@ var init_index_heavy = __esm(() => {
7118
7155
  init_terminal_ordering_barrier();
7119
7156
  init_inbound_message_admission();
7120
7157
  init_late_stage_message_router();
7158
+ init_active_session_admission();
7121
7159
  init_workflow_reply_tracker();
7122
7160
  init_closed_workflow_stage_message();
7123
7161
  init_group();
@@ -7135,11 +7173,20 @@ var init_index_heavy = __esm(() => {
7135
7173
  });
7136
7174
 
7137
7175
  // dist/builtin/intercom/index.ts
7138
- init_result_renderers();
7139
7176
  import { APP_NAME as APP_NAME2, getEnvValue } from "@bastani/atomic";
7140
7177
  import { Text as Text4 } from "@earendil-works/pi-tui";
7141
7178
  import { Type as Type3 } from "typebox";
7142
7179
 
7180
+ // dist/builtin/intercom/context-owner.ts
7181
+ var CONTEXT_OWNERS_KEY = Symbol.for("atomic-coding-agent/extension-context-owners@1");
7182
+ function getExtensionContextOwner(context) {
7183
+ const owners = globalThis[CONTEXT_OWNERS_KEY];
7184
+ return owners?.get(context) ?? context;
7185
+ }
7186
+
7187
+ // dist/builtin/intercom/index.ts
7188
+ init_result_renderers();
7189
+
7143
7190
  // dist/builtin/intercom/lazy-tool-execution.ts
7144
7191
  init_recoverable_disconnect();
7145
7192
  init_retry_policy();
@@ -7401,10 +7448,37 @@ function renderHeavyToolResult(loadedHeavy, name, args) {
7401
7448
  return renderer(...args);
7402
7449
  return renderIntercomToolResult(name, args);
7403
7450
  }
7404
- function reportRelayFailure(eventName, error) {
7451
+ function diagnosticDetail(error) {
7452
+ try {
7453
+ return String(error instanceof Error ? error.message : error);
7454
+ } catch {
7455
+ return "Unprintable error";
7456
+ }
7457
+ }
7458
+ function captureDiagnosticRoute(ctx) {
7459
+ try {
7460
+ return ctx?.hasUI && ctx.mode === "tui" ? ctx : "console";
7461
+ } catch {
7462
+ return "silent";
7463
+ }
7464
+ }
7465
+ function reportDiagnostic(route, message, error, level, consoleMessage = message) {
7466
+ if (route === "console") {
7467
+ console.error(consoleMessage, error);
7468
+ return;
7469
+ }
7470
+ if (route === "silent")
7471
+ return;
7472
+ try {
7473
+ route.ui.notify(message, level);
7474
+ } catch {}
7475
+ }
7476
+ function reportRelayFailure(route, eventName, error) {
7405
7477
  if (isRecoverableIntercomDisconnect(error))
7406
7478
  return;
7407
- console.error(`Intercom event relay failed (${eventName}):`, error);
7479
+ const prefix = `Intercom event relay failed (${eventName}):`;
7480
+ const detail = diagnosticDetail(error);
7481
+ reportDiagnostic(route, `${prefix} ${detail}`, error, "error", prefix);
7408
7482
  }
7409
7483
  var WARM_UP_RETRY_ATTEMPTS = 5;
7410
7484
  function intercom(pi, options = {}) {
@@ -7412,6 +7486,7 @@ function intercom(pi, options = {}) {
7412
7486
  let heavyAttempt = null;
7413
7487
  let loadedHeavy = null;
7414
7488
  let sessionSnapshot = null;
7489
+ let shutdownDiagnosticRoute;
7415
7490
  let lifecycleGeneration = 0;
7416
7491
  let nextLeaseId = 1;
7417
7492
  let activeLease = createLifecycleLease(nextLeaseId++);
@@ -7495,6 +7570,8 @@ function intercom(pi, options = {}) {
7495
7570
  await promise;
7496
7571
  }
7497
7572
  async function loadHeavy(ctx) {
7573
+ let diagnosticRoute = captureDiagnosticRoute(ctx);
7574
+ let diagnosticOwner = ctx && getExtensionContextOwner(ctx);
7498
7575
  const lease = activeLease;
7499
7576
  if (lease.retired)
7500
7577
  throw new Error("Intercom initialization unavailable: no active session");
@@ -7511,6 +7588,7 @@ function intercom(pi, options = {}) {
7511
7588
  return handle;
7512
7589
  }
7513
7590
  let promise;
7591
+ let replayCtx = null;
7514
7592
  promise = (async () => {
7515
7593
  const captured = {
7516
7594
  tools: new Map,
@@ -7519,7 +7597,6 @@ function intercom(pi, options = {}) {
7519
7597
  shortcuts: new Map,
7520
7598
  eventHandlers: new Map
7521
7599
  };
7522
- let replayCtx = null;
7523
7600
  let cleaned = false;
7524
7601
  const cleanupCandidate = async () => {
7525
7602
  const shutdown = lease.shutdown;
@@ -7531,7 +7608,9 @@ function intercom(pi, options = {}) {
7531
7608
  try {
7532
7609
  await dispatchHandlers(captured, "session_shutdown", event, cleanupCtx);
7533
7610
  } catch (cleanupError) {
7534
- console.error("Intercom failed to clean rejected lazy candidate:", cleanupError);
7611
+ const prefix = "Intercom failed to clean rejected lazy candidate:";
7612
+ const detail = diagnosticDetail(cleanupError);
7613
+ reportDiagnostic(shutdown?.diagnosticRoute ?? diagnosticRoute, `${prefix} ${detail}`, cleanupError, "error", prefix);
7535
7614
  }
7536
7615
  };
7537
7616
  try {
@@ -7543,6 +7622,11 @@ function intercom(pi, options = {}) {
7543
7622
  sessionSnapshot = { event: createSyntheticSessionStartEvent(), ctx, generation: ++lifecycleGeneration, lease };
7544
7623
  }
7545
7624
  await ensureSessionStartReplayed(captured, lease, (replayContext) => {
7625
+ const owner = getExtensionContextOwner(replayContext);
7626
+ if (owner !== diagnosticOwner) {
7627
+ diagnosticRoute = captureDiagnosticRoute(replayContext);
7628
+ diagnosticOwner = owner;
7629
+ }
7546
7630
  replayCtx = replayContext;
7547
7631
  });
7548
7632
  assertLease(lease);
@@ -7561,8 +7645,8 @@ function intercom(pi, options = {}) {
7561
7645
  if (heavyAttempt?.promise === promise)
7562
7646
  heavyAttempt = null;
7563
7647
  if (!isRecoverableIntercomDisconnect(error)) {
7564
- const message = error instanceof Error ? error.message : String(error);
7565
- console.error(`Intercom heavy initialization failed; a later call will retry: ${message}`, error);
7648
+ const message = diagnosticDetail(error);
7649
+ reportDiagnostic(diagnosticRoute, `Intercom heavy initialization failed; a later call will retry: ${message}`, error, "warning");
7566
7650
  }
7567
7651
  });
7568
7652
  return promise;
@@ -7673,6 +7757,7 @@ function intercom(pi, options = {}) {
7673
7757
  }
7674
7758
  const generation = ++lifecycleGeneration;
7675
7759
  sessionSnapshot = { event, ctx, generation, lease };
7760
+ shutdownDiagnosticRoute = undefined;
7676
7761
  cancelWarmUpRetry();
7677
7762
  if (ctx.orchestrationContext?.kind === "workflow-stage" && ctx.orchestrationContext.pendingStageDelivery !== undefined) {
7678
7763
  const pendingStageDelivery = ctx.orchestrationContext.pendingStageDelivery;
@@ -7690,7 +7775,9 @@ function intercom(pi, options = {}) {
7690
7775
  pi.on("session_shutdown", async (event, ctx) => {
7691
7776
  const lease = activeLease;
7692
7777
  const generation = ++lifecycleGeneration;
7693
- retireLifecycleLease(lease, { event, ctx, generation });
7778
+ const diagnosticRoute = captureDiagnosticRoute(ctx);
7779
+ retireLifecycleLease(lease, { event, ctx, generation, diagnosticRoute });
7780
+ shutdownDiagnosticRoute = diagnosticRoute;
7694
7781
  cancelWarmUpRetry();
7695
7782
  const retiredHeavy = loadedHeavy?.heavy ?? null;
7696
7783
  const retiredAttempt = heavyAttempt?.lease === lease ? heavyAttempt.promise : null;
@@ -7811,13 +7898,15 @@ function intercom(pi, options = {}) {
7811
7898
  return;
7812
7899
  payload.handled = true;
7813
7900
  const forwarded = { ...payload, handled: false, completion: undefined };
7814
- payload.completion = loadHeavy(latestLifecycleContext()).then(async (handle) => {
7901
+ const ctx = latestLifecycleContext();
7902
+ const diagnosticRoute = ctx ? captureDiagnosticRoute(ctx) : shutdownDiagnosticRoute ?? "console";
7903
+ payload.completion = loadHeavy(ctx).then(async (handle) => {
7815
7904
  handle.assertCurrent();
7816
7905
  await dispatchEventHandlers(handle.heavy, PENDING_STAGE_UNDELIVERABLE_EVENT2, forwarded);
7817
7906
  handle.assertCurrent();
7818
7907
  return forwarded.handled === true && forwarded.completion !== undefined ? await forwarded.completion : false;
7819
7908
  }).catch((error) => {
7820
- reportRelayFailure(PENDING_STAGE_UNDELIVERABLE_EVENT2, error);
7909
+ reportRelayFailure(diagnosticRoute, PENDING_STAGE_UNDELIVERABLE_EVENT2, error);
7821
7910
  return false;
7822
7911
  });
7823
7912
  });
@@ -7827,7 +7916,9 @@ function intercom(pi, options = {}) {
7827
7916
  PENDING_STAGE_ROUTE_EVENT2
7828
7917
  ]) {
7829
7918
  pi.events.on(eventName, (payload) => {
7830
- const completion = loadHeavy(latestLifecycleContext()).then(async (handle) => {
7919
+ const ctx = latestLifecycleContext();
7920
+ const diagnosticRoute = ctx ? captureDiagnosticRoute(ctx) : shutdownDiagnosticRoute ?? "console";
7921
+ const completion = loadHeavy(ctx).then(async (handle) => {
7831
7922
  handle.assertCurrent();
7832
7923
  await dispatchEventHandlers(handle.heavy, eventName, payload);
7833
7924
  handle.assertCurrent();
@@ -7842,7 +7933,7 @@ function intercom(pi, options = {}) {
7842
7933
  }
7843
7934
  completion.catch((error) => {
7844
7935
  rejectLazyResultRelay(pi, eventName, payload, error);
7845
- reportRelayFailure(eventName, error);
7936
+ reportRelayFailure(diagnosticRoute, eventName, error);
7846
7937
  });
7847
7938
  });
7848
7939
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/intercom",
3
- "version": "0.9.19-alpha.3",
3
+ "version": "0.9.19-alpha.5",
4
4
  "private": true,
5
5
  "description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
6
6
  "contributors": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/mcp",
3
- "version": "0.9.19-alpha.3",
3
+ "version": "0.9.19-alpha.5",
4
4
  "private": true,
5
5
  "description": "Atomic extension that adapts MCP (Model Context Protocol) servers into the coding agent. Fork of: https://github.com/nicobailon/pi-mcp-adapter",
6
6
  "contributors": [
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.9.19-alpha.5] - 2026-09-11
6
+
7
+ ### Changed
8
+
9
+ - The bundled debugger now uses GPT-6 Astra at `medium`, with Astra/Fable 5.1/Fable 5 fallbacks at `medium` and Sol at `high`. Its complete fallback order, other model efforts, and all other bundled agent configurations remain unchanged.
10
+
11
+ ## [0.9.19-alpha.4] - 2026-09-10
12
+
13
+ ### Breaking Changes
14
+
15
+ - Renamed the terminal subagent control action from `interrupt` to `kill`. Replace `subagent({ action: "interrupt", id })` with `subagent({ action: "kill", id })`, including calls using `runId`. The old action is rejected, not aliased. Killed children cannot be resumed; launch a fresh child with explicit context for follow-up work. Command results and status report killed, while parent cancellation and lower-level host/native interruption retain their existing semantics.
16
+
17
+ ### Fixed
18
+
19
+ - Preserved an explicit kill when parent cancellation arrives during execution-capacity waiting, without allowing a late kill to replace an earlier parent cancellation.
20
+ - Kept grouped Intercom cancellation status consistent when a killed child has parent-cancelled siblings, while retaining each child's outcome.
21
+ - Intercom `send` and `ask` interrupt a working foreground or background child immediately: its current model call or cancellable tool is cancelled and the message is handled in the same child execution without relaunch. Messages admitted during startup, consumed input preflight, overlapping SDK interrupt turns, or final settlement still join the original task rather than creating competing work or disappearing ahead of the result; explicit user abort and owner cancellation remain terminal.
22
+
5
23
  ## [0.9.19-alpha.3] - 2026-09-09
6
24
 
7
25
  ### Changed
@@ -125,7 +125,7 @@ There is no generic `reviewer` or `planner` agent; pick the specialist whose ang
125
125
 
126
126
  ## Changing a builtin agent's model
127
127
 
128
- Builtin agents inherit your current Pi default model by default. This keeps new installs from depending on a provider you may not have configured. If you want a role to use a specific model, set an override instead of copying the bundled agent file.
128
+ Builtin agents declare role-specific models and ordered fallbacks. The debugger starts with `openai-codex/gpt-6-astra:medium`, with Astra/Fable fallbacks at `medium` and Sol/Opus fallbacks at `high`. See the [bundled defaults](../coding-agent/docs/subagents.md#bundled-agents) for the other roles. If you want a role to use a specific model, set an override instead of copying the bundled agent file.
129
129
 
130
130
  For one run, pass `model` on the `subagent` call:
131
131
 
@@ -134,7 +134,7 @@ subagent({ agent: "codebase-analyzer", task: "Review this diff", model: "anthrop
134
134
  ```
135
135
 
136
136
 
137
- For a persistent override, edit settings. This example pins the codebase-analyzer everywhere, adds a backup model for provider failures, and keeps the other builtins on your normal default model:
137
+ For a persistent override, edit settings. This example pins the codebase-analyzer everywhere, adds a backup model for provider failures, and keeps the other builtins on their configured defaults:
138
138
 
139
139
  ```json
140
140
  {
@@ -181,7 +181,7 @@ subagent({ agent: "codebase-analyzer", task: "Trace authentication.", wait: { ki
181
181
  subagent({ agent: "codebase-analyzer", task: "Trace authentication.", wait: { kind: "foreground", budgetMs: 30000 } })
182
182
  subagent({ action: "wait", id: taskId, budgetMs: 1000 })
183
183
  subagent({ action: "status", id: taskId })
184
- subagent({ action: "interrupt", id: taskId })
184
+ subagent({ action: "kill", id: taskId })
185
185
  ```
186
186
 
187
187
  In owner-bound sessions, omitted `wait` means background. Explicit foreground waits use the owner's agent observation budget, normally 30 seconds, unless overridden. Expiry releases the caller, not the execution. Wait or inspect the returned task ID instead of launching a duplicate. Existing SDK callers without an owner retain their original execution path.
@@ -200,7 +200,7 @@ clarify → gather context → worker → fresh reviewers → worker
200
200
 
201
201
  Packaged `worker` defaults to forked context when a launch omits `context`; every other builtin runs fresh. Pass `context: "fresh"` when you intentionally want a fresh `worker` run.
202
202
 
203
- Child-safety boundaries are enforced at runtime by typed admission policy. 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: fanout is authorized only when the resolved builtin `tools` list includes `subagent`. Typed admission policy lets a non-fanout child use only `list`, `get`, and `status`; delegation and `interrupt` receive the fanout refusal. A management-restricted child is also refused `create`, `update`, and `delete`. The bundled `pi-subagents` skill remains parent-only and is stripped from child prompts, including fanout-authorized children. No admitted child may delegate or control another child: launches and `interrupt` are refused for every child regardless of its fanout authorization. Children receive boundary instructions that they are not the parent orchestrator and must complete their assigned task directly. Forked child context filtering also removes parent-only subagent artifacts (including old hidden orchestration-instruction messages, slash/status/control messages, and prior parent `subagent` tool-call/tool-result history) while preserving ordinary prose and unrelated tool calls/results.
203
+ Child-safety boundaries are enforced at runtime by typed admission policy. 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: fanout is authorized only when the resolved builtin `tools` list includes `subagent`. Typed admission policy lets a non-fanout child use only `list`, `get`, and `status`; delegation and `kill` receive the fanout refusal. A management-restricted child is also refused `create`, `update`, and `delete`. The bundled `pi-subagents` skill remains parent-only and is stripped from child prompts, including fanout-authorized children. No admitted child may delegate or control another child: launches and `kill` are refused for every child regardless of its fanout authorization. Children receive boundary instructions that they are not the parent orchestrator and must complete their assigned task directly. Forked child context filtering also removes parent-only subagent artifacts (including old hidden orchestration-instruction messages, slash/status/control messages, and prior parent `subagent` tool-call/tool-result history) while preserving ordinary prose and unrelated tool calls/results.
204
204
 
205
205
 
206
206
 
@@ -230,13 +230,13 @@ The child can use one dedicated coordination tool:
230
230
 
231
231
  Child-side routine completion handoffs are still not expected. In parallel runs, blocking `contact_supervisor` decisions/interviews and parent-targeted `intercom.ask` wait only in the requesting child. The supervisor replies through Intercom to the exact question; the same child continues with its original context and run identity. Sends and progress updates return without a reply.
232
232
 
233
- An exact-child probe/commit handshake may release parallel foreground observations, including queued slots, so the parent can respond. It does not end any execution or spend a running concurrency slot. Active siblings keep working, queued siblings start once capacity becomes available, and worktrees remain until their owners finish. Do not relaunch children to answer an ask. Targeted interruption, explicit batch cancellation, and owner closure remain separate controls.
233
+ An exact-child probe/commit handshake may release parallel foreground observations, including queued slots, so the parent can respond. It does not end any execution or spend a running concurrency slot. Active siblings keep working, queued siblings start once capacity becomes available, and worktrees remain until their owners finish. Do not relaunch children to answer an ask. Targeted kill, explicit batch cancellation, and owner closure remain separate controls.
234
234
 
235
235
  Single-child launches retain their existing terminal parent-ask handoff: the exact live child ends before broker send or waiter admission and the parent receives the verbatim question, ordered attachments, identity, and `[TASK_CONTEXT]` for a fresh child. The bridge still obtains each child's capability during admission; the child connects only when it uses Intercom.
236
236
 
237
237
  Parent-side Atomic sends grouped completion results through Intercom: one grouped message per foreground parent `subagent` run and one per detached child completion while its owning session remains live. When a workflow stage completes, Atomic cancels its still-running detached children and suppresses their late findings and completion notifications instead of forwarding them to the parent/main chat. Intercom-confirmed delivery returns a compact receipt with artifact/session paths; without that confirmation, the normal full output is preserved. Grouped messages include child Intercom targets and full child summaries.
238
238
 
239
- If a child appears stalled, needs-attention notices can show up in the parent session with useful next actions, such as checking `subagent({ action: "status" })`, interrupting the run, or nudging the child.
239
+ If a child appears stalled, needs-attention notices can show up in the parent session with useful next actions, such as checking `subagent({ action: "status" })`, killing the run, or nudging the child.
240
240
 
241
241
  If messages do not show up, check the bridge from the intercom side with `intercom({ action: "status" })`.
242
242
 
@@ -263,7 +263,7 @@ Agent locations, lowest to highest priority:
263
263
 
264
264
  Project discovery also reads legacy `.agents/**/*.md` and `.pi/agents/**/*.md` files. Nested subdirectories are discovered recursively. If primary Atomic and legacy paths define the same parsed runtime agent name, the primary `.atomic/agents/` definition wins. Use `agentScope: "user" | "project" | "both"` to control discovery; `both` is the default and project definitions win runtime-name collisions.
265
265
 
266
- Builtin agents load at the lowest priority, so a user or project agent with the same name overrides them. They do not pin a provider model; they inherit your current Atomic default model unless you set `subagents.agentOverrides.<name>.model`. `worker` is the implementation agent for normal tasks and approved orchestrator handoffs.
266
+ Builtin agents load at the lowest priority, so a user or project agent with the same name overrides them. Their declared models and fallback chains apply unless you set an override such as `subagents.agentOverrides.<name>.model`. `worker` is the implementation agent for normal tasks and approved orchestrator handoffs.
267
267
 
268
268
  The `codebase-online-researcher` builtin uses `web_search`, `fetch_content`, and `get_search_content`; those require [pi-web-access](https://github.com/nicobailon/pi-web-access):
269
269
 
@@ -434,7 +434,7 @@ What the bundled skill covers:
434
434
  - **Role-agent prompting guidance**: compact contract prompts instead of long scripts, what to include in role-specific meta prompts, and retrieval budgets for researchers
435
435
  - **Safety boundaries**: child agents must not run subagents, must not invent intercom targets, and must escalate unapproved decisions
436
436
  - **Intercom conventions**: when to ask vs send, and how parent-side result delivery works with `pi-intercom`
437
- - **Control signals**: attention signals, soft interrupts, and status
437
+ - **Control signals**: attention signals, terminal kills, and status
438
438
 
439
439
  If you are writing an agent that orchestrates subagents, the bundled skill helps it behave correctly without guessing the patterns. If you are a human user, you do not need to read it directly; the README and prompt shortcuts encode the same workflows in user-facing form.
440
440
 
@@ -524,11 +524,11 @@ Agent definitions are not loaded into context by default. Management actions let
524
524
  |-------|------|---------|-------------|
525
525
  | `agent` | string | - | Agent name for single mode, or target for management actions. |
526
526
  | `task` | string | - | Task string for single mode. |
527
- | `action` | string | - | `list`, `get`, `create`, `update`, `delete`, `status`, `wait`, or `interrupt`. |
527
+ | `action` | string | - | `list`, `get`, `create`, `update`, `delete`, `status`, `wait`, or `kill`. |
528
528
  | `config` | object/string | - | Agent config for create/update. |
529
529
  | `wait` | object | background in owner-bound sessions | `{ kind: "background" }` yields after admission; `{ kind: "foreground", budgetMs?: number }` waits before automatically yielding. |
530
530
  | `budgetMs` | number | owner wait policy | Observation budget for `action: "wait"`; not a child execution deadline. |
531
- | `id` | string | - | Task ID returned by an owner-bound launch for `wait`, `status`, or `interrupt`. |
531
+ | `id` | string | - | Task ID returned by an owner-bound launch for `wait`, `status`, or `kill`. |
532
532
  | `output` | `string \| false` | agent default | Override single-agent output file. |
533
533
  | `outputMode` | `"inline" \| "file-only"` | `inline` | Return saved output inline or as a concise saved-file reference. `file-only` requires an `output` path. |
534
534
  | `reads` | `string[] \| false` | - | Single-agent files to read before execution, or `false` to disable. Relative paths resolve against the effective child `cwd`; absolute paths pass through. |
@@ -557,10 +557,10 @@ Status and control actions:
557
557
  ```ts
558
558
  subagent({ action: "status" })
559
559
  subagent({ action: "status", id: "<run-id>" })
560
- subagent({ action: "interrupt", id: "<run-id>" })
560
+ subagent({ action: "kill", id: "<run-id>" })
561
561
  ```
562
562
 
563
- Completed, interrupted, and single-child terminal-handoff children cannot be revived by a prior run ID; follow-up work requires a fresh launch with explicit context. A parallel child waiting for a reply is not terminal and continues in its original execution. Explicit cancellation of a still-running child uses the interrupted/abort state: receipts and progress present it as cancelled rather than failed, persisted metadata keeps the abort cause, and bounded partial findings remain available.
563
+ Completed, killed, interrupted, and single-child terminal-handoff children cannot be revived by a prior run ID; follow-up work requires a fresh launch with explicit context. A parallel child waiting for a reply is not terminal and continues in its original execution. Parent cancellation of a still-running child uses the interrupted/abort state: receipts and progress present it as cancelled rather than failed, persisted metadata keeps the abort cause, and bounded partial findings remain available. Migrate old subagent calls from `action: "interrupt"` to `action: "kill"`; the old action is rejected. Kill is terminal and cannot be resumed. Workflow controls use `pause`; host interrupt APIs are unchanged.
564
564
 
565
565
  ## Worktree isolation
566
566
 
@@ -681,7 +681,7 @@ Foreground runs persist their session and user-facing artifacts beside the paren
681
681
  run-history.jsonl
682
682
  ```
683
683
 
684
- Task-ID status, wait, and interrupt resolve the same owner as launch. Run-ID status uses the existing Rust subagent registry. Owner-bound completion delivery uses persisted intent and acknowledgement records in session history; no second PID registry or execution is created for the UI.
684
+ Task-ID status, wait, and kill resolve the same owner as launch. Run-ID status uses the existing Rust subagent registry. Owner-bound completion delivery uses persisted intent and acknowledgement records in session history; no second PID registry or execution is created for the UI.
685
685
 
686
686
  ## Completion and output
687
687
 
@@ -716,7 +716,7 @@ This is disabled by default. Session data may contain source code, paths, enviro
716
716
 
717
717
  ## Delegation boundary
718
718
 
719
- Delegation is exactly one level deep, and nothing configures it. A top-level session main chat or a workflow stage may call `subagent`. A session that was itself admitted as a subagent child may not: every launch and `interrupt` it attempts is refused with guidance to complete its assigned task directly. The observing actions `list`, `get`, and `status` stay available to a child. Child sessions retain bundled workflow definitions as resources but do not load the workflows extension or expose its `workflow` tool; orchestration stays owned by the parent session.
719
+ Delegation is exactly one level deep, and nothing configures it. A top-level session, main chat or a workflow stage, may call `subagent`. A session that was itself admitted as a subagent child may not: every launch and `kill` it attempts is refused with guidance to complete its assigned task directly. The observing actions `list`, `get`, and `status` stay available to a child. Child sessions retain bundled workflow definitions as resources but do not load the workflows extension or expose its `workflow` tool; orchestration stays owned by the parent session.
720
720
 
721
721
  There is no configuration option, agent frontmatter field, or tool parameter for the delegation level. The rule is enforced twice: the subagent executor refuses a child before any run starts, and the Rust `SubagentControl` admission door refuses a child deeper than the single permitted level. Admitted depth is typed admission state and is not inherited through an environment variable.
722
722
 
@@ -773,7 +773,7 @@ The main runtime files are:
773
773
  |------|---------|
774
774
  | `src/extension/index.ts` | Extension registration, tool registration, message/render wiring. |
775
775
  | `src/agents/agents.ts` | Agent discovery and frontmatter parsing. |
776
- | `src/runs/foreground/subagent-executor.ts` | Main execution routing for single, parallel, management, status, and interrupt actions. |
776
+ | `src/runs/foreground/subagent-executor.ts` | Main execution routing for single, parallel, management, status, and kill actions. |
777
777
  | `src/runs/foreground/execution.ts` | Core foreground `runSync` handling. |
778
778
  | `src/runs/foreground/notify.ts` | Completion-notification delivery for a detached Intercom child. |
779
779
  | `src/runs/foreground/completion-notification.ts` | Local completion acknowledgement and ordering barrier for detached children. |
@@ -2,8 +2,8 @@
2
2
  name: debugger
3
3
  description: Debug and fix errors, test failures, and unexpected behavior. Use PROACTIVELY when encountering issues, analyzing stack traces, or investigating system problems.
4
4
  tools: read, edit, write, search, find, ls, bash, web_search, fetch_content, get_search_content, intercom, contact_supervisor, todo
5
- model: openai-codex/gpt-6-astra:xhigh
6
- fallbackModels: github-copilot/gpt-6-astra:xhigh, openai/gpt-6-astra:xhigh, anthropic/claude-fable-5-1:high, github-copilot/claude-fable-5-1:high, anthropic/claude-opus-5:high, github-copilot/claude-opus-5:high, anthropic/claude-fable-5:high, github-copilot/claude-fable-5:high, openai-codex/gpt-5.6-sol:xhigh, github-copilot/gpt-5.6-sol:xhigh, openai/gpt-5.6-sol:xhigh, kimi-coding/k3:max, moonshotai/kimi-k3:max, moonshotai-cn/kimi-k3:max, openai-codex/gpt-5.5:xhigh, github-copilot/gpt-5.5:xhigh, openai/gpt-5.5:xhigh, anthropic/claude-opus-4-8:high, github-copilot/claude-opus-4.8:high, xai/grok-4.6:xhigh, github-copilot/grok-4.6:xhigh, zai/glm-5.3:high, zai-coding-cn/glm-5.3:high, zai/glm-5.3-flash:high, zai-coding-cn/glm-5.3-flash:high, baseten/zai-org/GLM-5.3:high, baseten/zai-org/GLM-5.3-Flash:high, openrouter/openai/gpt-6-astra:xhigh, openrouter/anthropic/claude-fable-5-1:high, openrouter/anthropic/claude-opus-5:high, openrouter/anthropic/claude-fable-5:high, openrouter/openai/gpt-5.6-sol:xhigh, openrouter/moonshotai/kimi-k3:max, openrouter/sakana/fugu-ultra:high, openrouter/openai/gpt-5.5:xhigh, openrouter/anthropic/claude-opus-4-8:high, openrouter/x-ai/grok-4.6:xhigh, openrouter/z-ai/glm-5.3:high, openrouter/z-ai/glm-5.3-flash:high
5
+ model: openai-codex/gpt-6-astra:medium
6
+ fallbackModels: github-copilot/gpt-6-astra:medium, openai/gpt-6-astra:medium, anthropic/claude-fable-5-1:medium, github-copilot/claude-fable-5-1:medium, anthropic/claude-opus-5:high, github-copilot/claude-opus-5:high, anthropic/claude-fable-5:medium, github-copilot/claude-fable-5:medium, openai-codex/gpt-5.6-sol:high, github-copilot/gpt-5.6-sol:high, openai/gpt-5.6-sol:high, kimi-coding/k3:max, moonshotai/kimi-k3:max, moonshotai-cn/kimi-k3:max, openai-codex/gpt-5.5:xhigh, github-copilot/gpt-5.5:xhigh, openai/gpt-5.5:xhigh, anthropic/claude-opus-4-8:high, github-copilot/claude-opus-4.8:high, xai/grok-4.6:xhigh, github-copilot/grok-4.6:xhigh, zai/glm-5.3:high, zai-coding-cn/glm-5.3:high, zai/glm-5.3-flash:high, zai-coding-cn/glm-5.3-flash:high, baseten/zai-org/GLM-5.3:high, baseten/zai-org/GLM-5.3-Flash:high, openrouter/openai/gpt-6-astra:medium, openrouter/anthropic/claude-fable-5-1:medium, openrouter/anthropic/claude-opus-5:high, openrouter/anthropic/claude-fable-5:medium, openrouter/openai/gpt-5.6-sol:high, openrouter/moonshotai/kimi-k3:max, openrouter/sakana/fugu-ultra:high, openrouter/openai/gpt-5.5:xhigh, openrouter/anthropic/claude-opus-4-8:high, openrouter/x-ai/grok-4.6:xhigh, openrouter/z-ai/glm-5.3:high, openrouter/z-ai/glm-5.3-flash:high
7
7
  skills: tdd, playwright-cli, tmux
8
8
  ---
9
9
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/subagents",
3
- "version": "0.9.19-alpha.3",
3
+ "version": "0.9.19-alpha.5",
4
4
  "private": true,
5
5
  "description": "Atomic extension for delegating tasks to subagents with parallel execution. Fork of: https://github.com/nicobailon/pi-subagents",
6
6
  "contributors": [