@duckmind/dm-windows-x64 0.61.4 → 0.61.9

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 (279) hide show
  1. package/dm.exe +0 -0
  2. package/extensions/.dm-extensions.json +211 -67
  3. package/extensions/dm-subagents/agents/claude-code-writer.md +15 -0
  4. package/extensions/dm-subagents/agents/claude-code.md +15 -0
  5. package/extensions/dm-subagents/agents/codex-exec-writer.md +15 -0
  6. package/extensions/dm-subagents/agents/codex-exec.md +15 -0
  7. package/extensions/dm-subagents/agents/cursor-agent-writer.md +14 -0
  8. package/extensions/dm-subagents/agents/cursor-agent.md +14 -0
  9. package/extensions/dm-subagents/agents/delegate.md +3 -2
  10. package/extensions/dm-subagents/agents/oracle.md +10 -5
  11. package/extensions/dm-subagents/agents/researcher.md +2 -2
  12. package/extensions/dm-subagents/agents/reviewer.md +17 -7
  13. package/extensions/dm-subagents/agents/scout.md +5 -5
  14. package/extensions/dm-subagents/agents/worker.md +6 -2
  15. package/extensions/dm-subagents/async-retention-discovery-worker.mjs +167 -0
  16. package/extensions/dm-subagents/index.js +4 -0
  17. package/extensions/dm-subagents/inspector-runner.mjs +10 -0
  18. package/extensions/dm-subagents/install.mjs +3 -2
  19. package/extensions/dm-subagents/package.json +2 -2
  20. package/extensions/dm-subagents/prompts/council.md +60 -0
  21. package/extensions/dm-subagents/prompts/parallel-review.md +5 -1
  22. package/extensions/dm-subagents/prompts/review-loop.md +13 -7
  23. package/extensions/dm-subagents/skills/council-mode/SKILL.md +59 -0
  24. package/extensions/dm-subagents/skills/council-mode/references/pass-contracts.md +150 -0
  25. package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +96 -911
  26. package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +70 -0
  27. package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +539 -0
  28. package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +161 -0
  29. package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +51 -0
  30. package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +295 -0
  31. package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +73 -0
  32. package/extensions/dm-subagents/src/agents/agent-management.js +716 -484
  33. package/extensions/dm-subagents/src/agents/agent-refinements.js +563 -0
  34. package/extensions/dm-subagents/src/agents/agent-serializer.js +70 -5
  35. package/extensions/dm-subagents/src/agents/agents.js +1447 -299
  36. package/extensions/dm-subagents/src/agents/builtin-names.js +15 -0
  37. package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -7
  38. package/extensions/dm-subagents/src/agents/frontmatter.js +64 -14
  39. package/extensions/dm-subagents/src/agents/identity.js +1 -1
  40. package/extensions/dm-subagents/src/agents/proactive-skills.js +14 -11
  41. package/extensions/dm-subagents/src/agents/runtime-agent-events.js +49 -0
  42. package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +412 -0
  43. package/extensions/dm-subagents/src/agents/skills.js +52 -35
  44. package/extensions/dm-subagents/src/api/agents.js +6 -0
  45. package/extensions/dm-subagents/src/api/background-work.js +151 -0
  46. package/extensions/dm-subagents/src/api/capability-ceiling.js +12 -0
  47. package/extensions/dm-subagents/src/api/control-channel.js +3 -0
  48. package/extensions/dm-subagents/src/api/delegation.js +5 -0
  49. package/extensions/dm-subagents/src/api/dm-args.js +3 -0
  50. package/extensions/dm-subagents/src/api/external-job-provider.js +137 -0
  51. package/extensions/dm-subagents/src/api/external-runs.js +233 -0
  52. package/extensions/dm-subagents/src/api/intercom-bridge.js +3 -0
  53. package/extensions/dm-subagents/src/api/preflight.js +322 -0
  54. package/extensions/dm-subagents/src/api/project-panes.js +11 -0
  55. package/extensions/dm-subagents/src/api/shared-types.js +4 -0
  56. package/extensions/dm-subagents/src/extension/config.js +175 -0
  57. package/extensions/dm-subagents/src/extension/control-notices.js +4 -43
  58. package/extensions/dm-subagents/src/extension/doctor.js +71 -17
  59. package/extensions/dm-subagents/src/extension/fanout-child.js +49 -32
  60. package/extensions/dm-subagents/src/extension/index.js +711 -265
  61. package/extensions/dm-subagents/src/extension/public-execution.js +114 -0
  62. package/extensions/dm-subagents/src/extension/rpc.js +427 -22
  63. package/extensions/dm-subagents/src/extension/schemas.js +158 -65
  64. package/extensions/dm-subagents/src/extension/steering-notices.js +23 -0
  65. package/extensions/dm-subagents/src/extension/subagent-guide.js +31 -0
  66. package/extensions/dm-subagents/src/extension/tool-description.js +92 -74
  67. package/extensions/dm-subagents/src/extension/tool-result.js +7 -0
  68. package/extensions/dm-subagents/src/inspectors/herdr/actions.js +218 -0
  69. package/extensions/dm-subagents/src/inspectors/herdr/client.js +123 -0
  70. package/extensions/dm-subagents/src/inspectors/herdr/focus.js +47 -0
  71. package/extensions/dm-subagents/src/inspectors/herdr/inspector-runner.js +160 -0
  72. package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +618 -0
  73. package/extensions/dm-subagents/src/inspectors/herdr/session-roots-codec.js +21 -0
  74. package/extensions/dm-subagents/src/inspectors/herdr/shell-command.js +15 -0
  75. package/extensions/dm-subagents/src/integrations/herdr-status.js +377 -0
  76. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +17 -13
  77. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +371 -79
  78. package/extensions/dm-subagents/src/intercom/result-intercom.js +47 -7
  79. package/extensions/dm-subagents/src/missions/actions.js +394 -0
  80. package/extensions/dm-subagents/src/missions/goal-driver.js +149 -0
  81. package/extensions/dm-subagents/src/missions/lifecycle.js +331 -0
  82. package/extensions/dm-subagents/src/missions/store.js +548 -0
  83. package/extensions/dm-subagents/src/missions/types.js +9 -0
  84. package/extensions/dm-subagents/src/missions/workflow-state.js +245 -0
  85. package/extensions/dm-subagents/src/policy/authority.js +37 -0
  86. package/extensions/dm-subagents/src/profiles/profiles.js +36 -18
  87. package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +427 -0
  88. package/extensions/dm-subagents/src/runs/background/active-run-index.js +122 -0
  89. package/extensions/dm-subagents/src/runs/background/async-execution.js +925 -137
  90. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +515 -148
  91. package/extensions/dm-subagents/src/runs/background/async-resume.js +378 -51
  92. package/extensions/dm-subagents/src/runs/background/async-retention.js +828 -0
  93. package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +31 -0
  94. package/extensions/dm-subagents/src/runs/background/async-status.js +259 -22
  95. package/extensions/dm-subagents/src/runs/background/auto-drain.js +46 -0
  96. package/extensions/dm-subagents/src/runs/background/chain-append.js +50 -15
  97. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +67 -12
  98. package/extensions/dm-subagents/src/runs/background/completion-batcher.js +5 -1
  99. package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +3 -11
  100. package/extensions/dm-subagents/src/runs/background/completion-replay.js +245 -0
  101. package/extensions/dm-subagents/src/runs/background/control-channel.js +423 -36
  102. package/extensions/dm-subagents/src/runs/background/fleet-view.js +132 -59
  103. package/extensions/dm-subagents/src/runs/background/index-segment.js +38 -0
  104. package/extensions/dm-subagents/src/runs/background/inspect-rpc.js +373 -0
  105. package/extensions/dm-subagents/src/runs/background/notify.js +357 -57
  106. package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +86 -0
  107. package/extensions/dm-subagents/src/runs/background/process-terminal.js +269 -0
  108. package/extensions/dm-subagents/src/runs/background/result-delivery-ownership.js +34 -0
  109. package/extensions/dm-subagents/src/runs/background/result-files.js +469 -0
  110. package/extensions/dm-subagents/src/runs/background/result-watcher.js +540 -75
  111. package/extensions/dm-subagents/src/runs/background/resume-guidance.js +44 -0
  112. package/extensions/dm-subagents/src/runs/background/retained-children.js +119 -0
  113. package/extensions/dm-subagents/src/runs/background/run-id-query.js +5 -0
  114. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +93 -9
  115. package/extensions/dm-subagents/src/runs/background/run-status.js +303 -32
  116. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +784 -376
  117. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +75 -34
  118. package/extensions/dm-subagents/src/runs/background/steering.js +221 -0
  119. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +3106 -844
  120. package/extensions/dm-subagents/src/runs/background/subagent-wait.js +529 -0
  121. package/extensions/dm-subagents/src/runs/background/terminal-run-index.js +106 -0
  122. package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -1
  123. package/extensions/dm-subagents/src/runs/background/wait-completions.js +155 -0
  124. package/extensions/dm-subagents/src/runs/background/wait-config.js +46 -0
  125. package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +278 -0
  126. package/extensions/dm-subagents/src/runs/background/wait-tool.js +47 -0
  127. package/extensions/dm-subagents/src/runs/foreground/async-dismiss-action.js +81 -0
  128. package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +245 -0
  129. package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +74 -0
  130. package/extensions/dm-subagents/src/runs/foreground/execution.js +1401 -342
  131. package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +133 -0
  132. package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +148 -0
  133. package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +139 -0
  134. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +4278 -1441
  135. package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +278 -0
  136. package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +155 -0
  137. package/extensions/dm-subagents/src/runs/shared/abort-recovery.js +97 -0
  138. package/extensions/dm-subagents/src/runs/shared/acceptance.js +597 -148
  139. package/extensions/dm-subagents/src/runs/shared/agent-contract.js +35 -0
  140. package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +472 -0
  141. package/extensions/dm-subagents/src/runs/shared/background-process-options.js +6 -0
  142. package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +175 -0
  143. package/extensions/dm-subagents/src/runs/shared/child-identity.js +32 -0
  144. package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +65 -0
  145. package/extensions/dm-subagents/src/runs/shared/child-protocol.js +447 -0
  146. package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +120 -0
  147. package/extensions/dm-subagents/src/runs/shared/codex-exec-adapter.js +129 -0
  148. package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +40 -0
  149. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +140 -83
  150. package/extensions/dm-subagents/src/runs/shared/context-mode.js +38 -0
  151. package/extensions/dm-subagents/src/runs/shared/cursor-agent-adapter.js +101 -0
  152. package/extensions/dm-subagents/src/runs/shared/dm-args.js +445 -72
  153. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +27 -16
  154. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +19 -6
  155. package/extensions/dm-subagents/src/runs/shared/extension-bindings.js +81 -0
  156. package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +134 -0
  157. package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +98 -0
  158. package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +419 -0
  159. package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +404 -0
  160. package/extensions/dm-subagents/src/runs/shared/external-job-runner.js +334 -0
  161. package/extensions/dm-subagents/src/runs/shared/fast-mode-extension.js +8 -0
  162. package/extensions/dm-subagents/src/runs/shared/host-step-status.js +228 -0
  163. package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +104 -0
  164. package/extensions/dm-subagents/src/runs/shared/launch-cwd.js +17 -0
  165. package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +190 -0
  166. package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +48 -3
  167. package/extensions/dm-subagents/src/runs/shared/mcp-config-sources.js +387 -0
  168. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +212 -137
  169. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +131 -0
  170. package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +207 -0
  171. package/extensions/dm-subagents/src/runs/shared/model-fallback.js +225 -55
  172. package/extensions/dm-subagents/src/runs/shared/model-scope.js +85 -28
  173. package/extensions/dm-subagents/src/runs/shared/mutation-evidence.js +182 -0
  174. package/extensions/dm-subagents/src/runs/shared/nested-events.js +264 -102
  175. package/extensions/dm-subagents/src/runs/shared/nested-render.js +15 -5
  176. package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +505 -0
  177. package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +653 -0
  178. package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +29 -12
  179. package/extensions/dm-subagents/src/runs/shared/permissions.js +108 -0
  180. package/extensions/dm-subagents/src/runs/shared/process-signal.js +13 -0
  181. package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +257 -0
  182. package/extensions/dm-subagents/src/runs/shared/run-history.js +133 -13
  183. package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +62 -0
  184. package/extensions/dm-subagents/src/runs/shared/session-lease.js +225 -0
  185. package/extensions/dm-subagents/src/runs/shared/single-output.js +129 -27
  186. package/extensions/dm-subagents/src/runs/shared/spawn-budget.js +95 -0
  187. package/extensions/dm-subagents/src/runs/shared/structured-output.js +129 -10
  188. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +66 -11
  189. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +548 -70
  190. package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +50 -0
  191. package/extensions/dm-subagents/src/runs/shared/task-intent.js +130 -0
  192. package/extensions/dm-subagents/src/runs/shared/tool-availability.js +59 -0
  193. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +7 -5
  194. package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +64 -0
  195. package/extensions/dm-subagents/src/runs/shared/usage-budget.js +74 -0
  196. package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +22 -0
  197. package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +721 -0
  198. package/extensions/dm-subagents/src/runs/shared/worktree.js +168 -19
  199. package/extensions/dm-subagents/src/shared/accessible-dir.js +35 -0
  200. package/extensions/dm-subagents/src/shared/agent-stream-options.js +3 -0
  201. package/extensions/dm-subagents/src/shared/artifacts.js +170 -11
  202. package/extensions/dm-subagents/src/shared/atomic-json.js +36 -38
  203. package/extensions/dm-subagents/src/shared/capacity-resilient-json.js +77 -0
  204. package/extensions/dm-subagents/src/shared/child-session-name.js +15 -0
  205. package/extensions/dm-subagents/src/shared/child-transcript.js +57 -2
  206. package/extensions/dm-subagents/src/shared/completion-owner.js +7 -0
  207. package/extensions/dm-subagents/src/shared/display-text.js +142 -0
  208. package/extensions/dm-subagents/src/shared/extension-context.js +17 -0
  209. package/extensions/dm-subagents/src/shared/file-coalescer.js +9 -0
  210. package/extensions/dm-subagents/src/shared/file-system-retry.js +56 -0
  211. package/extensions/dm-subagents/src/shared/fork-context.js +96 -33
  212. package/extensions/dm-subagents/src/shared/formatters.js +21 -7
  213. package/extensions/dm-subagents/src/shared/launch-contract.js +94 -0
  214. package/extensions/dm-subagents/src/shared/model-info.js +10 -5
  215. package/extensions/dm-subagents/src/shared/node-executable.js +19 -0
  216. package/extensions/dm-subagents/src/shared/prompt-resources.js +10 -0
  217. package/extensions/dm-subagents/src/shared/pruned-fork.js +427 -0
  218. package/extensions/dm-subagents/src/shared/session-file-trust.js +19 -0
  219. package/extensions/dm-subagents/src/shared/session-tokens.js +14 -3
  220. package/extensions/dm-subagents/src/shared/settings.js +39 -47
  221. package/extensions/dm-subagents/src/shared/shortcuts.js +16 -0
  222. package/extensions/dm-subagents/src/shared/status-format.js +9 -2
  223. package/extensions/dm-subagents/src/shared/thinking-ceiling.js +41 -0
  224. package/extensions/dm-subagents/src/shared/types.js +47 -7
  225. package/extensions/dm-subagents/src/shared/utf8.js +12 -0
  226. package/extensions/dm-subagents/src/shared/utils.js +151 -131
  227. package/extensions/dm-subagents/src/shared/watch-strategy.js +3 -0
  228. package/extensions/dm-subagents/src/shared/workflow-child-permit.js +84 -0
  229. package/extensions/dm-subagents/src/slash/delegation-adapters.js +274 -0
  230. package/extensions/dm-subagents/src/slash/delegation-json.js +113 -0
  231. package/extensions/dm-subagents/src/slash/delegation-request.js +152 -0
  232. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +294 -243
  233. package/extensions/dm-subagents/src/slash/prompt-workflows.js +35 -73
  234. package/extensions/dm-subagents/src/slash/selector.js +101 -0
  235. package/extensions/dm-subagents/src/slash/slash-bridge.js +17 -1
  236. package/extensions/dm-subagents/src/slash/slash-commands.js +722 -732
  237. package/extensions/dm-subagents/src/slash/slash-live-state.js +37 -19
  238. package/extensions/dm-subagents/src/slash/subagents-admin.js +410 -0
  239. package/extensions/dm-subagents/src/tui/fleet-status.js +824 -0
  240. package/extensions/dm-subagents/src/tui/fleet-transcript.js +479 -0
  241. package/extensions/dm-subagents/src/tui/fleet.js +1326 -0
  242. package/extensions/dm-subagents/src/tui/render-helpers.js +22 -0
  243. package/extensions/dm-subagents/src/tui/render.js +1511 -261
  244. package/extensions/dm-subagents/src/watchdog/change-signature.js +220 -0
  245. package/extensions/dm-subagents/src/watchdog/child-status.js +151 -0
  246. package/extensions/dm-subagents/src/watchdog/emission-guard.js +90 -0
  247. package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +484 -0
  248. package/extensions/dm-subagents/src/watchdog/model-selection.js +154 -0
  249. package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +138 -0
  250. package/extensions/dm-subagents/src/watchdog/register-child.js +112 -0
  251. package/extensions/dm-subagents/src/watchdog/register-main.js +419 -0
  252. package/extensions/dm-subagents/src/watchdog/render.js +54 -0
  253. package/extensions/dm-subagents/src/watchdog/review.js +251 -0
  254. package/extensions/dm-subagents/src/watchdog/runtime.js +803 -0
  255. package/extensions/dm-subagents/src/watchdog/scope.js +56 -0
  256. package/extensions/dm-subagents/src/watchdog/settings.js +515 -0
  257. package/extensions/dm-subagents/src/watchdog/tool-actions.js +151 -0
  258. package/extensions/dm-subagents/src/watchdog/turn-delta.js +169 -0
  259. package/extensions/dm-subagents/src/watchdog/types.js +29 -0
  260. package/extensions/dm-subagents/src/watchdog/warning-format.js +58 -0
  261. package/extensions/dm-subagents/src/workflows/chat-progress.js +116 -0
  262. package/extensions/dm-subagents/src/workflows/host-command.js +227 -0
  263. package/extensions/dm-subagents/src/workflows/scripted-workflow.js +2011 -0
  264. package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +116 -0
  265. package/extensions/dm-subagents/src/workflows/workflow-preflight.js +243 -0
  266. package/extensions/dm-subagents/src/workflows/workflow-receipt.js +387 -0
  267. package/extensions/dm-subagents/src/workflows/workflow-settlement.js +189 -0
  268. package/package.json +4 -3
  269. package/extensions/dm-fff/package.json +0 -21
  270. package/extensions/dm-fff/src/index.js +0 -691
  271. package/extensions/dm-fff/src/query.js +0 -60
  272. package/extensions/dm-subagents/agents/context-builder.md +0 -46
  273. package/extensions/dm-subagents/agents/planner.md +0 -55
  274. package/extensions/dm-subagents/prompts/parallel-context-build.md +0 -55
  275. package/extensions/dm-subagents/prompts/parallel-handoff-plan.md +0 -61
  276. package/extensions/dm-subagents/src/runs/background/wait.js +0 -206
  277. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +0 -1013
  278. package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +0 -981
  279. package/extensions/dm-subagents/src/runs/shared/turn-budget.js +0 -50
