@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
@@ -1,9 +1,14 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { writeAtomicJson } from "../../shared/atomic-json.js";
4
- import { RESULTS_DIR } from "../../shared/types.js";
4
+ import { resultFilePath, resultPayloadPathForSessionRun, writeAsyncResultFile } from "./result-files.js";
5
+ import { updateActiveRunIndex } from "./active-run-index.js";
6
+ import { readStatus } from "../../shared/utils.js";
7
+ import { DIRS } from "../../shared/types.js";
8
+ import { resolveEffectiveThinking } from "../../shared/model-info.js";
5
9
  import { normalizeParallelGroups } from "./parallel-groups.js";
6
10
  import { nestedSummaryFromAsyncStatus, projectNestedEvents, resolveNestedAsyncDir, writeNestedEvent } from "../shared/nested-events.js";
11
+ import { assertWorkflowGraphHostSteps } from "../shared/host-step-status.js";
7
12
  function getErrorMessage(error) {
8
13
  return error instanceof Error ? error.message : String(error);
9
14
  }
@@ -45,31 +50,30 @@ function appendJsonlBestEffort(filePath, payload) {
45
50
  `, "utf-8");
46
51
  } catch {}
47
52
  }
48
- function readStatusFile(asyncDir) {
49
- const statusPath = path.join(asyncDir, "status.json");
50
- let content;
53
+ function regularFileExists(filePath) {
51
54
  try {
52
- content = fs.readFileSync(statusPath, "utf-8");
55
+ return fs.statSync(filePath).isFile();
53
56
  } catch (error) {
54
57
  if (isNotFoundError(error))
55
- return null;
56
- throw new Error(`Failed to read async status file '${statusPath}': ${getErrorMessage(error)}`, {
57
- cause: error instanceof Error ? error : undefined
58
- });
59
- }
60
- try {
61
- return JSON.parse(content);
62
- } catch (error) {
63
- throw new Error(`Failed to parse async status file '${statusPath}': ${getErrorMessage(error)}`, {
64
- cause: error instanceof Error ? error : undefined
65
- });
58
+ return false;
59
+ throw error;
66
60
  }
67
61
  }
68
62
  function readResultRepairData(resultPath) {
69
63
  try {
70
64
  const data = JSON.parse(fs.readFileSync(resultPath, "utf-8"));
71
- const state = data.success ? "complete" : data.state === "paused" || data.exitCode === 0 ? "paused" : "failed";
72
- return { state, ...Array.isArray(data.results) ? { results: data.results } : {} };
65
+ const state = data.success ? "complete" : data.state === "stopped" ? "stopped" : data.state === "rejected" ? "rejected" : data.state === "partial" ? "partial" : data.state === "paused" || data.exitCode === 0 ? "paused" : "failed";
66
+ const results = Array.isArray(data.results) ? data.results.map((entry, index) => {
67
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
68
+ return {};
69
+ const child = entry;
70
+ if (child.model !== undefined && typeof child.model !== "string")
71
+ throw new Error(`Invalid async result file '${resultPath}': results[${index}].model must be a string.`);
72
+ if (child.thinking !== undefined && typeof child.thinking !== "string")
73
+ throw new Error(`Invalid async result file '${resultPath}': results[${index}].thinking must be a string.`);
74
+ return child;
75
+ }) : undefined;
76
+ return { state, ...results ? { results } : {} };
73
77
  } catch (error) {
74
78
  if (isNotFoundError(error))
75
79
  return;
@@ -94,27 +98,39 @@ function terminalStatusFromResult(status, resultPath, now) {
94
98
  return step;
95
99
  const child = repair.results?.[index];
96
100
  const state = childState(repair.state, child);
101
+ const model = child?.model ?? step.model;
102
+ const thinking = resolveEffectiveThinking(model, child?.thinking ?? step.thinking);
97
103
  return {
98
104
  ...step,
99
105
  status: state === "complete" ? "complete" : state,
100
106
  endedAt: step.endedAt ?? now,
101
107
  durationMs: step.startedAt !== undefined && step.durationMs === undefined ? Math.max(0, now - step.startedAt) : step.durationMs,
102
108
  exitCode: step.exitCode ?? (state === "complete" || state === "paused" ? 0 : 1),
103
- error: state === "failed" ? step.error ?? child?.error : step.error,
109
+ error: state === "failed" || state === "partial" || state === "stopped" ? step.error ?? child?.error : step.error,
110
+ stopped: state === "stopped" ? true : step.stopped,
111
+ sessionName: step.sessionName ?? child?.sessionName,
104
112
  sessionFile: step.sessionFile ?? child?.sessionFile,
105
- model: step.model ?? child?.model,
106
- attemptedModels: step.attemptedModels ?? child?.attemptedModels,
107
- modelAttempts: step.modelAttempts ?? child?.modelAttempts
113
+ model,
114
+ thinking,
115
+ attemptedModels: child?.attemptedModels ?? step.attemptedModels,
116
+ modelAttempts: child?.modelAttempts ?? step.modelAttempts,
117
+ contextOverflow: child?.contextOverflow ?? step.contextOverflow
108
118
  };
109
119
  });
110
- return {
120
+ const terminalStatus = {
111
121
  ...status,
112
122
  state: repair.state,
123
+ ...status.lifecycleArtifactVersion === 3 && (!status.processTerminal || status.processTerminal.state === "pending") ? {
124
+ processTerminal: { version: 1, state: "unknown", runId: status.runId, runnerProcessInstanceId: "observer-unavailable", reason: "observer-unavailable" }
125
+ } : {},
126
+ ...repair.state === "stopped" ? { stopped: true } : {},
113
127
  activityState: undefined,
114
128
  lastUpdate: now,
115
129
  endedAt: status.endedAt ?? now,
116
130
  steps
117
131
  };
132
+ delete terminalStatus.displayDismissedAt;
133
+ return terminalStatus;
118
134
  }
119
135
  function buildStartedStatus(asyncDir, startedRun, now) {
120
136
  const startedAt = startedRun.startedAt ?? now;
@@ -124,6 +140,7 @@ function buildStartedStatus(asyncDir, startedRun, now) {
124
140
  return {
125
141
  runId: startedRun.runId || path.basename(asyncDir),
126
142
  ...startedRun.sessionId ? { sessionId: startedRun.sessionId } : {},
143
+ ...startedRun.completionOwnerId ? { completionOwnerId: startedRun.completionOwnerId } : {},
127
144
  mode: startedRun.mode ?? "single",
128
145
  state: "running",
129
146
  pid: startedRun.pid,
@@ -162,6 +179,9 @@ ${diagnostics}` : baseMessage;
162
179
  const repairedStatus = {
163
180
  ...status,
164
181
  state: "failed",
182
+ ...status.lifecycleArtifactVersion === 3 && (!status.processTerminal || status.processTerminal.state === "pending") ? {
183
+ processTerminal: { version: 1, state: "unknown", runId, runnerProcessInstanceId: "observer-unavailable", reason: "stale-repair" }
184
+ } : {},
165
185
  activityState: undefined,
166
186
  lastUpdate: now,
167
187
  endedAt: now,
@@ -175,17 +195,20 @@ ${diagnostics}` : baseMessage;
175
195
  id: runId,
176
196
  agent: resultAgent,
177
197
  mode: status.mode,
198
+ ...status.completionOwnerId ? { completionOwnerId: status.completionOwnerId } : {},
178
199
  success: false,
179
200
  state: "failed",
180
201
  summary: message,
181
202
  results: repairedSteps.map((step) => ({
182
203
  agent: step.agent,
204
+ ...step.sessionName ? { sessionName: step.sessionName } : {},
183
205
  output: step.status === "complete" || step.status === "completed" ? "" : message,
184
206
  error: step.status === "complete" || step.status === "completed" ? undefined : step.error ?? message,
185
207
  success: step.status === "complete" || step.status === "completed",
186
208
  model: step.model,
187
209
  attemptedModels: step.attemptedModels,
188
210
  modelAttempts: step.modelAttempts,
211
+ contextOverflow: step.contextOverflow,
189
212
  sessionFile: step.sessionFile
190
213
  })),
191
214
  exitCode: 1,
@@ -199,20 +222,22 @@ ${diagnostics}` : baseMessage;
199
222
  }
200
223
  function writeFailedRepair(asyncDir, status, resultPath, now, reason) {
201
224
  const repair = buildFailedRepair(status, asyncDir, now, reason);
202
- writeAtomicJson(resultPath, repair.result);
225
+ if (repair.result.sessionId)
226
+ writeAsyncResultFile(resultPath, repair.result);
203
227
  writeAtomicJson(path.join(asyncDir, "status.json"), repair.status);
228
+ updateActiveRunIndex(asyncDir, repair.status.state, repair.status.toolCallId);
204
229
  appendJsonlBestEffort(path.join(asyncDir, "events.jsonl"), {
205
230
  type: "subagent.run.repaired_stale",
206
231
  ts: now,
207
232
  runId: repair.status.runId,
208
233
  pid: status.pid,
209
- resultPath,
234
+ ...repair.result.sessionId ? { resultPath } : {},
210
235
  message: repair.message
211
236
  });
212
- return { status: repair.status, repaired: true, resultPath, message: repair.message };
237
+ return { status: repair.status, repaired: true, ...repair.result.sessionId ? { resultPath } : {}, message: repair.message };
213
238
  }
214
239
  function terminal(state) {
215
- return state === "complete" || state === "failed" || state === "paused";
240
+ return state === "complete" || state === "failed" || state === "partial" || state === "paused" || state === "stopped" || state === "rejected";
216
241
  }
217
242
  function* nestedRuns(children) {
218
243
  for (const child of children ?? []) {
@@ -231,7 +256,7 @@ export function reconcileNestedAsyncDescendants(route, options = {}) {
231
256
  continue;
232
257
  const result = reconcileAsyncRun(asyncDir, {
233
258
  ...options,
234
- resultsDir: path.join(options.resultsDir ?? RESULTS_DIR, "nested", route.rootRunId)
259
+ resultsDir: path.join(options.resultsDir ?? DIRS.results, "nested", route.rootRunId)
235
260
  });
236
261
  const status = result.status;
237
262
  if (!status)
@@ -271,20 +296,36 @@ export function checkPidLiveness(pid, kill = process.kill) {
271
296
  }
272
297
  export function reconcileAsyncRun(asyncDir, options = {}) {
273
298
  const now = options.now?.() ?? Date.now();
274
- const status = readStatusFile(asyncDir);
299
+ const status = readStatus(asyncDir);
275
300
  const startedStatus = !status && options.startedRun ? buildStartedStatus(asyncDir, options.startedRun, now) : undefined;
276
301
  const effectiveStatus = status ?? startedStatus;
277
302
  if (!effectiveStatus)
278
303
  return { status: null, repaired: false };
304
+ assertWorkflowGraphHostSteps(effectiveStatus.workflowGraph, path.join(asyncDir, "status.json"), effectiveStatus.runId);
305
+ const statusPath = path.join(asyncDir, "status.json");
306
+ for (const [index, step] of (effectiveStatus.steps ?? []).entries()) {
307
+ const stepRecord = step;
308
+ if (stepRecord.model !== undefined && typeof stepRecord.model !== "string")
309
+ throw new Error(`Invalid async status file '${statusPath}': steps[${index}].model must be a string.`);
310
+ if (stepRecord.thinking !== undefined && typeof stepRecord.thinking !== "string")
311
+ throw new Error(`Invalid async status file '${statusPath}': steps[${index}].thinking must be a string.`);
312
+ }
279
313
  const runId = effectiveStatus.runId || path.basename(asyncDir);
280
- const resultPath = path.join(options.resultsDir ?? RESULTS_DIR, `${runId}.json`);
281
- if (fs.existsSync(resultPath)) {
282
- const terminalStatus = effectiveStatus.state === "running" || effectiveStatus.state === "queued" ? terminalStatusFromResult(effectiveStatus, resultPath, now) : undefined;
314
+ const resultsDir = options.resultsDir ?? DIRS.results;
315
+ const resultPath = resultFilePath(resultsDir, runId);
316
+ const existingResultPath = effectiveStatus.sessionId ? resultPayloadPathForSessionRun(resultsDir, effectiveStatus.sessionId, runId) ?? (regularFileExists(resultPath) ? resultPath : undefined) : regularFileExists(resultPath) ? resultPath : undefined;
317
+ if (existingResultPath) {
318
+ const terminalStatus = effectiveStatus.state === "running" || effectiveStatus.state === "queued" ? terminalStatusFromResult(effectiveStatus, existingResultPath, now) : undefined;
283
319
  if (terminalStatus) {
284
320
  writeAtomicJson(path.join(asyncDir, "status.json"), terminalStatus);
285
- return { status: terminalStatus, repaired: true, resultPath, message: "Existing async result file was used to repair stale running status." };
321
+ updateActiveRunIndex(asyncDir, terminalStatus.state, terminalStatus.toolCallId);
322
+ return { status: terminalStatus, repaired: true, resultPath: existingResultPath, message: "Existing async result file was used to repair stale running status." };
286
323
  }
287
- return { status: effectiveStatus, repaired: false, resultPath };
324
+ if (effectiveStatus.displayDismissedAt === undefined)
325
+ return { status: effectiveStatus, repaired: false, resultPath: existingResultPath };
326
+ }
327
+ if (effectiveStatus.displayDismissedAt !== undefined) {
328
+ return { status: null, repaired: false, resultPath };
288
329
  }
289
330
  if (effectiveStatus.state !== "running" || typeof effectiveStatus.pid !== "number") {
290
331
  return { status: status ?? null, repaired: false, resultPath };
@@ -0,0 +1,221 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { writePrivateAtomicJson } from "../../shared/atomic-json.js";
4
+ import { readStatus } from "../../shared/utils.js";
5
+ import { previewDisplayText } from "../../shared/display-text.js";
6
+ import { redactSecretValues } from "../shared/permissions.js";
7
+ export const MAX_STEERING_REQUESTS = 20;
8
+ export const STEERING_MESSAGE_PREVIEW_LIMIT = 160;
9
+ export function steeringMessagePreview(message) {
10
+ return previewDisplayText(redactSecretValues(message), STEERING_MESSAGE_PREVIEW_LIMIT);
11
+ }
12
+ export function steeringReceipt(message, receipt) {
13
+ return `${receipt} Message: ${JSON.stringify(steeringMessagePreview(message))}`;
14
+ }
15
+ export function createSteeringStatus() {
16
+ return { requested: 0, scheduled: 0, pending: 0, delivered: 0, failed: 0, recovered: 0, recent: [] };
17
+ }
18
+ export function steeringStatus(status) {
19
+ return status.steering ?? createSteeringStatus();
20
+ }
21
+ export function recordSteeringRequest(status, input) {
22
+ const existing = status.recent.find((request) => request.id === input.id);
23
+ if (existing)
24
+ return existing;
25
+ const request = {
26
+ id: input.id,
27
+ requestedAt: input.requestedAt,
28
+ ...input.source ? { source: input.source } : {},
29
+ messagePreview: steeringMessagePreview(input.message),
30
+ targets: input.targets.map((target) => ({ index: target.index, state: target.state, ...target.reason ? { reason: target.reason } : {} }))
31
+ };
32
+ status.requested++;
33
+ status.lastRequestedAt = input.requestedAt;
34
+ status.recent = [...status.recent, request].slice(-MAX_STEERING_REQUESTS);
35
+ for (const target of request.targets)
36
+ incrementStateCount(status, target.state);
37
+ return request;
38
+ }
39
+ function incrementStateCount(status, state) {
40
+ if (state === "scheduled")
41
+ status.scheduled++;
42
+ else if (state === "routed" || state === "queued")
43
+ status.pending++;
44
+ else if (state === "delivered" || state === "late")
45
+ status.delivered++;
46
+ else if (state === "failed")
47
+ status.failed++;
48
+ else if (state === "recovered")
49
+ status.recovered++;
50
+ }
51
+ export function updateSteeringTarget(status, requestId, index, state, now, fields = {}) {
52
+ const request = status.recent.find((candidate) => candidate.id === requestId);
53
+ const target = request?.targets.find((candidate) => candidate.index === index);
54
+ if (!target)
55
+ return;
56
+ if (state === "late" && target.state === "recovered") {
57
+ if (target.lateDeliveredAt === undefined) {
58
+ target.lateDeliveredAt = now;
59
+ status.delivered++;
60
+ status.lastDeliveredAt = now;
61
+ }
62
+ if (fields.reason)
63
+ target.reason = fields.reason;
64
+ return target;
65
+ }
66
+ if (target.state === state) {
67
+ if (state === "routed" && target.routedAt === undefined)
68
+ target.routedAt = now;
69
+ if (state === "delivered" && target.deliveredAt === undefined)
70
+ target.deliveredAt = now;
71
+ if (state === "late" && target.lateDeliveredAt === undefined)
72
+ target.lateDeliveredAt = now;
73
+ if (fields.reason)
74
+ target.reason = fields.reason;
75
+ if (fields.replacementRunId)
76
+ target.replacementRunId = fields.replacementRunId;
77
+ return target;
78
+ }
79
+ if ((target.state === "routed" || target.state === "queued") && state !== "routed" && state !== "queued")
80
+ status.pending = Math.max(0, status.pending - 1);
81
+ target.state = state;
82
+ if (state === "routed")
83
+ target.routedAt = now;
84
+ if (state === "delivered") {
85
+ target.deliveredAt = now;
86
+ status.lastDeliveredAt = now;
87
+ }
88
+ if (state === "late") {
89
+ target.lateDeliveredAt = now;
90
+ status.lastDeliveredAt = now;
91
+ }
92
+ if (state === "failed")
93
+ target.failedAt = now;
94
+ if (state === "recovered")
95
+ target.recoveredAt = now;
96
+ if (fields.reason)
97
+ target.reason = fields.reason;
98
+ if (fields.replacementRunId)
99
+ target.replacementRunId = fields.replacementRunId;
100
+ incrementStateCount(status, state);
101
+ return target;
102
+ }
103
+ export function findSteeringRequest(status, requestId) {
104
+ return status.recent.find((request) => request.id === requestId);
105
+ }
106
+ export function actionResultFromSteeringStatus(status, sourceRunId, requestId, replacementRunId) {
107
+ const request = findSteeringRequest(status, requestId);
108
+ if (!request)
109
+ return;
110
+ const targets = request.targets.map((target) => ({
111
+ index: target.index,
112
+ state: target.state,
113
+ ...target.deliveredAt !== undefined ? { deliveredAt: target.deliveredAt } : {},
114
+ ...target.lateDeliveredAt !== undefined ? { lateDeliveredAt: target.lateDeliveredAt } : {},
115
+ ...target.reason ? { reason: target.reason } : {},
116
+ ...target.replacementRunId ? { replacementRunId: target.replacementRunId } : {}
117
+ }));
118
+ const states = targets.map((target) => target.state);
119
+ let state = "pending";
120
+ if (states.length > 0 && states.every((candidate) => candidate === "delivered"))
121
+ state = "delivered";
122
+ else if (states.length > 0 && states.every((candidate) => candidate === "scheduled"))
123
+ state = "scheduled";
124
+ else if (states.length > 0 && states.every((candidate) => candidate === "recovered"))
125
+ state = "recovered";
126
+ else if (states.length > 0 && states.every((candidate) => candidate === "failed" || candidate === "late"))
127
+ state = "failed";
128
+ else if (states.some((candidate) => candidate === "failed" || candidate === "late") && states.some((candidate) => candidate !== "failed" && candidate !== "late"))
129
+ state = "partial";
130
+ const effectiveReplacementRunId = replacementRunId ?? request.targets.find((target) => target.replacementRunId)?.replacementRunId;
131
+ const deliveryStatus = states.length > 0 && states.every((candidate) => candidate === "delivered" || candidate === "recovered") ? "delivered" : "queued";
132
+ return { requestId, state, deliveryStatus, sourceRunId, ...effectiveReplacementRunId ? { replacementRunId: effectiveReplacementRunId } : {}, targets };
133
+ }
134
+ export function steeringActionIsTerminal(result) {
135
+ return (result?.targets.length ?? 0) > 0 && result?.targets.every((target) => target.state === "queued" || target.state === "delivered") === true || result?.state === "delivered" || result?.state === "scheduled" || result?.state === "partial" || result?.state === "recovered" || result?.state === "failed";
136
+ }
137
+ export function terminalSteeringNoticeState(status, requestId) {
138
+ const request = status.recent.find((candidate) => candidate.id === requestId);
139
+ if (!request || request.targets.some((target) => target.state === "routed" || target.state === "queued" || target.state === "scheduled"))
140
+ return;
141
+ const hasSuccess = request.targets.some((target) => target.state === "delivered" || target.state === "recovered");
142
+ const hasFailure = request.targets.some((target) => target.state === "failed" || target.state === "late");
143
+ if (hasSuccess && hasFailure)
144
+ return "partial";
145
+ return hasFailure ? "failed" : undefined;
146
+ }
147
+ export function claimSteeringRecovery(asyncDir, input) {
148
+ const recoveryDir = path.join(asyncDir, "control", "steer-recovery");
149
+ fs.mkdirSync(recoveryDir, { recursive: true, mode: 448 });
150
+ const claimPath = path.join(recoveryDir, "claim.json");
151
+ let fd;
152
+ try {
153
+ fd = fs.openSync(claimPath, "wx", 384);
154
+ } catch (error) {
155
+ if (error.code === "EEXIST") {
156
+ throw new Error("Another steering recovery is already committed for this source run.");
157
+ }
158
+ throw error;
159
+ }
160
+ let writeError;
161
+ try {
162
+ fs.writeFileSync(fd, JSON.stringify({ version: 1, ...input }, null, 2), "utf-8");
163
+ fs.fsyncSync(fd);
164
+ } catch (error) {
165
+ writeError = error;
166
+ } finally {
167
+ fs.closeSync(fd);
168
+ }
169
+ if (writeError !== undefined) {
170
+ fs.rmSync(claimPath, { force: true });
171
+ throw writeError;
172
+ }
173
+ const markerPath = path.join(recoveryDir, `${Buffer.from(input.requestId).toString("base64url")}.json`);
174
+ try {
175
+ writePrivateAtomicJson(markerPath, { version: 1, ...input });
176
+ } catch (error) {
177
+ fs.rmSync(claimPath, { force: true });
178
+ throw error;
179
+ }
180
+ return { claimPath, markerPath };
181
+ }
182
+ export function readSteeringStatus(asyncDir) {
183
+ return readStatus(asyncDir)?.steering;
184
+ }
185
+ export function remainingSteeringRecoveryLimits(descriptor, status, now = Date.now()) {
186
+ const limits = {};
187
+ if (descriptor.absoluteDeadlineAt !== undefined) {
188
+ const timeoutMs = descriptor.absoluteDeadlineAt - now;
189
+ if (timeoutMs <= 0)
190
+ throw new Error("Source run has no remaining deadline budget; it remains paused.");
191
+ limits.timeoutMs = timeoutMs;
192
+ limits.absoluteDeadlineAt = descriptor.absoluteDeadlineAt;
193
+ }
194
+ if (descriptor.initialToolBudget) {
195
+ const consumed = status.toolBudget?.toolCount ?? status.toolCount ?? 0;
196
+ const hard = descriptor.initialToolBudget.hard - consumed;
197
+ if (hard <= 0)
198
+ throw new Error("Source run has no remaining tool budget; it remains paused.");
199
+ const soft = descriptor.initialToolBudget.soft === undefined ? undefined : descriptor.initialToolBudget.soft - consumed;
200
+ limits.toolBudget = {
201
+ hard,
202
+ ...soft !== undefined && soft > 0 && soft < hard ? { soft } : {},
203
+ block: descriptor.initialToolBudget.block
204
+ };
205
+ }
206
+ return limits;
207
+ }
208
+ export async function waitForSteeringAction(input) {
209
+ const deadline = Date.now() + input.timeoutMs;
210
+ while (Date.now() <= deadline) {
211
+ if (input.signal?.aborted)
212
+ return;
213
+ const status = readSteeringStatus(input.asyncDir);
214
+ const result = status ? actionResultFromSteeringStatus(status, input.sourceRunId, input.requestId) : undefined;
215
+ if (steeringActionIsTerminal(result))
216
+ return result;
217
+ await new Promise((resolve) => setTimeout(resolve, Math.min(50, Math.max(1, deadline - Date.now()))));
218
+ }
219
+ const status = readSteeringStatus(input.asyncDir);
220
+ return status ? actionResultFromSteeringStatus(status, input.sourceRunId, input.requestId) : undefined;
221
+ }