@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.
Files changed (197) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +15 -0
  3. package/dist/builtin/intercom/broker/broker.ts +8 -0
  4. package/dist/builtin/intercom/broker/client.ts +18 -0
  5. package/dist/builtin/intercom/broker/send-handler.ts +9 -0
  6. package/dist/builtin/intercom/index.bundle.mjs +161 -30
  7. package/dist/builtin/intercom/package.json +1 -1
  8. package/dist/builtin/intercom/types.ts +2 -1
  9. package/dist/builtin/mcp/package.json +1 -1
  10. package/dist/builtin/subagents/CHANGELOG.md +18 -0
  11. package/dist/builtin/subagents/README.md +14 -14
  12. package/dist/builtin/subagents/package.json +1 -1
  13. package/dist/builtin/subagents/skills/subagent/SKILL.md +14 -14
  14. package/dist/builtin/subagents/src/extension/index.bundle.mjs +142 -60
  15. package/dist/builtin/web-access/package.json +1 -1
  16. package/dist/builtin/workflows/CHANGELOG.md +33 -0
  17. package/dist/builtin/workflows/README.md +14 -15
  18. package/dist/builtin/workflows/builtin/{chunk-mygmtz6e.js → chunk-9k3ywfgd.js} +1 -1
  19. package/dist/builtin/workflows/builtin/{chunk-r9qq7xfj.js → chunk-ahbntmx2.js} +1 -1
  20. package/dist/builtin/workflows/builtin/{chunk-zggjyg5z.js → chunk-n8zysf1t.js} +1 -1
  21. package/dist/builtin/workflows/builtin/goal.js +2 -2
  22. package/dist/builtin/workflows/builtin/index.js +3 -3
  23. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  24. package/dist/builtin/workflows/package.json +5 -5
  25. package/dist/builtin/workflows/src/extension/index.bundle.mjs +171 -207
  26. package/dist/builtin/workflows/src/index.js +33 -6
  27. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -1
  28. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +1 -1
  29. package/dist/core/agent-session-auto-compaction.js +1 -1
  30. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  31. package/dist/core/agent-session-compaction.js +1 -1
  32. package/dist/core/agent-session-compaction.js.map +1 -1
  33. package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
  34. package/dist/core/agent-session-custom-message-commit.js +33 -2
  35. package/dist/core/agent-session-custom-message-commit.js.map +1 -1
  36. package/dist/core/agent-session-message-queue.d.ts +1 -1
  37. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  38. package/dist/core/agent-session-message-queue.js +22 -8
  39. package/dist/core/agent-session-message-queue.js.map +1 -1
  40. package/dist/core/agent-session-methods.d.ts +7 -1
  41. package/dist/core/agent-session-methods.d.ts.map +1 -1
  42. package/dist/core/agent-session-methods.js.map +1 -1
  43. package/dist/core/agent-session-persistent-custom-messages.d.ts +1 -1
  44. package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
  45. package/dist/core/agent-session-persistent-custom-messages.js +13 -3
  46. package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
  47. package/dist/core/agent-session-post-tool-compaction.js +1 -1
  48. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  49. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  50. package/dist/core/agent-session-prompt.js +83 -0
  51. package/dist/core/agent-session-prompt.js.map +1 -1
  52. package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
  53. package/dist/core/agent-session-queue-pause.js +11 -0
  54. package/dist/core/agent-session-queue-pause.js.map +1 -1
  55. package/dist/core/agent-session-tasks.d.ts +5 -0
  56. package/dist/core/agent-session-tasks.d.ts.map +1 -1
  57. package/dist/core/agent-session-tasks.js +8 -1
  58. package/dist/core/agent-session-tasks.js.map +1 -1
  59. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  60. package/dist/core/agent-session-tool-hooks.js +2 -0
  61. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  62. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  63. package/dist/core/agent-session-tool-registry.js +12 -0
  64. package/dist/core/agent-session-tool-registry.js.map +1 -1
  65. package/dist/core/agent-session-transfer.d.ts.map +1 -1
  66. package/dist/core/agent-session-transfer.js +7 -0
  67. package/dist/core/agent-session-transfer.js.map +1 -1
  68. package/dist/core/agent-session-types.d.ts +2 -0
  69. package/dist/core/agent-session-types.d.ts.map +1 -1
  70. package/dist/core/agent-session-types.js +2 -0
  71. package/dist/core/agent-session-types.js.map +1 -1
  72. package/dist/core/agent-session.d.ts +4 -0
  73. package/dist/core/agent-session.d.ts.map +1 -1
  74. package/dist/core/agent-session.js +22 -0
  75. package/dist/core/agent-session.js.map +1 -1
  76. package/dist/core/extensions/context-types.d.ts +6 -0
  77. package/dist/core/extensions/context-types.d.ts.map +1 -1
  78. package/dist/core/extensions/context-types.js.map +1 -1
  79. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  80. package/dist/core/extensions/loader-api.js +3 -0
  81. package/dist/core/extensions/loader-api.js.map +1 -1
  82. package/dist/core/extensions/loader-host-modules.d.ts +1 -1
  83. package/dist/core/extensions/loader-host-modules.d.ts.map +1 -1
  84. package/dist/core/extensions/loader-host-modules.js +2 -1
  85. package/dist/core/extensions/loader-host-modules.js.map +1 -1
  86. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  87. package/dist/core/extensions/loader-virtual-modules.js +4 -1
  88. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  89. package/dist/core/extensions/runner-context.d.ts +1 -1
  90. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  91. package/dist/core/extensions/runner-context.js +9 -3
  92. package/dist/core/extensions/runner-context.js.map +1 -1
  93. package/dist/core/extensions/runner.js +1 -1
  94. package/dist/core/extensions/runner.js.map +1 -1
  95. package/dist/core/extensions/workflow-events.d.ts +1 -1
  96. package/dist/core/extensions/workflow-events.d.ts.map +1 -1
  97. package/dist/core/extensions/workflow-events.js.map +1 -1
  98. package/dist/core/retry-policy.d.ts +1 -0
  99. package/dist/core/retry-policy.d.ts.map +1 -1
  100. package/dist/core/retry-policy.js +2 -1
  101. package/dist/core/retry-policy.js.map +1 -1
  102. package/dist/core/sdk-exports.d.ts +1 -1
  103. package/dist/core/sdk-exports.d.ts.map +1 -1
  104. package/dist/core/sdk-exports.js +1 -1
  105. package/dist/core/sdk-exports.js.map +1 -1
  106. package/dist/core/settings-manager-basic-accessors.d.ts +6 -3
  107. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  108. package/dist/core/settings-manager-basic-accessors.js +25 -8
  109. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  110. package/dist/core/settings-manager.d.ts +1 -1
  111. package/dist/core/settings-manager.d.ts.map +1 -1
  112. package/dist/core/settings-manager.js.map +1 -1
  113. package/dist/core/settings-types.d.ts +6 -0
  114. package/dist/core/settings-types.d.ts.map +1 -1
  115. package/dist/core/settings-types.js.map +1 -1
  116. package/dist/core/slash-commands.d.ts.map +1 -1
  117. package/dist/core/slash-commands.js +4 -5
  118. package/dist/core/slash-commands.js.map +1 -1
  119. package/dist/core/tasks/agent-adapter.d.ts +14 -2
  120. package/dist/core/tasks/agent-adapter.d.ts.map +1 -1
  121. package/dist/core/tasks/agent-adapter.js +45 -4
  122. package/dist/core/tasks/agent-adapter.js.map +1 -1
  123. package/dist/core/tasks/completion.d.ts.map +1 -1
  124. package/dist/core/tasks/completion.js +5 -1
  125. package/dist/core/tasks/completion.js.map +1 -1
  126. package/dist/core/tasks/pause.d.ts +4 -0
  127. package/dist/core/tasks/pause.d.ts.map +1 -0
  128. package/dist/core/tasks/pause.js +49 -0
  129. package/dist/core/tasks/pause.js.map +1 -0
  130. package/dist/core/tasks/supervisor.d.ts +3 -1
  131. package/dist/core/tasks/supervisor.d.ts.map +1 -1
  132. package/dist/core/tasks/supervisor.js +48 -22
  133. package/dist/core/tasks/supervisor.js.map +1 -1
  134. package/dist/core/tools/bash-pty-native.d.ts +16 -2
  135. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  136. package/dist/core/tools/bash-pty-native.js +82 -0
  137. package/dist/core/tools/bash-pty-native.js.map +1 -1
  138. package/dist/core/tools/bash.d.ts +15 -2
  139. package/dist/core/tools/bash.d.ts.map +1 -1
  140. package/dist/core/tools/bash.js +49 -4
  141. package/dist/core/tools/bash.js.map +1 -1
  142. package/dist/core/tools/index.d.ts +4 -1
  143. package/dist/core/tools/index.d.ts.map +1 -1
  144. package/dist/core/tools/index.js +12 -0
  145. package/dist/core/tools/index.js.map +1 -1
  146. package/dist/core/tools/kill.d.ts +17 -0
  147. package/dist/core/tools/kill.d.ts.map +1 -0
  148. package/dist/core/tools/kill.js +49 -0
  149. package/dist/core/tools/kill.js.map +1 -0
  150. package/dist/core/tools/powershell.d.ts +84 -28
  151. package/dist/core/tools/powershell.d.ts.map +1 -1
  152. package/dist/core/tools/powershell.js +11 -3
  153. package/dist/core/tools/powershell.js.map +1 -1
  154. package/dist/core/tools/resource-selectors.d.ts +1 -1
  155. package/dist/core/tools/resource-selectors.d.ts.map +1 -1
  156. package/dist/core/tools/resource-selectors.js +7 -4
  157. package/dist/core/tools/resource-selectors.js.map +1 -1
  158. package/dist/core/workflow-stage-admission.d.ts +14 -0
  159. package/dist/core/workflow-stage-admission.d.ts.map +1 -1
  160. package/dist/core/workflow-stage-admission.js +63 -3
  161. package/dist/core/workflow-stage-admission.js.map +1 -1
  162. package/dist/index.d.ts +2 -2
  163. package/dist/index.d.ts.map +1 -1
  164. package/dist/index.js +1 -1
  165. package/dist/index.js.map +1 -1
  166. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  167. package/dist/modes/interactive/components/chat-session-host.js +3 -2
  168. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  169. package/dist/modes/interactive/components/task-row.d.ts.map +1 -1
  170. package/dist/modes/interactive/components/task-row.js +8 -1
  171. package/dist/modes/interactive/components/task-row.js.map +1 -1
  172. package/docs/background-tasks.md +31 -2
  173. package/docs/compaction.md +20 -0
  174. package/docs/computer-use.md +390 -0
  175. package/docs/development.md +23 -74
  176. package/docs/docs.json +1 -0
  177. package/docs/extensions.md +15 -1
  178. package/docs/herdr.md +26 -77
  179. package/docs/index.md +1 -0
  180. package/docs/intercom.md +14 -2
  181. package/docs/models/evals.md +2 -0
  182. package/docs/models/model-selection.md +10 -7
  183. package/docs/quickstart.md +1 -1
  184. package/docs/sdk.md +11 -1
  185. package/docs/settings.md +24 -0
  186. package/docs/subagents.md +10 -6
  187. package/docs/tmux.md +2 -0
  188. package/docs/tools.md +11 -1
  189. package/docs/usage.md +1 -1
  190. package/docs/workflows/api-reference.md +5 -4
  191. package/docs/workflows/authoring.md +3 -3
  192. package/docs/workflows/operations.md +44 -33
  193. package/docs/workflows/reliable-design.md +3 -3
  194. package/docs/workflows/verification.md +99 -40
  195. package/docs/workflows.md +4 -2
  196. package/npm-shrinkwrap.json +59 -59
  197. package/package.json +3 -3