@@ -0,0 +1,44 @@
1
+ import * as fs from "node:fs";
2
+ import { readAsyncRecoveryDescriptor } from "./async-resume.js";
3
+ const INTERCOM_DETACH_ERROR = "detached for intercom coordination";
4
+ function isIntercomDetached(run) {
5
+ return run.steps.some((step) => step.execution?.status === "detached" || step.error?.toLowerCase().includes(INTERCOM_DETACH_ERROR) === true) || run.error?.toLowerCase().includes(INTERCOM_DETACH_ERROR) === true;
6
+ }
7
+ function formatIntercomDetachGuidance(run) {
8
+ if (!isIntercomDetached(run))
9
+ return;
10
+ return `Run "${run.id}" detached for intercom coordination. Reply to the supervisor request first, then wait with bg_wait({ id: "${run.id}" }). Use subagent({ action: "status", id: "${run.id}" }) to recover the result; do not resume or launch a replacement while it remains detached.`;
11
+ }
12
+ export function formatAsyncReviveCommand(run) {
13
+ const step = run.steps.find((candidate) => candidate.status === "failed");
14
+ const sessionFile = step?.sessionFile ?? (run.steps.length === 1 ? run.sessionFile : undefined);
15
+ if (!step || !sessionFile || !fs.existsSync(sessionFile))
16
+ return;
17
+ try {
18
+ const descriptor = readAsyncRecoveryDescriptor(run.asyncDir);
19
+ if (!descriptor || descriptor.sourceRunId !== run.id || descriptor.agent !== step.agent)
20
+ return;
21
+ } catch {
22
+ return;
23
+ }
24
+ const index = run.steps.length === 1 ? "" : `, index: ${step.index}`;
25
+ return `subagent({ action: "resume", id: "${run.id}"${index}, message: "Continue from the persisted child session and report the result." })`;
26
+ }
27
+ export function formatResumeFirstFailedRunDetail(run) {
28
+ if (run.state !== "failed")
29
+ return;
30
+ const detachGuidance = formatIntercomDetachGuidance(run);
31
+ if (detachGuidance)
32
+ return detachGuidance;
33
+ const command = formatAsyncReviveCommand(run);
34
+ if (!command)
35
+ return;
36
+ return `Resume-first: failed run "${run.id}" has a persisted child session. Revive the original run with ${command} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
37
+ }
38
+ export function formatResumeFirstFailedRunsNote(runs) {
39
+ const failedRuns = runs.filter((run) => run.state === "failed" || run.state === "partial");
40
+ const detachGuidance = failedRuns.map(formatIntercomDetachGuidance).filter((guidance) => Boolean(guidance));
41
+ const resumable = failedRuns.filter((run) => !isIntercomDetached(run)).map((run) => ({ run, command: formatAsyncReviveCommand(run) })).filter((entry) => Boolean(entry.command));
42
+ const resumeGuidance = resumable.length === 0 ? "" : resumable.length === 1 ? ` Resume-first: failed run "${resumable[0].run.id}" has a persisted child session. Revive the original run with ${resumable[0].command} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.` : ` Resume-first: ${resumable.length} failed runs have persisted child sessions. Inspect status and revive each original run before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
43
+ return `${detachGuidance.length > 0 ? ` ${detachGuidance.join(" ")}` : ""}${resumeGuidance}`;
44
+ }
@@ -0,0 +1,119 @@
1
+ import * as fs from "node:fs";
2
+ import { listAsyncRuns } from "./async-status.js";
3
+ import { readAsyncRecoveryDescriptor } from "./async-resume.js";
4
+ import { parallelHandoffPath, resolveRetainedWorktreeCwd } from "../shared/parallel-handoff.js";
5
+ const MAX_RETAINED_CHILDREN = 10;
6
+ const MAX_RETAINED_CHILD_CANDIDATES = 100;
7
+ const MAX_TASK_SUMMARY_LENGTH = 120;
8
+ function isRetainedChildState(state) {
9
+ return state === "complete" || state === "failed" || state === "partial" || state === "paused" || state === "stopped";
10
+ }
11
+ function isTerminalStepStatus(status) {
12
+ return status === "complete" || status === "completed" || status === "failed" || status === "paused" || status === "stopped";
13
+ }
14
+ function retainedSessionFile(sessionFile) {
15
+ if (!sessionFile)
16
+ return { state: "not-resumable", reason: "no persisted session file" };
17
+ if (!sessionFile.endsWith(".jsonl"))
18
+ return { state: "not-resumable", reason: "persisted session file is not a .jsonl file" };
19
+ try {
20
+ const stat = fs.lstatSync(sessionFile);
21
+ if (!stat.isFile() || stat.isSymbolicLink())
22
+ return { state: "not-resumable", reason: "persisted session file is not a regular file" };
23
+ return { state: "resumable", sessionPath: sessionFile };
24
+ } catch (error) {
25
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
26
+ return { state: "not-resumable", reason: `persisted session file is missing: ${sessionFile}` };
27
+ }
28
+ return { state: "not-resumable", reason: `persisted session file could not be inspected: ${error instanceof Error ? error.message : String(error)}` };
29
+ }
30
+ }
31
+ function childResumability(run, step) {
32
+ if (run.state === "stopped" || step.status === "stopped")
33
+ return { state: "not-resumable", reason: "stopped run" };
34
+ if (step.runner?.type === "external-cli" || step.runner?.type === "external-job")
35
+ return { state: "not-resumable", reason: "external runner" };
36
+ const session = retainedSessionFile(step.sessionFile ?? run.sessionFile);
37
+ if (session.state === "not-resumable")
38
+ return session;
39
+ let recoveryDescriptor;
40
+ try {
41
+ recoveryDescriptor = readAsyncRecoveryDescriptor(run.asyncDir);
42
+ if (!recoveryDescriptor)
43
+ return { state: "not-resumable", reason: "missing recovery descriptor" };
44
+ if (recoveryDescriptor.sourceRunId !== run.id)
45
+ return { state: "not-resumable", reason: `recovery descriptor belongs to run ${recoveryDescriptor.sourceRunId}` };
46
+ if (recoveryDescriptor.agent !== step.agent)
47
+ return { state: "not-resumable", reason: `recovery descriptor belongs to agent ${recoveryDescriptor.agent}` };
48
+ } catch (error) {
49
+ return { state: "not-resumable", reason: `invalid recovery descriptor: ${error instanceof Error ? error.message : String(error)}` };
50
+ }
51
+ let requiredCwd;
52
+ try {
53
+ requiredCwd = resolveRetainedWorktreeCwd(parallelHandoffPath(run.asyncDir), run.id, step.index) ?? recoveryDescriptor.cwd ?? run.cwd;
54
+ if (!requiredCwd || !fs.statSync(requiredCwd).isDirectory())
55
+ return { state: "not-resumable", reason: `required cwd is missing: ${requiredCwd ?? "unknown"}` };
56
+ } catch (error) {
57
+ return { state: "not-resumable", reason: `resume dependency unavailable: ${error instanceof Error ? error.message : String(error)}` };
58
+ }
59
+ return session;
60
+ }
61
+ function boundedTaskSummary(value) {
62
+ const normalized = value?.replace(/\s+/g, " ").trim() ?? "";
63
+ return normalized.length > MAX_TASK_SUMMARY_LENGTH ? `${normalized.slice(0, MAX_TASK_SUMMARY_LENGTH - 1)}…` : normalized;
64
+ }
65
+ export function listRetainedChildren(asyncDirRoot, sessionId) {
66
+ const children = listAsyncRuns(asyncDirRoot, { sessionId, states: ["complete", "failed", "paused", "stopped"], entryLimit: MAX_RETAINED_CHILD_CANDIDATES, reconcile: false }).flatMap((run) => {
67
+ if (!run.parentWorkflowRunId || run.steps.length !== 1)
68
+ return [];
69
+ if (!isRetainedChildState(run.state))
70
+ return [];
71
+ const step = run.steps[0];
72
+ if (!isTerminalStepStatus(step.status))
73
+ return [];
74
+ const completedAt = run.endedAt ?? run.lastUpdate;
75
+ if (completedAt === undefined)
76
+ return [];
77
+ const resumability = childResumability(run, step);
78
+ return [{
79
+ runId: run.id,
80
+ ...run.parentWorkflowRunId ? { parentRunId: run.parentWorkflowRunId } : {},
81
+ ...run.workflowKey ? { workflowKey: run.workflowKey } : {},
82
+ state: run.state,
83
+ agent: step.agent,
84
+ taskSummary: boundedTaskSummary(step.description),
85
+ completedAt,
86
+ resumability,
87
+ ...resumability.state === "resumable" ? { sessionPath: resumability.sessionPath } : {},
88
+ ...step.tokens ?? run.totalTokens ? { tokenTotals: step.tokens ?? run.totalTokens } : {}
89
+ }];
90
+ }).sort((left, right) => right.completedAt - left.completedAt);
91
+ return children;
92
+ }
93
+ export function formatRetainedChildren(children) {
94
+ if (children.length === 0)
95
+ return "No retained workflow children in the active parent session. If a retained-writer challenge is required, launch a same-role fallback challenge and label it as fallback.";
96
+ const retained = children.slice(0, MAX_RETAINED_CHILDREN);
97
+ if (!retained.some((child) => child.resumability.state === "resumable")) {
98
+ const resumable = children.slice(MAX_RETAINED_CHILDREN).find((child) => child.resumability.state === "resumable");
99
+ if (resumable && retained.length === MAX_RETAINED_CHILDREN)
100
+ retained[MAX_RETAINED_CHILDREN - 1] = resumable;
101
+ }
102
+ const hasResumableChild = retained.some((child) => child.resumability.state === "resumable");
103
+ return [
104
+ `Retained workflow children (up to ${MAX_RETAINED_CHILDREN}; newest first, with a resumable child retained when available):`,
105
+ ...retained.flatMap((child) => [
106
+ `- ${child.runId} | ${child.agent} | ${child.state} | ${new Date(child.completedAt).toISOString()}`,
107
+ ...child.parentRunId ? [` workflow: ${child.parentRunId}${child.workflowKey ? ` (${child.workflowKey})` : ""}`] : [],
108
+ ` task: ${child.taskSummary || "(no task summary)"}`,
109
+ child.resumability.state === "resumable" ? " resumability: resumable" : ` resumability: not resumable (${child.resumability.reason})`,
110
+ ...child.resumability.state === "resumable" ? [
111
+ ` session: ${child.resumability.sessionPath}`,
112
+ ` resume: subagent({ action: "resume", id: "${child.runId}", message: "..." })`
113
+ ] : [],
114
+ ...child.tokenTotals ? [` tokens: input ${child.tokenTotals.input}, output ${child.tokenTotals.output}, total ${child.tokenTotals.total}`] : []
115
+ ]),
116
+ ...hasResumableChild ? [] : ["No resumable retained child is listed. Launch a same-role fallback challenge and label it as fallback."]
117
+ ].join(`
118
+ `);
119
+ }
@@ -0,0 +1,5 @@
1
+ export const MIN_SAFE_ASYNC_RUN_PREFIX_LENGTH = 8;
2
+ const FULL_ASYNC_RUN_ID_LENGTH = 36;
3
+ export function canScanAsyncRunPrefix(id) {
4
+ return id.length >= MIN_SAFE_ASYNC_RUN_PREFIX_LENGTH && id.length < FULL_ASYNC_RUN_ID_LENGTH;
5
+ }
@@ -1,23 +1,99 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import { ASYNC_DIR, RESULTS_DIR } from "../../shared/types.js";
3
+ import { DIRS } from "../../shared/types.js";
4
+ import { readStatus } from "../../shared/utils.js";
4
5
  import { findAsyncRunPrefixMatches } from "./async-resume.js";
