@bastani/atomic 0.9.13-alpha.2 → 0.9.13-alpha.3

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 (255) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -1
  3. package/dist/builtin/i-have-adhd/package.json +1 -1
  4. package/dist/builtin/intercom/CHANGELOG.md +14 -0
  5. package/dist/builtin/intercom/README.md +12 -12
  6. package/dist/builtin/intercom/incoming-message-delivery.ts +1 -1
  7. package/dist/builtin/intercom/index.ts +1 -1
  8. package/dist/builtin/intercom/intercom-tool.ts +1 -1
  9. package/dist/builtin/intercom/intercom-utils.ts +3 -6
  10. package/dist/builtin/intercom/package.json +1 -1
  11. package/dist/builtin/intercom/result-renderers.ts +1 -1
  12. package/dist/builtin/intercom/session-target.ts +1 -15
  13. package/dist/builtin/intercom/skills/intercom/SKILL.md +6 -6
  14. package/dist/builtin/intercom/terminal-ordering-barrier.ts +2 -2
  15. package/dist/builtin/intercom/ui/inline-message.ts +7 -5
  16. package/dist/builtin/intercom/ui/session-list.ts +23 -10
  17. package/dist/builtin/mcp/package.json +1 -1
  18. package/dist/builtin/subagents/CHANGELOG.md +19 -0
  19. package/dist/builtin/subagents/README.md +29 -73
  20. package/dist/builtin/subagents/package.json +2 -2
  21. package/dist/builtin/subagents/prompts/parallel-cleanup.md +1 -1
  22. package/dist/builtin/subagents/prompts/parallel-review.md +1 -1
  23. package/dist/builtin/subagents/prompts/review-loop.md +2 -2
  24. package/dist/builtin/subagents/skills/subagent/SKILL.md +23 -59
  25. package/dist/builtin/subagents/skills/tmux/SKILL.md +1 -1
  26. package/dist/builtin/subagents/src/extension/control-notices.ts +2 -3
  27. package/dist/builtin/subagents/src/extension/doctor.ts +2 -14
  28. package/dist/builtin/subagents/src/extension/fanout-child.ts +1 -17
  29. package/dist/builtin/subagents/src/extension/index.ts +9 -70
  30. package/dist/builtin/subagents/src/extension/notification-content.ts +1 -1
  31. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +2 -2
  32. package/dist/builtin/subagents/src/extension/schemas.ts +2 -8
  33. package/dist/builtin/subagents/src/extension/tool-description.ts +2 -3
  34. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +1 -1
  35. package/dist/builtin/subagents/src/intercom/result-intercom.ts +5 -46
  36. package/dist/builtin/subagents/src/runs/{background → foreground}/completion-notification.ts +2 -2
  37. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +25 -88
  38. package/dist/builtin/subagents/src/runs/{background → foreground}/notify.ts +5 -5
  39. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +11 -28
  40. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +3 -0
  41. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +2 -0
  42. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +0 -5
  43. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +30 -20
  44. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +4 -4
  45. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +0 -13
  46. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +104 -48
  47. package/dist/builtin/subagents/src/runs/inprocess/index.ts +1 -1
  48. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +5 -5
  49. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-api.ts +0 -7
  50. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-core.ts +0 -10
  51. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-projection.ts +3 -108
  52. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-sanitize.ts +0 -4
  53. package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +1 -1
  54. package/dist/builtin/subagents/src/shared/formatters.ts +3 -5
  55. package/dist/builtin/subagents/src/shared/model-resolution.ts +78 -0
  56. package/dist/builtin/subagents/src/shared/status-format.ts +4 -11
  57. package/dist/builtin/subagents/src/shared/types-config.ts +10 -9
  58. package/dist/builtin/subagents/src/shared/types-nested.ts +127 -0
  59. package/dist/builtin/subagents/src/shared/types-results.ts +2 -8
  60. package/dist/builtin/subagents/src/shared/types-runtime.ts +0 -9
  61. package/dist/builtin/subagents/src/shared/types.ts +1 -1
  62. package/dist/builtin/subagents/src/shared/utils.ts +1 -109
  63. package/dist/builtin/subagents/src/slash/slash-commands.ts +7 -17
  64. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -252
  65. package/dist/builtin/subagents/src/tui/render-layout.ts +4 -4
  66. package/dist/builtin/subagents/src/tui/render-result.ts +0 -9
  67. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -34
  68. package/dist/builtin/subagents/src/tui/render.ts +0 -2
  69. package/dist/builtin/web-access/package.json +1 -1
  70. package/dist/builtin/workflows/CHANGELOG.md +12 -0
  71. package/dist/builtin/workflows/README.md +3 -3
  72. package/dist/builtin/workflows/package.json +1 -1
  73. package/dist/builtin/workflows/src/durable/backend.ts +11 -0
  74. package/dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts +63 -25
  75. package/dist/builtin/workflows/src/durable/completed-catalog.ts +166 -25
  76. package/dist/builtin/workflows/src/durable/dbos-backend.ts +42 -24
  77. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +2 -1
  78. package/dist/builtin/workflows/src/durable/run-timing.ts +28 -7
  79. package/dist/builtin/workflows/src/durable/scoped-backend.ts +4 -0
  80. package/dist/builtin/workflows/src/durable/targeted-inspection.ts +110 -0
  81. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +2 -2
  82. package/dist/builtin/workflows/src/engine/runtime.ts +19 -2
  83. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +3 -0
  84. package/dist/builtin/workflows/src/extension/index.bundle.mjs +680 -152
  85. package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +6 -0
  86. package/dist/builtin/workflows/src/extension/ui-surface.ts +2 -0
  87. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +6 -1
  88. package/dist/builtin/workflows/src/extension/workflow-targets.ts +18 -10
  89. package/dist/builtin/workflows/src/extension/workflow-tool-inspection.ts +31 -16
  90. package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +75 -3
  91. package/dist/builtin/workflows/src/extension/workflow-tool.ts +53 -6
  92. package/dist/builtin/workflows/src/runs/background/run-inspect.ts +5 -1
  93. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +94 -60
  94. package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +1 -1
  95. package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +7 -7
  96. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +25 -4
  97. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +4 -1
  98. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +2 -0
  99. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +142 -4
  100. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +2 -0
  101. package/dist/builtin/workflows/src/runs/foreground/stage-session-heartbeat.ts +88 -0
  102. package/dist/builtin/workflows/src/tui/run-detail.ts +25 -12
  103. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +1 -0
  104. package/dist/core/agent-session-events.d.ts.map +1 -1
  105. package/dist/core/agent-session-events.js +16 -5
  106. package/dist/core/agent-session-events.js.map +1 -1
  107. package/dist/core/agent-session-export.d.ts.map +1 -1
  108. package/dist/core/agent-session-export.js +2 -1
  109. package/dist/core/agent-session-export.js.map +1 -1
  110. package/dist/core/agent-session-methods.d.ts +8 -4
  111. package/dist/core/agent-session-methods.d.ts.map +1 -1
  112. package/dist/core/agent-session-methods.js.map +1 -1
  113. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  114. package/dist/core/agent-session-prompt.js +5 -0
  115. package/dist/core/agent-session-prompt.js.map +1 -1
  116. package/dist/core/agent-session-summary.d.ts +21 -0
  117. package/dist/core/agent-session-summary.d.ts.map +1 -0
  118. package/dist/core/agent-session-summary.js +156 -0
  119. package/dist/core/agent-session-summary.js.map +1 -0
  120. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  121. package/dist/core/agent-session-tool-registry.js +0 -4
  122. package/dist/core/agent-session-tool-registry.js.map +1 -1
  123. package/dist/core/agent-session-transfer.d.ts.map +1 -1
  124. package/dist/core/agent-session-transfer.js +0 -2
  125. package/dist/core/agent-session-transfer.js.map +1 -1
  126. package/dist/core/agent-session-tree.d.ts.map +1 -1
  127. package/dist/core/agent-session-tree.js +6 -0
  128. package/dist/core/agent-session-tree.js.map +1 -1
  129. package/dist/core/agent-session.d.ts +7 -3
  130. package/dist/core/agent-session.d.ts.map +1 -1
  131. package/dist/core/agent-session.js +8 -5
  132. package/dist/core/agent-session.js.map +1 -1
  133. package/dist/core/atomic-guide-command.js +2 -2
  134. package/dist/core/atomic-guide-command.js.map +1 -1
  135. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  136. package/dist/core/compaction/branch-summarization.js +1 -0
  137. package/dist/core/compaction/branch-summarization.js.map +1 -1
  138. package/dist/core/compaction/index.d.ts +1 -0
  139. package/dist/core/compaction/index.d.ts.map +1 -1
  140. package/dist/core/compaction/index.js +1 -0
  141. package/dist/core/compaction/index.js.map +1 -1
  142. package/dist/core/compaction/session-summarization.d.ts +41 -0
  143. package/dist/core/compaction/session-summarization.d.ts.map +1 -0
  144. package/dist/core/compaction/session-summarization.js +97 -0
  145. package/dist/core/compaction/session-summarization.js.map +1 -0
  146. package/dist/core/extensions/ui-types.d.ts +2 -0
  147. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  148. package/dist/core/extensions/ui-types.js.map +1 -1
  149. package/dist/core/session-manager-core.d.ts +3 -1
  150. package/dist/core/session-manager-core.d.ts.map +1 -1
  151. package/dist/core/session-manager-core.js +9 -1
  152. package/dist/core/session-manager-core.js.map +1 -1
  153. package/dist/core/session-manager-entries.d.ts +24 -1
  154. package/dist/core/session-manager-entries.d.ts.map +1 -1
  155. package/dist/core/session-manager-entries.js +48 -0
  156. package/dist/core/session-manager-entries.js.map +1 -1
  157. package/dist/core/session-manager-list.d.ts.map +1 -1
  158. package/dist/core/session-manager-list.js +10 -0
  159. package/dist/core/session-manager-list.js.map +1 -1
  160. package/dist/core/session-manager-types.d.ts +10 -1
  161. package/dist/core/session-manager-types.d.ts.map +1 -1
  162. package/dist/core/session-manager-types.js.map +1 -1
  163. package/dist/core/settings-manager-basic-accessors.d.ts +3 -0
  164. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  165. package/dist/core/settings-manager-basic-accessors.js +5 -0
  166. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  167. package/dist/core/settings-manager.d.ts +1 -1
  168. package/dist/core/settings-manager.d.ts.map +1 -1
  169. package/dist/core/settings-manager.js.map +1 -1
  170. package/dist/core/settings-types.d.ts +4 -0
  171. package/dist/core/settings-types.d.ts.map +1 -1
  172. package/dist/core/settings-types.js.map +1 -1
  173. package/dist/core/slash-commands.js +2 -2
  174. package/dist/core/slash-commands.js.map +1 -1
  175. package/dist/core/tools/bash.d.ts +0 -15
  176. package/dist/core/tools/bash.d.ts.map +1 -1
  177. package/dist/core/tools/bash.js +3 -81
  178. package/dist/core/tools/bash.js.map +1 -1
  179. package/dist/core/tools/fetch-url.d.ts +12 -0
  180. package/dist/core/tools/fetch-url.d.ts.map +1 -1
  181. package/dist/core/tools/fetch-url.js +76 -10
  182. package/dist/core/tools/fetch-url.js.map +1 -1
  183. package/dist/core/tools/index.js +4 -4
  184. package/dist/core/tools/index.js.map +1 -1
  185. package/dist/core/tools/session-temp-dir.d.ts +2 -2
  186. package/dist/core/tools/session-temp-dir.d.ts.map +1 -1
  187. package/dist/core/tools/session-temp-dir.js +6 -7
  188. package/dist/core/tools/session-temp-dir.js.map +1 -1
  189. package/dist/core/usage-totals.js +1 -1
  190. package/dist/core/usage-totals.js.map +1 -1
  191. package/dist/modes/interactive/components/footer.js +1 -1
  192. package/dist/modes/interactive/components/footer.js.map +1 -1
  193. package/dist/modes/interactive/components/host-session-picker.d.ts.map +1 -1
  194. package/dist/modes/interactive/components/host-session-picker.js +1 -0
  195. package/dist/modes/interactive/components/host-session-picker.js.map +1 -1
  196. package/dist/modes/interactive/components/session-selector-list.d.ts.map +1 -1
  197. package/dist/modes/interactive/components/session-selector-list.js +29 -4
  198. package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
  199. package/dist/modes/interactive/components/session-selector-search.js +1 -1
  200. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  201. package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/tree-selector-content.js +6 -0
  203. package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
  204. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  205. package/dist/modes/interactive-engine/protocol.js +4 -1
  206. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  207. package/docs/environment-variables.md +1 -1
  208. package/docs/intercom.md +20 -21
  209. package/docs/quickstart.md +5 -1
  210. package/docs/sdk.md +1 -1
  211. package/docs/session-format.md +15 -0
  212. package/docs/sessions.md +8 -0
  213. package/docs/settings.md +6 -0
  214. package/docs/subagents.md +19 -31
  215. package/docs/tools.md +3 -5
  216. package/docs/usage.md +1 -1
  217. package/docs/windows.md +1 -1
  218. package/docs/workflows.md +60 -32
  219. package/npm-shrinkwrap.json +29 -29
  220. package/package.json +2 -2
  221. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +0 -331
  222. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +0 -161
  223. package/dist/builtin/subagents/src/runs/inprocess/background-single.ts +0 -195
  224. package/dist/builtin/subagents/src/runs/inprocess/background.ts +0 -90
  225. package/dist/builtin/subagents/src/shared/types-async.ts +0 -247
  226. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +0 -217
  227. package/dist/builtin/subagents/src/tui/render-widget.ts +0 -366
  228. package/dist/core/async/format.d.ts +0 -3
  229. package/dist/core/async/format.d.ts.map +0 -1
  230. package/dist/core/async/format.js +0 -52
  231. package/dist/core/async/format.js.map +0 -1
  232. package/dist/core/async/job-manager.d.ts +0 -40
  233. package/dist/core/async/job-manager.d.ts.map +0 -1
  234. package/dist/core/async/job-manager.js +0 -293
  235. package/dist/core/async/job-manager.js.map +0 -1
  236. package/dist/core/async/session-manager.d.ts +0 -16
  237. package/dist/core/async/session-manager.d.ts.map +0 -1
  238. package/dist/core/async/session-manager.js +0 -34
  239. package/dist/core/async/session-manager.js.map +0 -1
  240. package/dist/core/async/types.d.ts +0 -23
  241. package/dist/core/async/types.d.ts.map +0 -1
  242. package/dist/core/async/types.js +0 -2
  243. package/dist/core/async/types.js.map +0 -1
  244. package/dist/core/tools/bash-async-execution.d.ts +0 -27
  245. package/dist/core/tools/bash-async-execution.d.ts.map +0 -1
  246. package/dist/core/tools/bash-async-execution.js +0 -81
  247. package/dist/core/tools/bash-async-execution.js.map +0 -1
  248. package/dist/core/tools/bash-async-jobs.d.ts +0 -30
  249. package/dist/core/tools/bash-async-jobs.d.ts.map +0 -1
  250. package/dist/core/tools/bash-async-jobs.js +0 -87
  251. package/dist/core/tools/bash-async-jobs.js.map +0 -1
  252. package/dist/core/tools/bash-async-output.d.ts +0 -13
  253. package/dist/core/tools/bash-async-output.d.ts.map +0 -1
  254. package/dist/core/tools/bash-async-output.js +0 -122
  255. package/dist/core/tools/bash-async-output.js.map +0 -1