@@ -8495,7 +8495,7 @@ function resolveTempScopeId(options) {
8495
8495
  return "shared";
8496
8496
  }
8497
8497
  var MAX_PARALLEL_TASKS = 50;
8498
- var MAX_CONCURRENCY = 4;
8498
+ var MAX_CONCURRENCY = 3;
8499
8499
  var TEMP_ROOT_DIR = path6.join(os4.tmpdir(), `${APP_NAME2}-subagents-${resolveTempScopeId()}`);
8500
8500
  var TEMP_ARTIFACTS_DIR = path6.join(TEMP_ROOT_DIR, "artifacts");
8501
8501
  var SLASH_RESULT_TYPE = "subagent-slash-result";
@@ -8504,7 +8504,7 @@ var SLASH_SUBAGENT_STARTED_EVENT = "subagent:slash:started";
8504
8504
  var SLASH_SUBAGENT_RESPONSE_EVENT = "subagent:slash:response";
8505
8505
  var SLASH_SUBAGENT_UPDATE_EVENT = "subagent:slash:update";
8506
8506
  var SLASH_SUBAGENT_CANCEL_EVENT = "subagent:slash:cancel";
8507
- var SUBAGENT_ACTIONS = ["list", "get", "create", "update", "delete", "status", "interrupt", "wait"];
8507
+ var SUBAGENT_ACTIONS = ["list", "get", "create", "update", "delete", "status", "kill", "wait"];
8508
8508
  var DEFAULT_FORK_PREAMBLE = "You are a delegated subagent running from a fork of the parent session. " + "Treat the inherited conversation as reference-only context, not a live thread to continue. " + "Do not continue or answer prior messages as if they are waiting for a reply. " + "Your sole job is to execute the task below and return a focused result for that task using your tools.";