6
+ import { resultCandidateFilesForToolCall, resultFilePath, resultPayloadPathForIndexedRun } from "./result-files.js";
7
+ import { readActiveRunToolCallIndex } from "./active-run-index.js";
5
8
  import { assertSafeNestedId, findNestedRunMatchesById } from "../shared/nested-events.js";
6
9
  function exactAsyncLocation(id, asyncDirRoot, resultsDir) {
7
10
  const asyncDir = path.join(asyncDirRoot, id);
8
- const resultPath = path.join(resultsDir, `${id}.json`);
9
- if (!fs.existsSync(asyncDir) && !fs.existsSync(resultPath))
11
+ const asyncDirExists = fs.existsSync(asyncDir);
12
+ const resultPath = resultPathFor(resultsDir, id);
13
+ if (!asyncDirExists && !resultPath)
10
14
  return;
11
15
  return {
12
- asyncDir: fs.existsSync(asyncDir) ? asyncDir : null,
13
- resultPath: fs.existsSync(resultPath) ? resultPath : null,
16
+ asyncDir: asyncDirExists ? asyncDir : null,
17
+ resultPath,
14
18
  resolvedId: id
15
19
  };
16
20
  }
21
+ function readWorkflowResultIdentity(resultPath) {
22
+ let parsed;
23
+ try {
24
+ parsed = JSON.parse(fs.readFileSync(resultPath, "utf-8"));
25
+ } catch {
26
+ return;
27
+ }
28
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
29
+ return;
30
+ const record = parsed;
31
+ return {
32
+ ...typeof record.id === "string" ? { id: record.id } : {},
33
+ ...typeof record.runId === "string" ? { runId: record.runId } : {},
34
+ ...typeof record.toolCallId === "string" ? { toolCallId: record.toolCallId } : {}
35
+ };
36
+ }
37
+ function resultPathFor(resultsDir, runId) {
38
+ const resultPath = resultPayloadPathForIndexedRun(resultsDir, runId) ?? resultFilePath(resultsDir, runId);
39
+ return fs.existsSync(resultPath) ? resultPath : null;
40
+ }
41
+ function toolCallIdMatches(value, query) {
42
+ return value === query;
43
+ }
44
+ function indexedToolCallIdAsyncLocations(toolCallId, asyncDirRoot, resultsDir) {
45
+ const byId = new Map;
46
+ for (const entry of readActiveRunToolCallIndex(asyncDirRoot, toolCallId)) {
47
+ const asyncDir = path.join(asyncDirRoot, entry);
48
+ const status = readStatus(asyncDir);
49
+ if (!status || !toolCallIdMatches(status.toolCallId, toolCallId))
50
+ continue;
51
+ const runId = status.runId || entry;
52
+ byId.set(runId, { asyncDir, resultPath: resultPathFor(resultsDir, runId), resolvedId: runId });
53
+ }
54
+ for (const entry of resultCandidateFilesForToolCall(resultsDir, toolCallId)) {
55
+ const runIdFromFile = entry.slice(0, -".json".length);
56
+ const resultPath = resultPayloadPathForIndexedRun(resultsDir, runIdFromFile) ?? path.join(resultsDir, entry);
57
+ const identity = readWorkflowResultIdentity(resultPath);
58
+ if (!identity || !toolCallIdMatches(identity.toolCallId, toolCallId))
59
+ continue;
60
+ const runId = identity.runId ?? identity.id ?? runIdFromFile;
61
+ const asyncDir = path.join(asyncDirRoot, runId);
62
+ byId.set(runId, { asyncDir: fs.existsSync(asyncDir) ? asyncDir : null, resultPath, resolvedId: runId });
63
+ }
64
+ return [...byId.entries()].map(([id, location]) => ({ id, location }));
65
+ }
17
66
  function foregroundIds(state) {
18
67
  if (!state)
19
68
  return [];
20
- return [...new Set([...state.foregroundControls.keys(), ...state.foregroundRuns?.keys() ?? []])];
69
+ const remembered = state.currentSessionId ? [...state.foregroundRuns?.values() ?? []].filter((run) => run.sessionId === state.currentSessionId).map((run) => run.runId) : [];
70
+ return [...new Set([...state.foregroundControls.keys(), ...remembered])];
71
+ }
72
+ function hasExactForegroundId(state, id) {
73
+ if (!state)
74
+ return false;
75
+ if (state.foregroundControls.has(id))
76
+ return true;
77
+ const remembered = state.foregroundRuns?.get(id);
78
+ return Boolean(remembered && state.currentSessionId && remembered.sessionId === state.currentSessionId);
79
+ }
80
+ function exactLiveAsyncToolCallMatch(state, toolCallId, asyncDirRoot, resultsDir) {
81
+ if (!state?.asyncJobs)
82
+ return;
83
+ const matches = [...state.asyncJobs.values()].filter((job) => job.toolCallId === toolCallId);
84
+ if (matches.length > 1)
85
+ throw new Error(`Subagent tool-call id '${toolCallId}' is ambiguous across async runs. Use the returned asyncId instead.`);
86
+ const match = matches[0];
87
+ if (!match)
88
+ return;
89
+ return {
90
+ id: match.asyncId,
91
+ location: {
92
+ asyncDir: fs.existsSync(match.asyncDir) ? match.asyncDir : path.join(asyncDirRoot, match.asyncId),
93
+ resultPath: resultPathFor(resultsDir, match.asyncId),
94
+ resolvedId: match.asyncId
95
+ }
96
+ };
21
97
  }