@@ -3,17 +3,13 @@ import * as path from "node:path";
3
3
  import { type AgentSource, discoverAgentsAll } from "../agents/agents.ts";
4
4
  import { discoverAvailableSkills, type SkillSource } from "../agents/skills.ts";
5
5
  import { diagnoseIntercomBridge, type IntercomBridgeDiagnostic } from "../intercom/intercom-bridge.ts";
6
- import { isAsyncAvailable } from "../runs/inprocess/background.ts";
7
- import { ASYNC_DIR, type ExtensionConfig, RESULTS_DIR, type SubagentState, TEMP_ROOT_DIR } from "../shared/types.ts";
6
+ import { type ExtensionConfig, type SubagentState, TEMP_ROOT_DIR } from "../shared/types.ts";
8
7
 
9
8
  interface DoctorPaths {
10
9
  tempRootDir: string;
11
- asyncDir: string;
12
- resultsDir: string;
13
10
  }
14
11
 
15
12
  interface DoctorDeps {
16
- isAsyncAvailable: () => boolean;
17
13
  discoverAgentsAll: typeof discoverAgentsAll;
18
14
  discoverAvailableSkills: typeof discoverAvailableSkills;
19
15
  diagnoseIntercomBridge: typeof diagnoseIntercomBridge;
@@ -34,14 +30,9 @@ interface DoctorReportInput {
34
30
  deps?: Partial<DoctorDeps>;
35
31
  }
36
32
 
37
- const DEFAULT_PATHS: DoctorPaths = {
38
- tempRootDir: TEMP_ROOT_DIR,
39
- asyncDir: ASYNC_DIR,
40
- resultsDir: RESULTS_DIR,
41
- };
33
+ const DEFAULT_PATHS: DoctorPaths = { tempRootDir: TEMP_ROOT_DIR };
42
34
 
43
35
  const DEFAULT_DEPS: DoctorDeps = {
44
- isAsyncAvailable,
45
36
  discoverAgentsAll,
46
37
  discoverAvailableSkills,
47
38
  diagnoseIntercomBridge,
@@ -162,13 +153,10 @@ export function buildDoctorReport(input: DoctorReportInput): string {
162
153
  "",
163
154
  "Runtime",
164
155
  `- cwd: ${input.cwd}`,
165
- lineFromCheck("async support", () => `- async support: ${deps.isAsyncAvailable() ? "available" : "unavailable"}`),
166
156
  ...formatSessionLines(input),
167
157
  "",
168
158
  "Filesystem",
169
159
  formatExistingDirectory("temp root", paths.tempRootDir),
170
- formatExistingDirectory("async runs", paths.asyncDir),
171
- formatExistingDirectory("results", paths.resultsDir),
172
160
  "",
173
161
  "Discovery",
174
162
  ...formatDiscovery(input, deps),
@@ -39,23 +39,12 @@ export function createChildSafeState(): SubagentState {
39
39
  return {
40
40
  baseCwd: "",
41
41
  currentSessionId: null,
42
- asyncJobs: new Map(),
43
42
  subagentInProgress: false,
44
43
  foregroundRuns: new Map(),
45
44
  foregroundControls: new Map(),
46
45
  lastForegroundControlId: null,
47
46
  pendingForegroundControlNotices: new Map(),
48
- cleanupTimers: new Map(),
49
47
  lastUiContext: null,
50
- poller: null,
51
- completionSeen: new Map(),
52
- watcher: null,
53
- watcherRestartTimer: null,
54
- // Child-safe stub: the parent extension owns watcher/coalescer/cleanup state.
55
- resultFileCoalescer: {
56
- schedule: () => false,
57
- clear: () => {},
58
- },
59
48
  };
60
49
  }
61
50
 
@@ -231,16 +220,10 @@ export default function registerFanoutChildSubagentExtension(pi: ExtensionAPI, c
231
220
  const config = loadConfig();
232
221
  const state = createChildSafeState();
233
222
  let nestedListenerCleanup: (() => void) | undefined;
234
- lifecycle.setCleanup(() => {
235
- nestedListenerCleanup?.();
236
- for (const timer of state.cleanupTimers.values()) clearInterval(timer);
237
- state.cleanupTimers.clear();
238
- });
239
223
  const executor = createSubagentExecutor({
240
224
  pi,
241
225
  state,
242
226
  config,
243
- asyncByDefault: config.asyncByDefault === true,
244
227
  tempArtifactsDir: getArtifactsDir(null),
245
228
  getSubagentSessionRoot,
246
229
  expandTilde,
@@ -248,6 +231,7 @@ export default function registerFanoutChildSubagentExtension(pi: ExtensionAPI, c
248
231
  childPolicy,
249
232
  allowMutatingManagementActions: childPolicy ? childPolicy.managementActions === "full" : false,
250
233
  });
234
+ lifecycle.setCleanup(() => nestedListenerCleanup?.());
251
235
 
252
236
  const tool: ToolDefinition<typeof SubagentParams, Details> = {
253
237
  name: "subagent",
@@ -1,4 +1,4 @@
1
- /** Subagent Tool: sync/async orchestration extension. */
1
+ /** Subagent Tool: foreground orchestration extension. */
2
2
  import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
@@ -21,8 +21,7 @@ import {
21
21
  wrapTextWithAnsi,
22
22
  } from "@earendil-works/pi-tui";
23
23
  import { discoverAgents } from "../agents/agents.ts";
24
- import { createAsyncJobTracker } from "../runs/background/async-job-tracker.ts";
25
- import registerSubagentNotify, { type SubagentNotifyDetails } from "../runs/background/notify.ts";
24
+ import registerSubagentNotify, { type SubagentNotifyDetails } from "../runs/foreground/notify.ts";
26
25
  import { createSubagentExecutor, type SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
27
26
  import { getArtifactsDir } from "../shared/artifacts.ts";
28
27
  import { formatDuration, shortenPath } from "../shared/formatters.ts";
@@ -43,7 +42,6 @@ import {
43
42
  renderSubagentResult,
44
43
  type SubagentResultRenderState,
45
44
  stopResultAnimations,
46
- stopWidgetAnimation,
47
45
  } from "../tui/render.ts";
48
46
  import { loadConfig } from "./config.ts";
49
47
  import { parseSubagentNotifyContent } from "./notification-content.ts";
@@ -62,12 +60,9 @@ export {
62
60
  export { SUBAGENT_TOOL_DESCRIPTION } from "./tool-description.ts";
63
61
 
64
62
  import {
65
- ASYNC_DIR,
66
63
  DEFAULT_ARTIFACT_CONFIG,
67
64
  type Details,
68
65
  SLASH_RESULT_TYPE,
69
- SUBAGENT_ASYNC_COMPLETE_EVENT,
70
- SUBAGENT_ASYNC_STARTED_EVENT,
71
66
  SUBAGENT_CONTROL_EVENT,
72
67
  type SubagentState,
73
68
  } from "../shared/types.ts";
@@ -218,40 +213,26 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
218
213
  let runtimeCleanupInstalled = false;
219
214
  try {
220
215
  const config = loadConfig();
221
- const asyncByDefault = config.asyncByDefault === true;
222
216
  const tempArtifactsDir = getArtifactsDir(null);
223
217
  const state: SubagentState = {
224
218
  baseCwd: "",
225
219
  currentSessionId: null,
226
- asyncJobs: new Map(),
227
220
  subagentInProgress: false,
228
221
  foregroundRuns: new Map(),
229
222
  foregroundControls: new Map(),
230
223
  lastForegroundControlId: null,
231
224
  pendingForegroundControlNotices: new Map(),
232
- cleanupTimers: new Map(),
233
225
  lastUiContext: null,
234
- poller: null,
235
- completionSeen: new Map(),
236
- watcher: null,
237
- watcherRestartTimer: null,
238
- resultFileCoalescer: {
239
- schedule: () => false,
240
- clear: () => {},
241
- },
242
226
  };
243
227
  const maintenance = createSubagentStartupMaintenance(state, {
244
228
  artifactCleanupDays: DEFAULT_ARTIFACT_CONFIG.cleanupDays,
245
229
  });
246
230
  maintenance.scheduleStartupCleanup();
247
231
  registrationFailureCleanups.push(() => maintenance.stop());
248
- const { ensurePoller, handleStarted, handleComplete, resetJobs, hydrateActiveJobsDeferred } =
249
- createAsyncJobTracker(pi, state, ASYNC_DIR);
250
232
  const executorDeps = {
251
233
  pi,
252
234
  state,
253
235
  config,
254
- asyncByDefault,
255
236
  tempArtifactsDir,
256
237
  getSubagentSessionRoot,
257
238
  expandTilde,
@@ -320,13 +301,7 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
320
301
  if (request.tasks && request.tasks.length > 0) {
321
302
  return executeSubagentCollapsed(
322
303
  requestId,
323
- {
324
- tasks: request.tasks,
325
- context: request.context,
326
- cwd: request.cwd,
327
- worktree: request.worktree,
328
- async: false,
329
- },
304
+ { tasks: request.tasks, context: request.context, cwd: request.cwd, worktree: request.worktree },
330
305
  signal,
331
306
  onUpdate,
332
307
  ctx,
@@ -340,7 +315,6 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
340
315
  context: request.context,
341
316
  cwd: request.cwd,
342
317
  model: request.model,
343
- async: false,
344
318
  },
345
319
  signal,
346
320
  onUpdate,
@@ -381,15 +355,10 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
381
355
  }
382
356
  const isParallel = (args.tasks?.length ?? 0) > 0;
383
357
  const parallelCount = effectiveParallelTaskCount(args.tasks as Array<{ count?: unknown }> | undefined);
384
- const asyncLabel = args.async === true ? theme.fg("warning", " [async]") : "";
385
- if (isParallel)
386
- return new Text(
387
- `${theme.fg("toolTitle", theme.bold("subagent "))}parallel (${parallelCount})${asyncLabel}`,
388
- 0,
389
- 0,
390
- );
391
358
  return new Text(
392
- `${theme.fg("toolTitle", theme.bold("subagent "))}${theme.fg("accent", args.agent || "?")}${asyncLabel}`,
359
+ isParallel
360
+ ? `${theme.fg("toolTitle", theme.bold("subagent "))}parallel (${parallelCount})`
361
+ : `${theme.fg("toolTitle", theme.bold("subagent "))}${theme.fg("accent", args.agent || "?")}`,
393
362
  0,
394
363
  0,
395
364
  );
@@ -403,12 +372,6 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
403
372
  const notifyCleanup = registerSubagentNotify(pi);
404
373
  registrationFailureCleanups.push(notifyCleanup);
405
374
  const visibleControlNotices = getApiScopedSet(pi, "__piSubagentVisibleControlNoticesByApi");
406
- const startedEventHandler = (payload: unknown) => {
407
- if (lifecycle.isCurrent()) handleStarted(payload);
408
- };
409
- const completeEventHandler = (payload: unknown) => {
410
- if (lifecycle.isCurrent()) handleComplete(payload);
411
- };
412
375
  const controlEventHandler = (payload: unknown) => {
413
376
  if (!lifecycle.isCurrent()) return;
414
377
  handleSubagentControlNotice({
@@ -419,15 +382,9 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
419
382
  });
420
383
  };
421
384
  const eventUnsubscribes: Array<() => void> = [];
422
- for (const [event, handler] of [
423
- [SUBAGENT_ASYNC_STARTED_EVENT, startedEventHandler],
424
- [SUBAGENT_ASYNC_COMPLETE_EVENT, completeEventHandler],
425
- [SUBAGENT_CONTROL_EVENT, controlEventHandler],
426
- ] as const) {
427
- const unsubscribe = pi.events.on(event, handler);
428
- eventUnsubscribes.push(unsubscribe);
429
- registrationFailureCleanups.push(unsubscribe);
430
- }
385
+ const unsubscribeControl = pi.events.on(SUBAGENT_CONTROL_EVENT, controlEventHandler);
386
+ eventUnsubscribes.push(unsubscribeControl);
387
+ registrationFailureCleanups.push(unsubscribeControl);
431
388
  let cleaned = false;
432
389
  const runtimeCleanup = () => {
433
390
  if (cleaned) return;
@@ -436,16 +393,8 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
436
393
  ...eventUnsubscribes,
437
394
  notifyCleanup,
438
395
  () => maintenance.stop(),
439
- () => stopWidgetAnimation(undefined, pi),
440
396
  () => stopResultAnimations(),
441
- () => {
442
- if (state.poller) clearInterval(state.poller);
443
- state.poller = null;
444
- },
445
397
  () => clearPendingForegroundControlNotices(state),
446
- ...Array.from(state.cleanupTimers.values(), (timer) => () => clearTimeout(timer)),
447
- () => state.cleanupTimers.clear(),
448
- () => state.asyncJobs.clear(),
449
398
  () => childExecutors.clear(),
450
399
  () => clearSlashSnapshots(pi),
451
400
  () => slashBridge.cancelAll(),
@@ -463,13 +412,6 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
463
412
  };
464
413
  lifecycle.setCleanup(runtimeCleanup);
465
414
  runtimeCleanupInstalled = true;
466
- pi.on("tool_result", (event, ctx) => {
467
- if (!lifecycle.isCurrent() || event.toolName !== "subagent") return;
468
- if (!ctx.hasUI) return;
469
- state.lastUiContext = ctx;
470
- hydrateActiveJobsDeferred(ctx);
471
- if (state.asyncJobs.size > 0) ensurePoller();
472
- });
473
415
  const cleanupSessionArtifacts = (ctx: ExtensionContext) => {
474
416
  maintenance.cleanupSessionArtifactsDeferred(ctx);
475
417
  };
@@ -479,9 +421,6 @@ export default function registerSubagentExtension(pi: ExtensionAPI): void {
479
421
  state.lastUiContext = ctx;
480
422
  cleanupSessionArtifacts(ctx);
481
423
  clearPendingForegroundControlNotices(state);
482
- resetJobs(ctx);
483
- hydrateActiveJobsDeferred(ctx);
484
- restoreSlashFinalSnapshots(ctx.sessionManager.getEntries(), pi);
485
424
  restoreSlashFinalSnapshots(ctx.sessionManager.getEntries(), pi);
486
425
  };
487
426
  pi.on("session_start", (_event, ctx) => {
@@ -1,4 +1,4 @@
1
- import type { SubagentNotifyDetails } from "../runs/background/notify.ts";
1
+ import type { SubagentNotifyDetails } from "../runs/foreground/notify.ts";
2
2
 
3
3
  const HEADER_STATUSES = ["completed", "failed", "paused"] as const;
4
4
 
@@ -3,9 +3,9 @@ export const DEFAULT_PROMPT_GUIDANCE: string[] = [
3
3
  - Because workflows are the default for non-trivial structured work with verifiable objectives, do not stretch parent-controlled subagent calls into an ad hoc implementation, review, or retry pipeline; use a workflow and let its stages delegate specialists.
4
4
  - Use a single subagent for a focused specialty or parallel tasks for independent work. Keep substantial-overlap tasks together rather than duplicating investigation across agents.
5
5
  - Delegate noisy or context-heavy command investigation when isolation helps, but run concise commands inline when that is simpler.
6
- - Use async/background execution when delegated work is genuinely long-running or independently useful. Foreground execution is appropriate when the parent needs the result before proceeding; do not duplicate a delegated job while waiting.
6
+ - Foreground execution is the only subagent execution mode; do not duplicate a delegated job while waiting. Workflow stages may still run their own durable work in the background.
7
7
  - Use the debugger subagent for actual failures that need reproduction, root-cause diagnosis, and a validated fix; additional debugger or research delegates are optional when they add a distinct useful angle.
8
8
  - Let each named agent use its declared model and fallback policy: omit the explicit model argument unless the user requests an exact model or a documented task requirement needs one, and record the reason for any override before launch. Do not choose an ad hoc model merely for diversity.
9
9
  - If an agent has no declared model or fallback policy, consult packages/coding-agent/docs/models/model-selection.md for the role's Pareto-efficient recommendations, then use workflow({ action: "models" }) when available to inspect the configured catalog. Pin only a returned fullId and only append a thinking level listed for that entry. If the catalog tool is unavailable, the catalog is empty, or no recommended model is present, leave the child unpinned and state the limitation rather than inventing a model. Do not inspect credentials or infer why a model is absent.
10
- - Workflow stages automatically receive their invocation-scoped Intercom group, and delegated children inherit the launching session's group across single, parallel, async, and follow-up work. Do not create or propagate group identifiers for ordinary workflow-stage delegation; use an explicit group only for an intentional topology override. Keep contact_supervisor available for cross-group escalation.`,
10
+ - Workflow stages automatically receive their invocation-scoped Intercom group, and delegated children inherit the launching session's group across single, parallel, and follow-up work. Do not create or propagate group identifiers for ordinary workflow-stage delegation; use an explicit group only for an intentional topology override. Keep contact_supervisor available for cross-group escalation.`,
11
11
  ];
@@ -100,8 +100,8 @@ const ControlOverrides = Type.Object({
100
100
  }),
101
101
  ),
102
102
  notifyChannels: Type.Optional(
103
- Type.Array(Type.String({ enum: ["event", "async", "intercom"] }), {
104
- description: "Notification channels to use when available. Defaults to event, async, and intercom.",
103
+ Type.Array(Type.String({ enum: ["event", "intercom"] }), {
104
+ description: "Notification channels to use when available. Defaults to event and intercom.",
105
105
  }),
106
106
  ),
107
107
  });
@@ -130,11 +130,6 @@ export const SubagentParams = Type.Object(
130
130
  "Target run ID for action='interrupt' or action='resume'. Defaults to the most recently active controllable run for interrupt. Prefer id for new calls.",
131
131
  }),
132
132
  ),
133
- dir: Type.Optional(
134
- Type.String({
135
- description: "Async run directory for action='status' or action='resume'.",
136
- }),
137
- ),
138
133
  index: Type.Optional(
139
134
  Type.Integer({ minimum: 0, description: "Zero-based child index for actions that target a specific child." }),
140
135
  ),
@@ -178,7 +173,6 @@ export const SubagentParams = Type.Object(
178
173
  "'fresh' or 'fork' to branch from parent session. If omitted, any requested agent with defaultContext: 'fork' makes the whole invocation forked; otherwise the default is 'fresh'.",
179
174
  }),
180
175
  ),
181
- async: Type.Optional(Type.Boolean({ description: "Run in background (default: false, or per config)" })),
182
176
  agentScope: Type.Optional(
183
177
  Type.String({
184
178
  description:
@@ -5,7 +5,6 @@ EXECUTION (use exactly ONE mode):
5
5
  • SINGLE: { agent, task?, progress? } - one focused task; progress:true maintains a run-scoped progress.md under isolated artifact storage without writing it into the child cwd (separate from includeProgress, which only returns runtime telemetry); omit task for self-contained agents
6
6
  • PARALLEL: { tasks: [{agent,task,count?,output?,reads?,progress?}, ...], concurrency?: number, worktree?: true } - independent concurrent tasks (worktree: isolate each task in a git worktree)
7
7
  • Optional context: { context: "fresh" | "fork" } (default: if any requested agent has defaultContext: "fork", the whole invocation uses fork; otherwise "fresh"; inspect agent defaults via { action: "list" })
8
- • async:true is selective for genuinely long-running/background work; foreground is appropriate when the parent needs the result before proceeding
9
8
  • group (string | true) sets the intercom group for spawned children so same-group subagents can intercom each other but stay isolated from other groups. Boolean true or the trimmed, case-insensitive string sentinel "true"/"auto" auto-generates one shared UUID group per parallel set; those names are reserved and cannot be literal group names. Defaults to the current session/stage's group (subagents inherit their launching stage's group). Only applied when the child has intercom access; contact_supervisor still reaches the supervisor across groups.
10
9
  MANAGEMENT (use action field, omit agent/task/tasks):
11
10
  • { action: "list" } - discover executable agents
@@ -14,8 +13,8 @@ MANAGEMENT (use action field, omit agent/task/tasks):
14
13
  • { action: "update", agent: "code-analysis.custom-agent", config: { package: "analysis", ... } } - merge
15
14
  • { action: "delete", agent: "code-analysis.custom-agent" }
16
15
  CONTROL:
17
- • { action: "status", id: "..." } - inspect an async/background run by id or prefix
16
+ • { action: "status", id: "..." } - inspect an in-process run by id or prefix
18
17
  • { action: "interrupt", id?: "..." } - soft-interrupt the current child turn and leave the run paused
19
- • { action: "resume", id: "...", message: "...", index?: 0 } - follow up with a live async child or revive a completed async/foreground child from its session
18
+ • { action: "resume", id: "...", message: "...", index?: 0 } - follow up with a live child or revive a retained foreground child
20
19
  DIAGNOSTICS:
21
20
  • { action: "doctor" } - read-only report for runtime paths, discovery, sessions, and intercom`;
@@ -83,7 +83,7 @@ export function resolveIntercomSessionTarget(sessionName: string | undefined, se
83
83
  const trimmedName = sessionName?.trim();
84
84
  if (trimmedName) return trimmedName;
85
85
  const normalizedSessionId = sessionId.startsWith("session-") ? sessionId.slice("session-".length) : sessionId;
86
- return `${DEFAULT_INTERCOM_TARGET_PREFIX}-${normalizedSessionId.slice(0, 8)}`;
86
+ return `${DEFAULT_INTERCOM_TARGET_PREFIX}-${normalizedSessionId}`;
87
87
  }
88
88
 
89
89
  function sanitizeIntercomTargetPart(value: string): string {
@@ -1,5 +1,4 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import * as fs from "node:fs";
3
2
  import { isStaleExtensionContextError } from "@bastani/atomic";
4
3
  import {
5
4
  type Details,
@@ -76,7 +75,6 @@ function compactNestedRun(run: NestedRunSummary | PublicNestedRunSummary, depth
76
75
  ...(part.stepIndex !== undefined ? { stepIndex: part.stepIndex } : {}),
77
76
  ...(part.agent ? { agent: part.agent } : {}),
78
77
  })),
79
- ...(run.asyncDir ? { asyncDir: run.asyncDir } : {}),
80
78
  ...(run.sessionId ? { sessionId: run.sessionId } : {}),
81
79
  ...(run.sessionFile ? { sessionFile: run.sessionFile } : {}),
82
80
  ...(run.intercomTarget ? { intercomTarget: run.intercomTarget } : {}),
@@ -191,39 +189,14 @@ export interface GroupedResultIntercomMessageInput {
191
189
  to: string;
192
190
  runId: string;
193
191
  mode: SubagentRunMode;
194
- source: "foreground" | "async";
195
192
  children: SubagentResultIntercomChild[];
196
- asyncId?: string;
197
- asyncDir?: string;
198
- }
199
-
200
- function asyncResumeGuidance(input: {
201
- source: "foreground" | "async";
202
- children: SubagentResultIntercomChild[];
203
- asyncId?: string;
204
- }): string | undefined {
205
- if (input.source !== "async" || !input.asyncId) return undefined;
206
- const resumable = input.children.filter(
207
- (child) => typeof child.sessionPath === "string" && fs.existsSync(child.sessionPath),
208
- );
209
- if (input.children.length === 1 && resumable.length === 1) {
210
- return `Revive: subagent({ action: "resume", id: "${input.asyncId}", message: "..." })`;
211
- }
212
- if (resumable.length > 0) {
213
- const firstIndex = resumable[0]?.index ?? input.children.indexOf(resumable[0]!);
214
- return `Revive child: subagent({ action: "resume", id: "${input.asyncId}", index: ${firstIndex}, message: "..." })`;
215
- }
216
- return "Resume: unavailable; no child session file was persisted.";
217
193
  }
218
194
 
219
195
  function formatSubagentResultIntercomMessage(input: {
220
196
  runId: string;
221
197
  mode: SubagentRunMode;
222
198
  status: SubagentResultStatus;
223
- source: "foreground" | "async";
224
199
  children: SubagentResultIntercomChild[];
225
- asyncId?: string;
226
- asyncDir?: string;
227
200
  }): string {
228
201
  const counts = countStatuses(input.children);
229
202
  const lines: string[] = [
@@ -234,32 +207,21 @@ function formatSubagentResultIntercomMessage(input: {
234
207
  `Status: ${input.status}`,
235
208
  `Children: ${formatStatusCounts(counts)}`,
236
209
  ];
237
- if (input.asyncId) lines.push(`Async id: ${input.asyncId}`);
238
- if (input.asyncDir) lines.push(`Async dir: ${input.asyncDir}`);
239
- const resumeGuidance = asyncResumeGuidance(input);
240
- if (resumeGuidance) lines.push(resumeGuidance);
241
210
  if (input.children.some((child) => child.intercomTarget)) {
242
- lines.push("");
243
211
  lines.push(
244
- input.source === "async"
245
- ? "Previous intercom targets below identify child sessions used while they were running. Inspect artifacts or session logs if resume is unavailable."
246
- : "Intercom targets below identify child sessions used while they were running; completed child sessions may no longer be reachable. Inspect artifacts or session logs for follow-up.",
212
+ "",
213
+ "Intercom targets below identify child sessions used while they were running; completed child sessions may no longer be reachable. Inspect artifacts or session logs for follow-up.",
247
214
  );
248
215
  }
249
216
 
250
217
  for (let index = 0; index < input.children.length; index++) {
251
218
  const child = input.children[index]!;
252
- lines.push("");
253
- lines.push(`${index + 1}. ${child.agent} — ${child.status}`);
254
- if (child.intercomTarget)
255
- lines.push(
256
- `${input.source === "async" ? "Previous intercom target" : "Run intercom target"}: ${child.intercomTarget}`,
257
- );
219
+ lines.push("", `${index + 1}. ${child.agent} — ${child.status}`);
220
+ if (child.intercomTarget) lines.push(`Run intercom target: ${child.intercomTarget}`);
258
221
  if (child.artifactPath) lines.push(`Output artifact: ${child.artifactPath}`);
259
222
  if (child.sessionPath) lines.push(`Session: ${child.sessionPath}`);
260
223
  lines.push(...formatNestedResultLines(child.children));
261
- lines.push("Summary:");
262
- lines.push(child.summary);
224
+ lines.push("Summary:", child.summary);
263
225
  }
264
226
 
265
227
  return lines.join("\n");
@@ -282,10 +244,7 @@ export function buildSubagentResultIntercomPayload(
282
244
  mode: input.mode,
283
245
  status,
284
246
  summary,
285
- source: input.source,
286
247
  children,
287
- ...(input.asyncId ? { asyncId: input.asyncId } : {}),
288
- ...(input.asyncDir ? { asyncDir: input.asyncDir } : {}),
289
248
  ...(firstChild?.agent ? { agent: firstChild.agent } : {}),
290
249
  ...(firstChild?.index !== undefined ? { index: firstChild.index } : {}),
291
250
  ...(firstChild?.artifactPath ? { artifactPath: firstChild.artifactPath } : {}),
@@ -1,5 +1,5 @@
1
1
  import type { IntercomEventBus } from "../../shared/types.ts";
2
- import { SUBAGENT_ASYNC_COMPLETE_EVENT } from "../../shared/types.ts";
2
+ import { SUBAGENT_COMPLETE_EVENT } from "../../shared/types.ts";
3
3
 
4
4
  export interface CompletionNotificationEnvelope extends Record<string, unknown> {
5
5
  notificationId: string;
@@ -26,7 +26,7 @@ export function deliverLocalCompletionNotification(
26
26
  reject(error);
27
27
  };
28
28
  try {
29
- events.emit(SUBAGENT_ASYNC_COMPLETE_EVENT, {
29
+ events.emit(SUBAGENT_COMPLETE_EVENT, {
30
30
  ...payload,
31
31
  notificationId,
32
32
  defer: () => {