8509
8509
  function normalizeTopLevelParallelValue(value) {
8510
8510
  const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
@@ -8657,7 +8657,7 @@ function registerSubagentNotify(pi) {
8657
8657
  const agent = result.agent ?? "unknown";
8658
8658
  const summary = typeof result.summary === "string" ? result.summary : "";
8659
8659
  const interrupted = result.status === "interrupted" || result.state === "interrupted";
8660
- const status = interrupted ? "interrupted" : result.status === "ok" ? "completed" : result.status === "continued" ? "interrupted" : "failed";
8660
+ const status = result.status === "killed" || result.state === "killed" ? "killed" : interrupted ? "interrupted" : result.status === "ok" ? "completed" : result.status === "continued" ? "interrupted" : "failed";
8661
8661
  const taskInfo = result.taskIndex !== undefined && result.totalTasks !== undefined ? `(${result.taskIndex + 1}/${result.totalTasks})` : undefined;
8662
8662
  const sessionLine = result.shareUrl ? `Session: ${result.shareUrl}` : result.shareError ? `Session share error: ${result.shareError}` : result.sessionFile ? `Session file: ${result.sessionFile}` : undefined;
8663
8663
  const displaySummary = summary.trim() ? summary : "(no output)";
@@ -9913,7 +9913,7 @@ function formatControlNoticeMessage(event, childIntercomTarget) {
9913
9913
  "Hint: Inspect status, then nudge if the work seems stuck.",
9914
9914
  childIntercomTarget ? `Nudge: ${nudgeCommand}` : "Nudge: no child message route registered",
9915
9915
  `Status: subagent({ action: "status", id: "${runTarget}" })`,
9916
- `Interrupt: subagent({ action: "interrupt", id: "${runTarget}" })`
9916
+ `Kill: subagent({ action: "kill", id: "${runTarget}" })`
9917
9917
  ].filter((line) => Boolean(line)).join(`
9918
9918
  `);
9919
9919
  }
@@ -9925,7 +9925,7 @@ function formatControlNoticeMessage(event, childIntercomTarget) {
9925
9925
  "Hint: Inspect status first unless the run is clearly blocked.",
9926
9926
  childIntercomTarget ? `Nudge: ${nudgeCommand}` : "Nudge: no child message route registered",
9927
9927
  `Status: subagent({ action: "status", id: "${runTarget}" })`,
9928
- `Interrupt: subagent({ action: "interrupt", id: "${runTarget}" })`
9928
+ `Kill: subagent({ action: "kill", id: "${runTarget}" })`
9929
9929
  ].filter((line) => Boolean(line)).join(`
9930
9930
  `);
9931
9931
  }