22
98
  function nestedScopeFromState(state) {
23
99
  if (!state)
@@ -44,14 +120,22 @@ function asyncPrefixMatches(prefix, asyncDirRoot, resultsDir) {
44
120
  }
45
121
  export function resolveSubagentRunId(id, deps = {}) {
46
122
  assertSafeNestedId("id", id);
47
- const asyncDirRoot = deps.asyncDirRoot ?? ASYNC_DIR;
48
- const resultsDir = deps.resultsDir ?? RESULTS_DIR;
123
+ const asyncDirRoot = deps.asyncDirRoot ?? DIRS.async;
124
+ const resultsDir = deps.resultsDir ?? DIRS.results;
49
125
  const nestedScope = deps.nested ?? nestedScopeFromState(deps.state);
50
- if (deps.state?.foregroundControls.has(id) || deps.state?.foregroundRuns?.has(id))
126
+ if (hasExactForegroundId(deps.state, id))
51
127
  return { kind: "foreground", id };
52
128
  const exactAsync = exactAsyncLocation(id, asyncDirRoot, resultsDir);
53
129
  if (exactAsync)
54
130
  return { kind: "async", id, location: exactAsync };
131
+ const exactLiveToolCallMatch = exactLiveAsyncToolCallMatch(deps.state, id, asyncDirRoot, resultsDir);
132
+ if (exactLiveToolCallMatch)
133
+ return { kind: "async", id: exactLiveToolCallMatch.id, location: exactLiveToolCallMatch.location };
134
+ const exactToolCallIdMatches = indexedToolCallIdAsyncLocations(id, asyncDirRoot, resultsDir);
135
+ if (exactToolCallIdMatches.length > 1)
136
+ throw new Error(`Subagent tool-call id '${id}' is ambiguous across async runs. Use the returned asyncId instead.`);
137
+ if (exactToolCallIdMatches[0])
138
+ return { kind: "async", id: exactToolCallIdMatches[0].id, location: exactToolCallIdMatches[0].location };
55
139
  const exactNested = findNestedRunMatchesById(id, nestedScope ? { scope: nestedScope } : {});
56
140
  if (exactNested.length > 1)
57
141
  throw new Error(`Nested run id '${id}' is ambiguous across authorized registries. Provide the full id after stale registries are cleaned up.`);