@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
@@ -18,47 +18,104 @@ export function checkModelScope(model, scope, source) {
18
18
  if (allow.some((pattern) => matchesScopePattern(model, pattern)))
19
19
  return;
20
20
  const baseModel = stripThinkingSuffix(model);
21
- const severity = source === "explicit" ? "error" : "warn";
21
+ const severity = source === "explicit" || scope.strict === true ? "error" : "warn";
22
+ const origin = scope.origin ?? "modelScope";
22
23
  return {
23
24
  model: baseModel,
24
25
  severity,
25
26
  allowedPatterns: allow,
26
- message: `Model '${baseModel}' is outside the configured subagent model scope. ` + `Allowed patterns: ${allow.join(", ")}.`
27
+ origin,
28
+ message: `Model '${baseModel}' is outside the configured subagent model scope (${origin}). ` + `Allowed patterns: ${allow.join(", ")}.`
27
29
  };
28
30
  }
29
- export function parseModelScopeConfig(value, meta) {
30
- if (value === undefined)
31
- return;
31
+ function expandInheritPattern(pattern, parentModel) {
32
+ return pattern === "inherit" && parentModel ? `${parentModel.provider}/${parentModel.id}` : pattern;
33
+ }
34
+ function assertRecord(value, field, meta, expected = "an object") {
32
35
  if (!value || typeof value !== "object" || Array.isArray(value)) {
33
- throw new Error(`Subagent settings in '${meta.filePath}' have invalid 'modelScope'; expected an object.`);
36
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid '${field}'; expected ${expected}.`);
34
37
  }
35
- const input = value;
36
- const config = {};
37
- if ("enforce" in input) {
38
- if (typeof input.enforce !== "boolean") {
39
- throw new Error(`Subagent settings in '${meta.filePath}' have invalid 'modelScope.enforce'; expected a boolean.`);
40
- }
41
- config.enforce = input.enforce;
38
+ return value;
39
+ }
40
+ function parseAllowList(value, field, meta) {
41
+ if (!Array.isArray(value)) {
42
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid '${field}'; expected an array of strings.`);
42
43
  }
43
- if ("allow" in input) {
44
- if (!Array.isArray(input.allow)) {
45
- throw new Error(`Subagent settings in '${meta.filePath}' have invalid 'modelScope.allow'; expected an array of strings.`);
44
+ const allow = [];
45
+ for (const entry of value) {
46
+ if (typeof entry !== "string") {
47
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid '${field}'; expected an array of strings.`);
46
48
  }
47
- const allow = [];
48
- for (const entry of input.allow) {
49
- if (typeof entry !== "string") {
50
- throw new Error(`Subagent settings in '${meta.filePath}' have invalid 'modelScope.allow'; expected an array of strings.`);
49
+ const trimmed = entry.trim();
50
+ if (trimmed)
51
+ allow.push(trimmed);
52
+ }
53
+ if (allow.length === 0) {
54
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid '${field}'; expected a non-empty array of patterns.`);
55
+ }
56
+ return allow;
57
+ }
58
+ function parseScopeRule(input, field, meta) {
59
+ const rule = {};
60
+ if ("enforce" in input) {
61
+ if (typeof input.enforce !== "boolean")
62
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid '${field}.enforce'; expected a boolean.`);
63
+ rule.enforce = input.enforce;
64
+ }
65
+ if ("strict" in input) {
66
+ if (typeof input.strict !== "boolean")
67
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid '${field}.strict'; expected a boolean.`);
68
+ rule.strict = input.strict;
69
+ }
70
+ if ("allow" in input)
71
+ rule.allow = parseAllowList(input.allow, `${field}.allow`, meta);
72
+ return rule;
73
+ }
74
+ export function resolveModelScopesForAgent(config, agentName, parentModel) {
75
+ if (!config)
76
+ return [];
77
+ const scopes = [];
78
+ if (config.allow) {
79
+ scopes.push({
80
+ ...config.enforce !== undefined ? { enforce: config.enforce } : {},
81
+ ...config.strict !== undefined ? { strict: config.strict } : {},
82
+ allow: config.allow.map((pattern) => expandInheritPattern(pattern, parentModel)),
83
+ origin: "modelScope"
84
+ });
85
+ }
86
+ const agentScope = config.agents?.[agentName];
87
+ if (agentScope?.allow) {
88
+ scopes.push({
89
+ enforce: agentScope.enforce ?? config.enforce,
90
+ strict: agentScope.strict ?? config.strict,
91
+ allow: agentScope.allow.map((pattern) => expandInheritPattern(pattern, parentModel)),
92
+ origin: `modelScope.agents.${agentName}`
93
+ });
94
+ }
95
+ return scopes;
96
+ }
97
+ export function parseModelScopeConfig(value, meta) {
98
+ if (value === undefined)
99
+ return;
100
+ const input = assertRecord(value, "modelScope", meta);
101
+ const config = parseScopeRule(input, "modelScope", meta);
102
+ if ("agents" in input) {
103
+ const agents = {};
104
+ for (const [rawName, rawScope] of Object.entries(assertRecord(input.agents, "modelScope.agents", meta, "an object keyed by agent name"))) {
105
+ const name = rawName.trim();
106
+ const field = `modelScope.agents.${name}`;
107
+ if (!name)
108
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid 'modelScope.agents' key; expected a non-empty agent name.`);
109
+ const agentInput = assertRecord(rawScope, field, meta);
110
+ if ("agents" in agentInput) {
111
+ throw new Error(`Subagent settings in '${meta.filePath}' have invalid '${field}.agents'; nested agent scopes are not supported.`);
51
112
  }
52
- const trimmed = entry.trim();
53
- if (trimmed)
54
- allow.push(trimmed);
55
- }
56
- if (allow.length === 0) {
57
- throw new Error(`Subagent settings in '${meta.filePath}' have invalid 'modelScope.allow'; expected a non-empty array of patterns.`);
113
+ agents[name] = parseScopeRule(agentInput, field, meta);
58
114
  }
59
- config.allow = allow;
115
+ config.agents = agents;
60
116
  }
61
- if (config.enforce === true && (!config.allow || config.allow.length === 0)) {
117
+ const hasAnyAllow = Boolean(config.allow?.length) || Object.values(config.agents ?? {}).some((scope) => Boolean(scope.allow?.length));
118
+ if (config.enforce === true && !hasAnyAllow) {
62
119
  throw new Error(`Subagent settings in '${meta.filePath}' set modelScope.enforce without a non-empty 'allow' list; supply allowed model patterns or disable enforcement.`);
63
120
  }
64
121
  return Object.keys(config).length > 0 ? config : undefined;
@@ -0,0 +1,182 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import * as fs from "node:fs";
4
+ import * as os from "node:os";
5
+ import * as path from "node:path";
6
+ const MAX_TRACKED_PATHS = 500;
7
+ const MAX_HASH_BYTES = 1024 * 1024;
8
+ const MAX_TIMEOUT_FILES = 20;
9
+ function gitArguments(args) {
10
+ return ["-c", "core.fsmonitor=false", ...args];
11
+ }
12
+ function gitOutput(cwd, args, maxBuffer = MAX_HASH_BYTES) {
13
+ return execFileSync("git", gitArguments(args), { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer, windowsHide: true });
14
+ }
15
+ function splitNul(output) {
16
+ return output.split("\x00").filter((part) => part.length > 0);
17
+ }
18
+ function hashLargeDiff(cwd, relativePath) {
19
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "dm-subagents-tracked-diff-"));
20
+ const diffPath = path.join(tempDir, "diff.patch");
21
+ try {
22
+ execFileSync("git", gitArguments(["diff", "--no-ext-diff", "--binary", `--output=${diffPath}`, "HEAD", "--", relativePath]), { cwd, stdio: "ignore", windowsHide: true });
23
+ const hash = createHash("sha256");
24
+ const buffer = Buffer.allocUnsafe(64 * 1024);
25
+ const fd = fs.openSync(diffPath, "r");
26
+ try {
27
+ for (;; ) {
28
+ const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null);
29
+ if (bytesRead === 0)
30
+ break;
31
+ hash.update(buffer.subarray(0, bytesRead));
32
+ }
33
+ } finally {
34
+ fs.closeSync(fd);
35
+ }
36
+ return hash.digest("hex");
37
+ } finally {
38
+ fs.rmSync(tempDir, { recursive: true, force: true });
39
+ }
40
+ }
41
+ function listChangedTrackedFiles(cwd) {
42
+ const paths = splitNul(gitOutput(cwd, ["diff", "--no-ext-diff", "--name-only", "-z", "HEAD", "--"], MAX_HASH_BYTES));
43
+ return { paths: paths.slice(0, MAX_TRACKED_PATHS), truncated: paths.length > MAX_TRACKED_PATHS };
44
+ }
45
+ function fingerprintPath(cwd, relativePath) {
46
+ try {
47
+ const diff = gitOutput(cwd, ["diff", "--no-ext-diff", "--binary", "HEAD", "--", relativePath], MAX_HASH_BYTES);
48
+ return { kind: "diff", digest: createHash("sha256").update(diff).digest("hex") };
49
+ } catch {
50
+ return { kind: "diff", digest: hashLargeDiff(cwd, relativePath) };
51
+ }
52
+ }
53
+ function sameFingerprint(left, right) {
54
+ if (!left || left.kind !== "diff" || right.kind !== "diff")
55
+ return false;
56
+ return left.digest === right.digest;
57
+ }
58
+ export function snapshotTrackedMutations(cwd) {
59
+ try {
60
+ const changed = listChangedTrackedFiles(cwd);
61
+ const fingerprints = {};
62
+ for (const file of changed.paths)
63
+ fingerprints[file] = fingerprintPath(cwd, file);
64
+ return { source: "tracked-files", trackedOnly: true, cwd, dirtyFiles: changed.paths, fingerprints, truncated: changed.truncated };
65
+ } catch (error) {
66
+ return { source: "tracked-files", trackedOnly: true, cwd, dirtyFiles: [], fingerprints: {}, unavailable: error instanceof Error ? error.message : String(error) };
67
+ }
68
+ }
69
+ export function collectTrackedMutationEvidence(snapshot, cwd = snapshot.cwd) {
70
+ if (snapshot.unavailable) {
71
+ return { source: "tracked-files", trackedOnly: true, changedFiles: [], attemptedMutation: false, unavailable: snapshot.unavailable };
72
+ }
73
+ try {
74
+ const current = listChangedTrackedFiles(cwd);
75
+ const startDirty = new Set(snapshot.dirtyFiles);
76
+ const candidates = new Set([...snapshot.dirtyFiles, ...current.paths]);
77
+ const changedFiles = [];
78
+ for (const file of candidates) {
79
+ if (!startDirty.has(file)) {
80
+ if (!snapshot.truncated)
81
+ changedFiles.push(file);
82
+ continue;
83
+ }
84
+ if (!sameFingerprint(snapshot.fingerprints[file], fingerprintPath(cwd, file)))
85
+ changedFiles.push(file);
86
+ }
87
+ changedFiles.sort();
88
+ return {
89
+ source: "tracked-files",
90
+ trackedOnly: true,
91
+ changedFiles,
92
+ attemptedMutation: changedFiles.length > 0,
93
+ truncated: snapshot.truncated || current.truncated || undefined
94
+ };
95
+ } catch (error) {
96
+ return { source: "tracked-files", trackedOnly: true, changedFiles: [], attemptedMutation: false, unavailable: error instanceof Error ? error.message : String(error) };
97
+ }
98
+ }
99
+ function formatPathList(paths) {
100
+ if (paths.length === 0)
101
+ return "none";
102
+ const shown = paths.slice(0, MAX_TIMEOUT_FILES).join(", ");
103
+ return paths.length > MAX_TIMEOUT_FILES ? `${shown}, ... (${paths.length - MAX_TIMEOUT_FILES} more)` : shown;
104
+ }
105
+ export function projectTimeoutRecovery(value) {
106
+ if (!value || typeof value !== "object" || Array.isArray(value))
107
+ return;
108
+ const source = value;
109
+ const termination = source.termination === "timed-out" || source.termination === "stopped" ? source.termination : undefined;
110
+ if (!termination || !Array.isArray(source.changedFiles))
111
+ return;
112
+ const allChangedFiles = source.changedFiles.filter((file) => typeof file === "string");
113
+ const changedFiles = allChangedFiles.slice(0, MAX_TIMEOUT_FILES);
114
+ const reportStatus = source.reportStatus === "missing" || source.reportStatus === "written" || source.reportStatus === "not-requested" || source.reportStatus === "unknown" ? source.reportStatus : undefined;
115
+ return {
116
+ termination,
117
+ changedFiles,
118
+ ...source.truncated === true || allChangedFiles.length > changedFiles.length ? { truncated: true } : {},
119
+ ...source.recoveryNeeded === true ? { recoveryNeeded: true } : {},
120
+ ...source.reason === "timed-out-with-dirty-worktree" ? { reason: source.reason } : {},
121
+ ...reportStatus ? { reportStatus } : {}
122
+ };
123
+ }
124
+ export function formatTimeoutRecoveryLines(value, indent = "") {
125
+ const recovery = projectTimeoutRecovery(value);
126
+ if (!recovery?.recoveryNeeded)
127
+ return [];
128
+ const changedFiles = recovery.changedFiles.length > 0 ? `${recovery.changedFiles.join(", ")}${recovery.truncated ? ", …" : ""}` : "none";
129
+ const changedFileCount = recovery.changedFiles.length > 0 ? `${recovery.changedFiles.length}${recovery.truncated ? "+" : ""}` : "0";
130
+ return [
131
+ `${indent}Recovery needed: review the diff and artifacts before resuming or launching dependent stages.`,
132
+ `${indent}Recovery evidence: requested report: ${recovery.reportStatus ?? "unknown"}; changed tracked files: ${changedFiles} (${changedFileCount}); classification: ${recovery.reason ?? recovery.termination}`
133
+ ];
134
+ }
135
+ export function buildTimeoutRecoverySummary(input) {
136
+ const warning = "Inspect partial changes before retrying or resuming the child.";
137
+ const changedFiles = input.evidence.changedFiles.slice(0, MAX_TIMEOUT_FILES);
138
+ let reportStatus = "not-requested";
139
+ if (input.requiredOutputMissing === true)
140
+ reportStatus = "missing";
141
+ else if (input.requiredOutputMissing === false)
142
+ reportStatus = "written";
143
+ const recoveryNeeded = input.termination === "timed-out" && reportStatus === "missing" && input.evidence.changedFiles.length > 0;
144
+ const lines = [
145
+ "Recovery summary:",
146
+ `- termination: ${input.termination}`,
147
+ `- changed tracked files: ${input.evidence.unavailable ? `unavailable (${input.evidence.unavailable})` : formatPathList(input.evidence.changedFiles)}`
148
+ ];
149
+ if (input.requiredOutputMissing !== undefined)
150
+ lines.push(`- requested report: ${reportStatus}`);
151
+ if (recoveryNeeded)
152
+ lines.push("- Recovery needed: review the diff and artifacts before resuming or launching dependent stages.");
153
+ if (input.currentTool)
154
+ lines.push(`- active tool: ${input.currentTool}${input.currentToolArgs ? ` — ${input.currentToolArgs}` : ""}`);
155
+ if (input.currentPath)
156
+ lines.push(`- active path: ${input.currentPath}`);
157
+ if (input.sessionFile)
158
+ lines.push(`- session file: ${input.sessionFile}`);
159
+ if (input.transcriptPath)
160
+ lines.push(`- transcript: ${input.transcriptPath}`);
161
+ if (input.artifactPaths?.outputPath)
162
+ lines.push(`- output artifact: ${input.artifactPaths.outputPath}`);
163
+ if (input.artifactPaths?.metadataPath)
164
+ lines.push(`- metadata artifact: ${input.artifactPaths.metadataPath}`);
165
+ lines.push(`Warning: ${warning}`);
166
+ return {
167
+ termination: input.termination,
168
+ changedFiles,
169
+ truncated: input.evidence.changedFiles.length > changedFiles.length || input.evidence.truncated || undefined,
170
+ ...recoveryNeeded ? { recoveryNeeded: true, reason: "timed-out-with-dirty-worktree" } : {},
171
+ reportStatus,
172
+ currentTool: input.currentTool,
173
+ currentToolArgs: input.currentToolArgs,
174
+ currentPath: input.currentPath,
175
+ sessionFile: input.sessionFile,
176
+ transcriptPath: input.transcriptPath,
177
+ artifactPaths: input.artifactPaths,
178
+ warning,
179
+ message: lines.join(`
180
+ `)
181
+ };
182
+ }