@@ -10280,7 +10280,7 @@ var CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS = [
10280
10280
  var CHILD_FANOUT_BOUNDARY_INSTRUCTIONS = [
10281
10281
  "You are a child subagent with explicit fanout responsibility for this assigned task.",
10282
10282
  "The parent session owns final orchestration, completion decisions, and follow-up implementation launches.",
10283
- "Delegation is one level deep: the `subagent` tool refuses every launch and interrupt from inside a subagent.",
10283
+ "Delegation is one level deep: the `subagent` tool refuses every launch and kill from inside a subagent.",
10284
10284
  "Do the assigned fanout work yourself and report what you found; do not plan around delegating it.",
10285
10285
  "If you need to edit files, call the actual edit/write tools. Do not print tool-call syntax, patches, or pseudo-tool calls as text."
10286
10286
  ].join(`
@@ -10445,11 +10445,12 @@ var EMPTY_STATS = {
10445
10445
  var CAPACITY_RETRY_INITIAL_DELAY_MS = 5;
10446
10446
  var INTERRUPTED_ENVELOPE = "Interrupted";
10447
10447
  var CAPACITY_RETRY_MAX_DELAY_MS = 100;
10448
- function waitForExecutionCapacity(delayMs, signals) {
10449
- if (signals.interrupt.aborted)
10450
- return Promise.resolve("interrupt");
10451
- if (signals.abort.aborted)
10452
- return Promise.resolve("abort");
10448
+ function waitForExecutionCapacity(delayMs, signals, onSettled) {
10449
+ if (signals.interrupt.aborted || signals.abort.aborted) {
10450
+ const result = signals.interrupt.aborted ? "interrupt" : "abort";
10451
+ onSettled(result);
10452
+ return Promise.resolve(result);
10453
+ }
10453
10454
  return new Promise((resolveWait) => {
10454
10455
  let settled = false;
10455
10456
  let timer;
@@ -10460,6 +10461,7 @@ function waitForExecutionCapacity(delayMs, signals) {
10460
10461
  clearTimeout(timer);
10461
10462
  signals.abort.removeEventListener("abort", onAbort);
10462
10463
  signals.interrupt.removeEventListener("abort", onInterrupt);
10464
+ onSettled(result);
10463
10465
  resolveWait(result);
10464
10466
  };
10465
10467
  const onAbort = () => settle("abort");
@@ -10657,7 +10659,7 @@ function createTestSession(sessionManager, spec) {
10657
10659
  };
10658
10660
  }
10659
10661
  function nativeStatus(value) {
10660
- return value;
10662
+ return value === "killed" ? "interrupted" : value;
10661
10663
  }
10662
10664
  function nativeCause(value) {
10663
10665
  return value;
@@ -10814,6 +10816,7 @@ class SubagentControlRuntime {
10814
10816
  attemptTerminators = new Map;
10815
10817
  delivered = new Set;
10816
10818
  deliveredEnvelopes = new Map;
10819
+ killedChildren = new Set;
10817
10820
  nextAttemptId = 1;
10818
10821
  constructor(parent, sessionRoot) {
10819
10822
  this.parent = { ...parent };
@@ -10886,17 +10889,24 @@ class SubagentControlRuntime {
10886
10889
  guard = this.native.beginChildAttempt(admitted.identity.path);
10887
10890
  if (guard.token || guard.refusal?.kind !== "capacityExhausted")
10888
10891
  break;
10889
- const waitResult = await waitForExecutionCapacity(retryDelayMs, signals);
10892
+ let killed = false;
10893
+ const waitResult = await waitForExecutionCapacity(retryDelayMs, signals, (result) => {
10894
+ killed = this.killedChildren.has(admitted.identity.path) || result === PARENT_CANCEL_CAUSE && !!taskHooks && signals.abort.reason === "user";
10895
+ });
10890
10896
  if (waitResult !== "retry") {
10891
10897
  const stats = { ...EMPTY_STATS, sessionId: admitted.identity.path };
10892
10898
  if (waitResult === "interrupt" || waitResult === PARENT_CANCEL_CAUSE) {
10899
+ if (killed)
10900
+ this.killedChildren.add(admitted.identity.path);
10901
+ else
10902
+ this.killedChildren.delete(admitted.identity.path);
10893
10903
  this.native.publishChildStatus(admitted.identity.path, nativeStatus("interrupted"));
10894
10904
  return {
10895
- status: "interrupted",
10896
- ...waitResult === PARENT_CANCEL_CAUSE ? { cause: PARENT_CANCEL_CAUSE } : {},
10905
+ status: killed ? "killed" : "interrupted",
10906
+ ...waitResult === PARENT_CANCEL_CAUSE && !killed ? { cause: PARENT_CANCEL_CAUSE } : {},
10897
10907
  stats,
10898
10908
  path: admitted.identity.path,
10899
- envelope: waitResult === PARENT_CANCEL_CAUSE ? cancelledEnvelope(undefined, admitted.spec, stats) : INTERRUPTED_ENVELOPE,
10909
+ envelope: killed ? "Killed. This child cannot be resumed." : waitResult === PARENT_CANCEL_CAUSE ? cancelledEnvelope(undefined, admitted.spec, stats) : INTERRUPTED_ENVELOPE,
10900
10910
  ...effectiveModelId === undefined ? {} : { model: effectiveModelId },
10901
10911
  ...effectiveThinking === undefined ? {} : { thinking: effectiveThinking }
10902
10912
  };
@@ -10935,11 +10945,18 @@ class SubagentControlRuntime {
10935
10945
  let activeSessionManager;
10936
10946
  let termination;
10937
10947
  let terminating;
10948
+ let terminationWasKill = false;
10938
10949
  let unsubscribe;
10939
10950
  let skillReport = {};
10940
10951
  const terminate = async (cause) => {
10941
- if (terminating)
10952
+ if (terminating) {
10953
+ if (!terminationWasKill)
10954
+ this.killedChildren.delete(admitted.identity.path);
10942
10955
  return terminating;
10956
+ }
10957
+ if (taskHooks && cause === "abort" && signals.abort.reason === "user")
10958
+ this.killedChildren.add(admitted.identity.path);
10959
+ terminationWasKill = this.killedChildren.has(admitted.identity.path);
10943
10960
  termination = cause;
10944
10961
  terminating = (async () => {
10945
10962
  try {
@@ -11161,11 +11178,11 @@ class SubagentControlRuntime {
11161
11178
  };
11162
11179
  if (status === "interrupted")
11163
11180
  return {
11164
- status,
11165
- ...termination === PARENT_CANCEL_CAUSE ? { cause: PARENT_CANCEL_CAUSE } : {},
11181
+ status: this.killedChildren.has(admitted.identity.path) ? "killed" : status,
11182
+ ...termination === PARENT_CANCEL_CAUSE && !this.killedChildren.has(admitted.identity.path) ? { cause: PARENT_CANCEL_CAUSE } : {},
11166
11183
  stats,
11167
11184
  path: admitted.identity.path,
11168
- envelope,
11185
+ envelope: this.killedChildren.has(admitted.identity.path) ? "Killed. This child cannot be resumed." : envelope,
11169
11186
  sessionFile,
11170
11187
  ...effectiveModelId === undefined ? {} : { model: effectiveModelId },
11171
11188
  ...effectiveThinking === undefined ? {} : { thinking: effectiveThinking },
@@ -11194,11 +11211,11 @@ class SubagentControlRuntime {
11194
11211
  } catch {}
11195
11212
  if (status === "interrupted")
11196
11213
  return {
11197
- status,
11198
- ...termination === PARENT_CANCEL_CAUSE ? { cause: PARENT_CANCEL_CAUSE } : {},
11214
+ status: this.killedChildren.has(admitted.identity.path) ? "killed" : status,
11215
+ ...termination === PARENT_CANCEL_CAUSE && !this.killedChildren.has(admitted.identity.path) ? { cause: PARENT_CANCEL_CAUSE } : {},
11199
11216
  stats,
11200
11217
  path: admitted.identity.path,
11201
- envelope: termination === PARENT_CANCEL_CAUSE ? cancelledEnvelope(session, admitted.spec, stats) : INTERRUPTED_ENVELOPE,
11218
+ envelope: termination === PARENT_CANCEL_CAUSE && !this.killedChildren.has(admitted.identity.path) ? cancelledEnvelope(session, admitted.spec, stats) : this.killedChildren.has(admitted.identity.path) ? "Killed. This child cannot be resumed." : INTERRUPTED_ENVELOPE,
11202
11219
  sessionFile: session?.sessionFile,
11203
11220
  ...effectiveModelId === undefined ? {} : { model: effectiveModelId },
11204
11221
  ...effectiveThinking === undefined ? {} : { thinking: effectiveThinking },
@@ -11352,20 +11369,25 @@ class SubagentControlRuntime {
11352
11369
  return this.deliveredEnvelopes.get(pathValue);
11353
11370
  }
11354
11371
  findChild(pathValue) {
11355
- return this.native.listChildren().find((child) => child.path === pathValue);
11372
+ return this.listChildren().find((child) => child.path === pathValue);
11356
11373
  }
11357
11374
  listChildren() {
11358
- return this.native.listChildren();
11375
+ return this.native.listChildren().map((child) => ({
11376
+ ...child,
11377
+ status: child.status === "interrupted" && this.killedChildren.has(child.path) ? "killed" : child.status
11378
+ }));
11359
11379
  }
11360
- async interruptChild(pathValue) {
11380
+ async killChild(pathValue) {
11361
11381
  const running = [...this.runningAttempts.values()].find((attempt) => attempt.child.identity.path === pathValue && (attempt.status === "running" || attempt.status === "continued"));
11362
11382
  if (!running)
11363
11383
  return false;
11384
+ if (this.findChild(pathValue)?.status !== "interrupted")
11385
+ this.killedChildren.add(pathValue);
11364
11386
  await this.terminateChildAttempt(running, "interrupt");
11365
11387
  return true;
11366
11388
  }
11367
11389
  subscribe(pathValue, callback) {
11368
- this.native.subscribeChildStatus(pathValue, callback);
11390
+ this.native.subscribeChildStatus(pathValue, (status) => callback(status === "interrupted" && this.killedChildren.has(pathValue) ? "killed" : status));
11369
11391
  }
11370
11392
  async terminateRunningAttempt(running, cause) {
11371
11393
  const terminate = this.attemptTerminators.get(running.child.identity.path);
@@ -11475,16 +11497,21 @@ function inspectInProcessChildStatus(id) {
11475
11497
  details: { mode: "management", results: [], statusGroups: controls.map((control) => statusGroup(control)) }
11476
11498
  };
11477
11499
  }
11478
- async function interruptInProcessChild(id) {
11500
+ async function killInProcessChild(id) {
11479
11501
  const control = findSubagentControl(id);
11480
11502
  if (!control)
11481
11503
  return;
11482
11504
  const identities = canonicalChildren(control);
11483
11505
  const candidates = id === control.parent.path ? identities : identities.filter((child) => child.path === id);
11484
11506
  for (const child of candidates) {
11485
- if (await control.interruptChild(child.path)) {
11507
+ if (await control.killChild(child.path)) {
11486
11508
  return {
11487
- content: [{ type: "text", text: `Interrupt requested for in-process child ${child.path}.` }],
11509
+ content: [
11510
+ {
11511
+ type: "text",
11512
+ text: `Kill requested for in-process child ${child.path}. This child cannot be resumed.`
11513
+ }
11514
+ ],
11488
11515
  details: { mode: "management", results: [] }
11489
11516
  };
11490
11517
  }
@@ -13284,9 +13311,18 @@ function findDuplicateParallelOutputPath(input) {
13284
13311
  }
13285
13312
 
13286
13313
  // dist/builtin/subagents/src/runs/foreground/task-execution.ts
13314
+ function subagentTaskResultLabel(result) {
13315
+ return result.kind === "cancelled" && result.cause === "user" ? "killed (non-resumable)" : result.kind;
13316
+ }
13317
+ function subagentTaskResponseText(response) {
13318
+ const outcomes = response.kind === "parallel" ? response.slots.map((slot) => slot.outcome) : [response];
13319
+ const killed = outcomes.filter((outcome) => outcome.kind === "admitted" && outcome.observation.kind === "settled" && subagentTaskResultLabel(outcome.observation.result) === "killed (non-resumable)");
13320
+ return `${killed.length ? `${killed.length} killed. These children cannot be resumed. Underlying host response:
13321
+ ` : ""}${JSON.stringify(response)}`;
13322
+ }
13287
13323
  function taskToolResult(response, host) {
13288
13324
  return {
13289
- content: [{ type: "text", text: JSON.stringify(response) }],
13325
+ content: [{ type: "text", text: subagentTaskResponseText(response) }],
13290
13326
  details: {
13291
13327
  mode: "single",
13292
13328
  results: [],
@@ -13369,6 +13405,8 @@ async function runAgentTask(input) {
13369
13405
  byteCount: String(bytes.length),
13370
13406
  omittedRanges: []
13371
13407
  };
13408
+ if (child.status === "killed")
13409
+ return { kind: "cancelled", cause: "user", output };
13372
13410
  if (child.interrupted)
13373
13411
  return {
13374
13412
  kind: "cancelled",
@@ -13637,6 +13675,8 @@ import { isStaleExtensionContextError as isStaleExtensionContextError4 } from "@
13637
13675
  import { randomUUID as randomUUID4 } from "node:crypto";
13638
13676
  import { isStaleExtensionContextError as isStaleExtensionContextError3 } from "@bastani/atomic";
13639
13677
  function resolveSubagentResultStatus(input) {
13678
+ if (input.status === "killed" || input.state === "killed")
13679
+ return "killed";
13640
13680
  if (input.detached || input.status === "continued")
13641
13681
  return "detached";
13642
13682
  if (input.interrupted || input.status === "interrupted" || input.state === "interrupted")
@@ -13652,6 +13692,7 @@ function countStatuses(children) {
13652
13692
  completed: 0,
13653
13693
  failed: 0,
13654
13694
  interrupted: 0,
13695
+ killed: 0,
13655
13696
  detached: 0
13656
13697
  };
13657
13698
  for (const child of children) {
@@ -13663,6 +13704,7 @@ function formatStatusCounts(children) {
13663
13704
  let completed = 0;
13664
13705
  let failed = 0;
13665
13706
  let interrupted = 0;
13707
+ let killed = 0;
13666
13708
  let cancelled = 0;
13667
13709
  let detached = 0;
13668
13710
  for (const child of children) {
@@ -13675,6 +13717,8 @@ function formatStatusCounts(children) {
13675
13717
  failed += 1;
13676
13718
  else if (label === "interrupted")
13677
13719
  interrupted += 1;
13720
+ else if (label === "killed")
13721
+ killed += 1;
13678
13722
  else if (label === "detached")
13679
13723
  detached += 1;
13680
13724
  }
@@ -13683,6 +13727,7 @@ function formatStatusCounts(children) {
13683
13727
  failed ? `${failed} failed` : undefined,
13684
13728
  cancelled ? `${cancelled} cancelled` : undefined,
13685
13729
  interrupted ? `${interrupted} interrupted` : undefined,
13730
+ killed ? `${killed} killed (non-resumable)` : undefined,
13686
13731
  detached ? `${detached} detached` : undefined
13687
13732
  ].filter((part) => Boolean(part));
13688
13733
  return parts.length ? parts.join(", ") : "0 results";
@@ -13691,6 +13736,10 @@ function resolveGroupedStatus(children) {
13691
13736
  const counts = countStatuses(children);
13692
13737
  if (counts.failed > 0)
13693
13738
  return "failed";
13739
+ if (groupedParentCancelCause(children))
13740
+ return "interrupted";
13741
+ if (counts.killed > 0)
13742
+ return "killed";
13694
13743
  if (counts.interrupted > 0)
13695
13744
  return "interrupted";
13696
13745
  if (counts.completed > 0)
@@ -14242,7 +14291,7 @@ async function runParallelPath(data, deps) {
14242
14291
  };
14243
14292
  worktreeCleanupDeferred = detachedCleanup.defer(response.slots.flatMap(({ ordinal, outcome }) => outcome.kind === "admitted" && outcome.observation.kind === "yielded" ? [ordinal] : []));
14244
14293
  return {
14245
- content: [{ type: "text", text: JSON.stringify(response) }],
14294
+ content: [{ type: "text", text: subagentTaskResponseText(response) }],
14246
14295
  details: {
14247
14296
  mode: "parallel",
14248
14297
  results: [],
@@ -14261,7 +14310,7 @@ async function runParallelPath(data, deps) {
14261
14310
  if (result.artifactPaths)
14262
14311
  allArtifactPaths.push(result.artifactPaths);
14263
14312
  }
14264
- const interrupted = results.find((result) => result.interrupted && !isParentCancellation(result.cause));
14313
+ const interrupted = results.find((result) => result.status === "killed" || result.interrupted && !isParentCancellation(result.cause));
14265
14314
  const details = compactForegroundDetails({
14266
14315
  mode: "parallel",
14267
14316
  runId,
@@ -14275,7 +14324,7 @@ async function runParallelPath(data, deps) {
14275
14324
  content: [
14276
14325
  {
14277
14326
  type: "text",
14278
- text: `Parallel run ended after interrupt (${interrupted.agent}). Launch fresh subagents for any follow-up.`
14327
+ text: interrupted.status === "killed" ? `Parallel child killed (${interrupted.agent}). This child cannot be resumed. Launch fresh subagents for any follow-up.` : `Parallel run ended before completion (${interrupted.agent}). Launch fresh subagents for any follow-up.`
14279
14328
  }
14280
14329
  ],
14281
14330
  details
@@ -14549,7 +14598,7 @@ function workflowOrchestrationContext(options) {
14549
14598
  };
14550
14599
  }
14551
14600
  function progressFor(agent, task, outcome, startedAt) {
14552
- const status = outcome.status === "ok" ? "completed" : outcome.status === "interrupted" && isParentCancellation(outcome.cause) ? "interrupted" : "failed";
14601
+ const status = outcome.status === "ok" ? "completed" : outcome.status === "killed" ? "killed" : outcome.status === "interrupted" && isParentCancellation(outcome.cause) ? "interrupted" : "failed";
14553
14602
  return {
14554
14603
  index: 0,
14555
14604
  agent: agent.name,
@@ -14571,7 +14620,7 @@ function progressFor(agent, task, outcome, startedAt) {
14571
14620
  }
14572
14621
  function resultFromOutcome(agent, task, outcome, startedAt, artifactPaths) {
14573
14622
  const status = outcome.status;
14574
- const output = outcome.status === "ok" ? outcome.output : outcome.envelope;
14623
+ const output = outcome.status === "killed" ? "Killed. This child cannot be resumed." : outcome.status === "ok" ? outcome.output : outcome.envelope;
14575
14624
  const model = outcome.model;
14576
14625
  const thinking = outcome.thinking;
14577
14626
  const result = {
@@ -14581,7 +14630,7 @@ function resultFromOutcome(agent, task, outcome, startedAt, artifactPaths) {
14581
14630
  ...outcome.status === "error" ? { cause: outcome.cause, error: outcome.cause } : outcome.status === "interrupted" && isParentCancellation(outcome.cause) ? { cause: outcome.cause } : {},
14582
14631
  stats: outcome.stats,
14583
14632
  path: outcome.path,
14584
- envelope: outcome.envelope,
14633
+ envelope: outcome.status === "killed" ? output : outcome.envelope,
14585
14634
  interrupted: status === "interrupted" ? true : undefined,
14586
14635
  messages: [],
14587
14636
  usage: usageFromStats(outcome.stats),
@@ -15190,12 +15239,23 @@ async function runSinglePath(data, deps) {
15190
15239
  details
15191
15240
  };
15192
15241
  }
15242
+ if (r.status === "killed") {
15243
+ return {
15244
+ content: [
15245
+ {
15246
+ type: "text",
15247
+ text: `Killed (${params.agent}). This child cannot be resumed. Launch a fresh subagent for any follow-up.`
15248
+ }
15249
+ ],
15250
+ details
15251
+ };
15252
+ }
15193
15253
  if (r.interrupted) {
15194
15254
  return {
15195
15255
  content: [
15196
15256
  {
15197
15257
  type: "text",
15198
- text: `Run ended after interrupt (${params.agent}). Launch a fresh subagent for any follow-up.`
15258
+ text: `Run ended before completion (${params.agent}). Launch a fresh subagent for any follow-up.`
15199
15259
  }
15200
15260
  ],
15201
15261
  details
@@ -15256,7 +15316,13 @@ async function handleManagementRequest(input) {
15256
15316
  if (action === "wait") {
15257
15317
  const observed = ctx.getAgentTaskHost && params.id !== undefined ? await ctx.getAgentTaskHost().waitForTask(params.id, params.budgetMs) : { ok: false, error: { code: "UnknownTask", message: "Task not found in this owner" } };
15258
15318
  return {
15259
- content: [{ type: "text", text: JSON.stringify(observed.ok ? observed.value : observed.error) }],
15319
+ content: [
15320
+ {
15321
+ type: "text",
15322
+ text: `${observed.ok && observed.value.kind === "settled" && subagentTaskResultLabel(observed.value.result) === "killed (non-resumable)" ? `Killed. This child cannot be resumed. Underlying host observation:
15323
+ ` : ""}${JSON.stringify(observed.ok ? observed.value : observed.error)}`
15324
+ }
15325
+ ],
15260
15326
  details: {
15261
15327
  mode: "management",
15262
15328
  results: [],
@@ -15269,11 +15335,11 @@ async function handleManagementRequest(input) {
15269
15335
  };
15270
15336
  }
15271
15337
  const targetTaskId = paramsWithResolvedCwd.id ?? paramsWithResolvedCwd.runId;
15272
- if ((action === "status" || action === "interrupt") && ctx.getAgentTaskHost && targetTaskId) {
15338
+ if ((action === "status" || action === "kill") && ctx.getAgentTaskHost && targetTaskId) {
15273
15339
  const host = ctx.getAgentTaskHost();
15274
15340
  const taskId = targetTaskId;
15275
15341
  if (host.resolveTask(taskId).ok) {
15276
- if (action === "interrupt") {
15342
+ if (action === "kill") {
15277
15343
  const cancelled = await host.cancelTask(taskId, "user");
15278
15344
  if (!cancelled.ok)
15279
15345
  return {
@@ -15287,7 +15353,14 @@ async function handleManagementRequest(input) {
15287
15353
  const records = watched.value.snapshot.tasks.filter((task) => task.ref.taskId === taskId);
15288
15354
  watched.value.dispose();
15289
15355
  return {
15290
- content: [{ type: "text", text: JSON.stringify(records) }],
15356
+ content: [
15357
+ {
15358
+ type: "text",
15359
+ text: `${records.some((task) => task.execution.kind === "settled" && subagentTaskResultLabel(task.execution.result) === "killed (non-resumable)") ? `Killed. This child cannot be resumed. Underlying host records:
15360
+ ` : action === "kill" ? `Kill requested. This child cannot be resumed. Underlying host records:
15361
+ ` : ""}${JSON.stringify(records)}`
15362
+ }
15363
+ ],
15291
15364
  details: { mode: "management", results: [], taskRecords: records }
15292
15365
  };
15293
15366
  }
@@ -15317,10 +15390,10 @@ async function handleManagementRequest(input) {
15317
15390
  details: { mode: "management", results: [] }
15318
15391
  };
15319
15392
  }
15320
- if (action === "interrupt") {
15393
+ if (action === "kill") {
15321
15394
  const targetRunId = paramsWithResolvedCwd.runId ?? paramsWithResolvedCwd.id;
15322
15395
  if (targetRunId) {
15323
- const inProcess = await interruptInProcessChild(targetRunId);
15396
+ const inProcess = await killInProcessChild(targetRunId);
15324
15397
  if (inProcess)
15325
15398
  return inProcess;
15326
15399
  }
@@ -15328,7 +15401,7 @@ async function handleManagementRequest(input) {
15328
15401
  content: [
15329
15402
  {
15330
15403
  type: "text",
15331
- text: targetRunId ? `No running in-process child found for '${targetRunId}'.` : "No interrupt-capable child found."
15404
+ text: targetRunId ? `No running in-process child found for '${targetRunId}'.` : "No kill-capable child found."
15332
15405
  }
15333
15406
  ],
15334
15407
  isError: true,
@@ -16250,7 +16323,7 @@ function buildMultiProgressLabel(details, hasRunning) {
16250
16323
  const index = result.progress?.index ?? progressFromArray?.index ?? i;
16251
16324
  if (index < 0 || index >= totalCount)
16252
16325
  continue;
16253
- const status = result.progress?.status ?? (result.interrupted || result.status === "interrupted" ? "interrupted" : result.detached || result.status === "continued" ? "detached" : result.status === "ok" ? "completed" : "failed");
16326
+ const status = result.progress?.status ?? (result.status === "killed" ? "killed" : result.interrupted || result.status === "interrupted" ? "interrupted" : result.detached || result.status === "continued" ? "detached" : result.status === "ok" ? "completed" : "failed");
16254
16327
  statuses[index] = status;
16255
16328
  }
16256
16329
  const running = statuses.filter((status) => status === "running").length;
@@ -16393,6 +16466,8 @@ function resultStatusLine(result, output) {
16393
16466
  return result.detachedReason ? `Detached: ${result.detachedReason}` : "Detached";
16394
16467
  if (result.status === "continued")
16395
16468
  return "Continued";
16469
+ if (result.status === "killed")
16470
+ return "Killed (non-resumable)";
16396
16471
  if (isParentCancellation(result.cause) && (result.interrupted || result.status === "interrupted"))
16397
16472
  return "Cancelled";
16398
16473
  if (result.interrupted || result.status === "interrupted")
@@ -16410,7 +16485,7 @@ function resultGlyph(result, output, theme, running = result.progress?.status ==
16410
16485
  return theme.fg("accent", pulseGlyph(pulseFrame));
16411
16486
  if (result.detached || result.status === "continued")
16412
16487
  return theme.fg("warning", "■");
16413
- if (result.interrupted || result.status === "interrupted" || result.status === "skipped")
16488
+ if (result.status === "killed" || result.interrupted || result.status === "interrupted" || result.status === "skipped")
16414
16489
  return theme.fg("warning", "■");
16415
16490
  if (result.status === "error")
16416
16491
  return theme.fg("error", "✗");
@@ -16467,6 +16542,7 @@ function renderSingleCompact(d, r, theme, now, pulseFrame) {
16467
16542
  function renderMultiCompact(d, theme, now, pulseFrame) {
16468
16543
  const hasRunning = d.progress?.some((p) => p.status === "running") || d.results.some((r) => r.progress?.status === "running");
16469
16544
  const failed = d.results.some((r) => r.status === "error" && r.progress?.status !== "running");
16545
+ const hasKilled = d.results.some((r) => r.status === "killed" && r.progress?.status !== "running");
16470
16546
  const interruptedOrDetached = d.results.some((r) => (r.interrupted || r.detached || r.status === "interrupted" || r.status === "continued" || r.status === "skipped") && r.progress?.status !== "running");
16471
16547
  let totalSummary = d.progressSummary;
16472
16548
  if (!totalSummary) {
@@ -16486,8 +16562,12 @@ function renderMultiCompact(d, theme, now, pulseFrame) {
16486
16562
  }
16487
16563
  const multiLabel = buildMultiProgressLabel(d, hasRunning);
16488
16564
  const itemTitle = multiLabel.itemTitle;
16489
- const stats = statJoin(theme, [multiLabel.headerLabel, formatProgressStats(theme, totalSummary, true, now)]);
16490
- const glyph = hasRunning ? theme.fg("accent", pulseGlyph(pulseFrame)) : failed ? theme.fg("error", "✗") : interruptedOrDetached ? theme.fg("warning", "■") : theme.fg("success", "✓");
16565
+ const stats = statJoin(theme, [
16566
+ multiLabel.headerLabel,
16567
+ !hasRunning && hasKilled ? theme.fg("warning", "killed (non-resumable)") : "",
16568
+ formatProgressStats(theme, totalSummary, true, now)
16569
+ ]);
16570
+ const glyph = hasRunning ? theme.fg("accent", pulseGlyph(pulseFrame)) : failed ? theme.fg("error", "✗") : hasKilled || interruptedOrDetached ? theme.fg("warning", "■") : theme.fg("success", "✓");
16491
16571
  const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
16492
16572
  const c = new Container;
16493
16573
  const width = getTermWidth() - 4;
@@ -16629,6 +16709,7 @@ var statusStyles = {
16629
16709
  ok: { glyph: "✓", label: "Completed", color: "success" },
16630
16710
  error: { glyph: "✗", label: "Failed", color: "error" },
16631
16711
  interrupted: { glyph: "■", label: "Interrupted", color: "warning" },
16712
+ killed: { glyph: "■", label: "Killed (non-resumable)", color: "warning" },
16632
16713
  continued: { glyph: "■", label: "Continued", color: "warning" }
16633
16714
  };
16634
16715
  var displayText = (value) => stripTerminalSequences(value).replace(/[\x00-\x1f\x7f-\x9f]/g, " ");
@@ -16735,7 +16816,7 @@ function renderSubagentResult(result, options, theme) {
16735
16816
  if (!expanded)
16736
16817
  return appendParentAskOutput(renderSingleCompact(d, r, theme, options.now, options.pulseFrame), handoffOutput, theme);
16737
16818
  const isRunning = r.progress?.status === "running";
16738
- const icon = isRunning ? theme.fg("warning", "running") : d.parentAskYielded ? theme.fg("warning", "yielded") : r.detached || r.status === "continued" ? theme.fg("warning", "detached") : isParentCancellation(r.cause) && (r.interrupted || r.status === "interrupted") ? theme.fg("warning", "cancelled") : r.status === "ok" ? theme.fg("success", "ok") : theme.fg("error", "failed");
16819
+ const icon = isRunning ? theme.fg("warning", "running") : d.parentAskYielded ? theme.fg("warning", "yielded") : r.detached || r.status === "continued" ? theme.fg("warning", "detached") : r.status === "killed" ? theme.fg("warning", "killed (non-resumable)") : isParentCancellation(r.cause) && (r.interrupted || r.status === "interrupted") ? theme.fg("warning", "cancelled") : r.status === "ok" ? theme.fg("success", "ok") : theme.fg("error", "failed");
16739
16820
  const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
16740
16821
  const output = r.truncation?.text || getSingleResultOutput(r);
16741
16822
  const progressInfo = isRunning && r.progress ? ` | ${r.progress.toolCount} tools, ${formatTokens(r.progress.tokens)} tok, ${formatDuration(displayProgressDurationMs(r.progress, options.now))}` : r.progressSummary ? ` | ${r.progressSummary.toolCount} tools, ${formatTokens(r.progressSummary.tokens)} tok, ${formatDuration(r.progressSummary.durationMs)}` : "";
@@ -16815,7 +16896,8 @@ function renderSubagentResult(result, options, theme) {
16815
16896
  const ok = d.results.filter((r) => r.progress?.status === "completed" || r.status === "ok" && r.progress?.status !== "running").length;
16816
16897
  const hasEmptyWithoutTarget = d.results.some((r) => r.status === "ok" && r.progress?.status !== "running" && hasEmptyTextOutputWithoutOutputTarget(r.task, getSingleResultOutput(r)));
16817
16898
  const hasCancelled = d.results.some((result) => isParentCancellation(result.cause) && (result.interrupted || result.status === "interrupted"));
16818
- const icon = hasRunning ? theme.fg("warning", "running") : d.parentAskYielded ? theme.fg("warning", "yielded") : hasEmptyWithoutTarget ? theme.fg("warning", "warning") : ok === d.results.length ? theme.fg("success", "ok") : d.results.some((result) => result.status === "error") ? theme.fg("error", "failed") : hasCancelled ? theme.fg("warning", "cancelled") : theme.fg("error", "failed");
16899
+ const hasKilled = d.results.some((result) => result.status === "killed");
16900
+ const icon = hasRunning ? theme.fg("warning", "running") : d.parentAskYielded ? theme.fg("warning", "yielded") : hasKilled && !hasCancelled && !d.results.some((result) => result.status === "error") ? theme.fg("warning", "killed (non-resumable)") : hasEmptyWithoutTarget ? theme.fg("warning", "warning") : ok === d.results.length ? theme.fg("success", "ok") : d.results.some((result) => result.status === "error") ? theme.fg("error", "failed") : hasCancelled ? theme.fg("warning", "cancelled") : theme.fg("error", "failed");
16819
16901
  const totalSummary = d.progressSummary || d.results.reduce((acc, r) => {
16820
16902
  const prog = r.progress || r.progressSummary;
16821
16903
  if (prog) {
@@ -16882,7 +16964,7 @@ function renderSubagentResult(result, options, theme) {
16882
16964
  const rRunning = rProg?.status === "running";
16883
16965
  const stepNumber = typeof rProg?.index === "number" ? rProg.index + 1 : i + 1;
16884
16966
  const resultOutput = getSingleResultOutput(r);
16885
- const statusIcon = rRunning ? theme.fg("warning", "running") : r.status === "error" ? theme.fg("error", "failed") : isParentCancellation(r.cause) && (r.interrupted || r.status === "interrupted") ? theme.fg("warning", "cancelled") : r.status === "skipped" || r.status === "interrupted" || r.status === "continued" ? theme.fg("warning", r.status) : hasEmptyTextOutputWithoutOutputTarget(r.task, resultOutput) ? theme.fg("warning", "warning") : theme.fg("success", "done");
16967
+ const statusIcon = rRunning ? theme.fg("warning", "running") : r.status === "error" ? theme.fg("error", "failed") : isParentCancellation(r.cause) && (r.interrupted || r.status === "interrupted") ? theme.fg("warning", "cancelled") : r.status === "killed" || r.status === "skipped" || r.status === "interrupted" || r.status === "continued" ? theme.fg("warning", r.status) : hasEmptyTextOutputWithoutOutputTarget(r.task, resultOutput) ? theme.fg("warning", "warning") : theme.fg("success", "done");
16886
16968
  const stats = rProg ? ` | ${rProg.toolCount} tools, ${formatDuration(displayProgressDurationMs(rProg, options.now))}` : "";
16887
16969
  const modelDisplay = modelThinkingBadge(theme, r.model ?? rProg?.model, r.thinking ?? rProg?.thinking);
16888
16970
  const stepLabel = resultRowLabel(d, multiLabel, i, stepNumber);
@@ -16971,7 +17053,7 @@ function loadConfig() {
16971
17053
  }
16972
17054
 
16973
17055
  // dist/builtin/subagents/src/extension/notification-content.ts
16974
- var HEADER_STATUSES = ["completed", "failed", "interrupted"];
17056
+ var HEADER_STATUSES = ["completed", "failed", "interrupted", "killed"];
16975
17057
  function isHeaderLineTerminator(character) {
16976
17058
  return character === "\r" || character === "\u2028" || character === "\u2029";
16977
17059
  }
@@ -17161,9 +17243,9 @@ var SubagentParams = Type.Object({
17161
17243
  enum: [...SUBAGENT_ACTIONS],
17162
17244
  description: "Management/control action. Omit for execution mode."
17163
17245
  })),
17164
- id: Type.Optional(Type.String({ description: "Run id or prefix for action='status' or action='interrupt'." })),
17246
+ id: Type.Optional(Type.String({ description: "Run id or prefix for action='status' or action='kill'." })),
17165
17247
  runId: Type.Optional(Type.String({
17166
- description: "Target run ID for action='interrupt'. Defaults to the most recently active controllable run. Prefer id for new calls."
17248
+ description: "Target run ID for action='kill'. Prefer id for new calls."
17167
17249
  })),
17168
17250
  config: Type.Optional(Type.Unsafe({
17169
17251
  anyOf: [{ type: "object", additionalProperties: true }, { type: "string" }],
@@ -17175,7 +17257,7 @@ var SubagentParams = Type.Object({
17175
17257
  })),
17176
17258
  concurrency: Type.Optional(Type.Integer({
17177
17259
  minimum: 1,
17178
- description: "Top-level PARALLEL mode only: max concurrent tasks. Defaults to config.parallel.concurrency or 4."
17260
+ description: "Top-level PARALLEL mode only: max concurrent tasks. Defaults to config.parallel.concurrency or 3."
17179
17261
  })),
17180
17262
  group: Type.Optional(GroupSchema),
17181
17263
  worktree: Type.Optional(Type.Boolean({
@@ -17227,7 +17309,7 @@ MANAGEMENT (use action field, omit agent/task/tasks):
17227
17309
  • { action: "delete", agent: "code-analysis.custom-agent" }
17228
17310
  CONTROL:
17229
17311
  • { action: "status", id: "..." } - inspect an in-process run by id or prefix
17230
- • { action: "interrupt", id?: "..." } - soft-interrupt the current child turn; the child is terminal for continuation, so follow-up work starts a fresh launch`;
17312
+ • { action: "kill", id: "..." } - terminally stop the selected child; killed children cannot be resumed, so follow-up work starts a fresh launch`;
17231
17313
 
17232
17314
  // dist/builtin/subagents/src/extension/tool-rendering.ts
17233
17315
  import { keyHintIfBound as keyHintIfBound4 } from "@bastani/atomic";
@@ -17268,7 +17350,7 @@ function renderSubagentToolResult(result, options, theme, context) {
17268
17350
  return new Text4(theme.fg("error", `✗ ${displayText2(result.details.taskError)}`), 0, 0);
17269
17351
  if (result.details?.taskRecords && !result.details.taskResponse) {
17270
17352
  const lines = result.details.taskRecords.flatMap((task) => {
17271
- const state = task.execution.kind === "settled" ? task.execution.result.kind : task.execution.kind;
17353
+ const state = task.execution.kind === "settled" ? subagentTaskResultLabel(task.execution.result) : task.execution.kind;
17272
17354
  return [
17273
17355
  theme.bold(`${displayText2(task.agentName ?? "bash")} · ${state}`),
17274
17356
  ...task.kind === "agent" ? [
@@ -17294,7 +17376,7 @@ function renderSubagentToolResult(result, options, theme, context) {
17294
17376
  if (outcome.kind === "unstarted")
17295
17377
  return theme.fg("error", outcome.reason.kind === "rejected" ? `✗ ${index + 1}. Not started · ${displayText2(outcome.reason.error.message)}` : `○ ${index + 1}. Skipped`);
17296
17378
  const observation = outcome.observation;
17297
- const state = observation.kind === "yielded" ? request?.action === "wait" ? "Still running in background" : "Launched in background" : observation.result.kind === "completed" ? "Completed" : observation.result.kind === "failed" ? "Failed" : "Stopped";
17379
+ const state = observation.kind === "yielded" ? request?.action === "wait" ? "Still running in background" : "Launched in background" : observation.result.kind === "completed" ? "Completed" : observation.result.kind === "failed" ? "Failed" : subagentTaskResultLabel(observation.result) === "killed (non-resumable)" ? "Killed (non-resumable)" : "Stopped";
17298
17380
  const icon = observation.kind === "yielded" ? "∀" : observation.result.kind === "completed" ? "✓" : observation.result.kind === "failed" ? "✗" : "○";
17299
17381
  const color = observation.kind === "yielded" ? "accent" : observation.result.kind === "failed" ? "error" : observation.result.kind === "completed" ? "success" : "warning";
17300
17382
  const identity = labels[index];
@@ -17572,7 +17654,7 @@ function renderSubagentNotification(message, options, theme) {
17572
17654
  const details = message.details ?? parseSubagentNotifyContent(content);
17573
17655
  if (!details)
17574
17656
  return new Text5(content, 0, 0);
17575
- const icon = details.status === "completed" ? theme.fg("success", "✓") : details.status === "interrupted" ? theme.fg("warning", "■") : theme.fg("error", "✗");
17657
+ const icon = details.status === "completed" ? theme.fg("success", "✓") : details.status === "interrupted" || details.status === "killed" ? theme.fg("warning", "■") : theme.fg("error", "✗");
17576
17658
  const parts = [];
17577
17659
  if (details.taskInfo)
17578
17660
  parts.push(details.taskInfo);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/web-access",
3
- "version": "0.9.19-alpha.2",
3
+ "version": "0.9.19-alpha.4",
4
4
  "private": true,
5
5
  "description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
6
6
  "contributors": [