@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,563 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import { discoverAgents, formatUnknownAgentError, resolveAgentName, unknownAgentDiagnosticContext } from "./agents.js";
5
+ import { getProjectSubagentsDir } from "../shared/artifacts.js";
6
+ const REFINEMENT_FORMAT_VERSION = 1;
7
+ const REFINEMENT_DIR = "refinements";
8
+ const CURRENT_FENCE = "dm-subagents-refinement-current";
9
+ const SNAPSHOTS_FENCE = "dm-subagents-refinement-snapshots-json";
10
+ const MAX_EVIDENCE_ITEMS = 8;
11
+ const MAX_AGE_DAYS = 14;
12
+ const MAX_ITEM_BYTES = 2048;
13
+ const MAX_PACKET_BYTES = 16384;
14
+ const PROPOSAL_AGENT = "reviewer";
15
+ function result(text, isError = false) {
16
+ return {
17
+ content: [{ type: "text", text }],
18
+ ...isError ? { isError: true } : {},
19
+ details: { mode: "management", results: [] }
20
+ };
21
+ }
22
+ function record(value) {
23
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
24
+ }
25
+ function text(value) {
26
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
27
+ }
28
+ function textArray(value) {
29
+ if (!Array.isArray(value))
30
+ return [];
31
+ return value.map(text).filter((entry) => entry !== null);
32
+ }
33
+ function isoTime(value) {
34
+ const numberValue = typeof value === "number" && Number.isFinite(value) ? value : undefined;
35
+ if (numberValue !== undefined)
36
+ return new Date(numberValue).toISOString();
37
+ const stringValue = text(value);
38
+ if (!stringValue)
39
+ return;
40
+ const parsed = Date.parse(stringValue);
41
+ return Number.isFinite(parsed) ? new Date(parsed).toISOString() : undefined;
42
+ }
43
+ function hashPrompt(systemPrompt) {
44
+ return createHash("sha256").update(systemPrompt).digest("hex");
45
+ }
46
+ function safeAgentFileName(agentName) {
47
+ const trimmed = agentName.trim();
48
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(trimmed) || trimmed.includes("..")) {
49
+ throw new Error(`Agent name '${agentName}' cannot be used as a refinement file name.`);
50
+ }
51
+ return `${trimmed}.md`;
52
+ }
53
+ export function getAgentRefinementPath(cwd, agentName) {
54
+ const refinementRoot = path.join(getProjectSubagentsDir(cwd), REFINEMENT_DIR);
55
+ const resolvedRoot = path.resolve(refinementRoot);
56
+ const resolvedPath = path.resolve(refinementRoot, safeAgentFileName(agentName));
57
+ if (resolvedPath !== path.join(resolvedRoot, path.basename(resolvedPath))) {
58
+ throw new Error(`Agent name '${agentName}' cannot be used as a refinement file name.`);
59
+ }
60
+ return resolvedPath;
61
+ }
62
+ function readExisting(cwd, agentName) {
63
+ const filePath = getAgentRefinementPath(cwd, agentName);
64
+ if (!fs.existsSync(filePath))
65
+ return { path: filePath };
66
+ return { path: filePath, parsed: parseRefinementFile(fs.readFileSync(filePath, "utf-8"), filePath) };
67
+ }
68
+ function extractFence(markdown, fence) {
69
+ const escaped = fence.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
70
+ const match = markdown.match(new RegExp("\\n```" + escaped + "\\n([\\s\\S]*?)\\n```", "m"));
71
+ return match?.[1] ?? null;
72
+ }
73
+ export function parseRefinementFile(markdown, label = "refinement file") {
74
+ const metadataMatch = markdown.match(/^<!-- dm-subagents-refinement:v1\n([\s\S]*?)\n-->\n/);
75
+ if (!metadataMatch?.[1])
76
+ throw new Error(`${label} is missing refinement metadata.`);
77
+ const metadataValue = JSON.parse(metadataMatch[1]);
78
+ const metadataRecord = record(metadataValue);
79
+ if (!metadataRecord)
80
+ throw new Error(`${label} metadata must be an object.`);
81
+ const agent = text(metadataRecord.agent);
82
+ const revision = metadataRecord.revision;
83
+ const updatedAt = text(metadataRecord.updatedAt);
84
+ const base = record(metadataRecord.base);
85
+ const evidence = record(metadataRecord.evidence);
86
+ if (!agent || typeof revision !== "number" || !Number.isInteger(revision) || !updatedAt || !base || !evidence) {
87
+ throw new Error(`${label} metadata is invalid.`);
88
+ }
89
+ const source = text(base.source);
90
+ const filePath = text(base.filePath);
91
+ const systemPromptSha256 = text(base.systemPromptSha256);
92
+ if (source !== "builtin" && source !== "package" && source !== "user" && source !== "project")
93
+ throw new Error(`${label} base source is invalid.`);
94
+ if (!filePath || !systemPromptSha256)
95
+ throw new Error(`${label} base metadata is invalid.`);
96
+ const current = extractFence(markdown, CURRENT_FENCE);
97
+ if (current === null)
98
+ throw new Error(`${label} is missing current refinement block.`);
99
+ const snapshotsRaw = extractFence(markdown, SNAPSHOTS_FENCE) ?? "[]";
100
+ const snapshotsValue = JSON.parse(snapshotsRaw);
101
+ if (!Array.isArray(snapshotsValue))
102
+ throw new Error(`${label} snapshots must be an array.`);
103
+ const snapshots = snapshotsValue.map((entry, index) => {
104
+ const item = record(entry);
105
+ if (!item)
106
+ throw new Error(`${label} snapshot ${index} must be an object.`);
107
+ const action = text(item.action);
108
+ const before = typeof item.before === "string" ? item.before : null;
109
+ const after = typeof item.after === "string" ? item.after : null;
110
+ const at = text(item.at);
111
+ if (typeof item.revision !== "number" || !Number.isInteger(item.revision) || !at || action !== "refine" && action !== "rollback" || before === null || after === null) {
112
+ throw new Error(`${label} snapshot ${index} is invalid.`);
113
+ }
114
+ return {
115
+ revision: item.revision,
116
+ at,
117
+ action,
118
+ before,
119
+ after,
120
+ evidenceIds: textArray(item.evidenceIds),
121
+ ...text(item.proposalAgent) ? { proposalAgent: text(item.proposalAgent) } : {}
122
+ };
123
+ });
124
+ return {
125
+ metadata: {
126
+ agent,
127
+ revision,
128
+ updatedAt,
129
+ base: { source, filePath, systemPromptSha256 },
130
+ evidence: {
131
+ maxItems: typeof evidence.maxItems === "number" ? evidence.maxItems : MAX_EVIDENCE_ITEMS,
132
+ maxAgeDays: typeof evidence.maxAgeDays === "number" ? evidence.maxAgeDays : MAX_AGE_DAYS,
133
+ itemBytes: typeof evidence.itemBytes === "number" ? evidence.itemBytes : MAX_ITEM_BYTES,
134
+ totalBytes: typeof evidence.totalBytes === "number" ? evidence.totalBytes : MAX_PACKET_BYTES
135
+ }
136
+ },
137
+ current,
138
+ snapshots
139
+ };
140
+ }
141
+ function serializeRefinementFile(parsed) {
142
+ const metadata = JSON.stringify(parsed.metadata, null, 2);
143
+ const snapshots = JSON.stringify(parsed.snapshots, null, 2);
144
+ return [
145
+ `<!-- dm-subagents-refinement:v${REFINEMENT_FORMAT_VERSION}`,
146
+ metadata,
147
+ "-->",
148
+ "",
149
+ `# Current refinement for \`${parsed.metadata.agent}\``,
150
+ "",
151
+ `\`\`\`${CURRENT_FENCE}`,
152
+ parsed.current,
153
+ "```",
154
+ "",
155
+ "# Snapshots",
156
+ "",
157
+ `\`\`\`${SNAPSHOTS_FENCE}`,
158
+ snapshots,
159
+ "```",
160
+ ""
161
+ ].join(`
162
+ `);
163
+ }
164
+ function writeRefinementFile(filePath, parsed) {
165
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
166
+ const tmp = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
167
+ fs.writeFileSync(tmp, serializeRefinementFile(parsed), "utf-8");
168
+ fs.renameSync(tmp, filePath);
169
+ }
170
+ function baseMetadata(agent) {
171
+ return {
172
+ source: agent.source,
173
+ filePath: agent.filePath,
174
+ systemPromptSha256: hashPrompt(agent.systemPrompt)
175
+ };
176
+ }
177
+ function metadataFor(agent, revision, now) {
178
+ return {
179
+ agent: agent.name,
180
+ revision,
181
+ updatedAt: now,
182
+ base: baseMetadata(agent),
183
+ evidence: {
184
+ maxItems: MAX_EVIDENCE_ITEMS,
185
+ maxAgeDays: MAX_AGE_DAYS,
186
+ itemBytes: MAX_ITEM_BYTES,
187
+ totalBytes: MAX_PACKET_BYTES
188
+ }
189
+ };
190
+ }
191
+ function withinAge(at, now = Date.now()) {
192
+ if (!at)
193
+ return true;
194
+ const parsed = Date.parse(at);
195
+ return Number.isFinite(parsed) && now - parsed <= MAX_AGE_DAYS * 24 * 60 * 60 * 1000;
196
+ }
197
+ function tailBytes(value, maxBytes) {
198
+ const buffer = Buffer.from(value, "utf-8");
199
+ if (buffer.byteLength <= maxBytes)
200
+ return value;
201
+ return buffer.subarray(buffer.byteLength - maxBytes).toString("utf-8");
202
+ }
203
+ function pushCapped(items, item) {
204
+ if (items.length >= MAX_EVIDENCE_ITEMS)
205
+ return;
206
+ items.push({ ...item, outputTail: item.outputTail ? tailBytes(item.outputTail, MAX_ITEM_BYTES) : undefined });
207
+ }
208
+ function acceptanceFields(value) {
209
+ const ledger = record(value);
210
+ if (!ledger)
211
+ return {};
212
+ const childReport = record(ledger.childReport);
213
+ const reviewResult = record(ledger.reviewResult);
214
+ const reviewFindings = [
215
+ ...textArray(childReport?.reviewFindings),
216
+ ...Array.isArray(reviewResult?.findings) ? reviewResult.findings.map((finding) => text(record(finding)?.issue)).filter((entry) => entry !== null) : []
217
+ ];
218
+ const residualRisks = textArray(childReport?.residualRisks);
219
+ return {
220
+ ...text(ledger.status) ? { acceptanceStatus: text(ledger.status) } : {},
221
+ ...reviewFindings.length > 0 ? { reviewFindings } : {},
222
+ ...residualRisks.length > 0 ? { residualRisks } : {}
223
+ };
224
+ }
225
+ function controlSignals(value) {
226
+ if (!Array.isArray(value))
227
+ return [];
228
+ return value.map((entry) => {
229
+ const item = record(entry);
230
+ if (!item)
231
+ return null;
232
+ const message = text(item.message);
233
+ const reason = text(item.reason);
234
+ return message ? reason ? `${reason}: ${message}` : message : null;
235
+ }).filter((entry) => entry !== null);
236
+ }
237
+ function evidencePacket(items) {
238
+ const packet = [];
239
+ let bytes = 2;
240
+ for (const item of items) {
241
+ const encoded = Buffer.byteLength(JSON.stringify(item), "utf-8") + 1;
242
+ if (bytes + encoded > MAX_PACKET_BYTES)
243
+ break;
244
+ packet.push(item);
245
+ bytes += encoded;
246
+ }
247
+ return packet;
248
+ }
249
+ export function collectBoundedRefinementEvidence(cwd, agentName, state) {
250
+ const items = [];
251
+ const jobs = [...state.asyncJobs.values()].filter((job) => !job.cwd || path.resolve(job.cwd) === path.resolve(cwd)).filter((job) => job.agents?.includes(agentName) || job.steps?.some((step) => step.agent === agentName)).sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
252
+ for (const job of jobs) {
253
+ const at = isoTime(job.updatedAt ?? job.startedAt);
254
+ if (!withinAge(at))
255
+ continue;
256
+ const matchingSteps = job.steps?.filter((step) => step.agent === agentName) ?? [];
257
+ if (matchingSteps.length === 0) {
258
+ pushCapped(items, {
259
+ id: `live:${job.asyncId}`,
260
+ source: "live-state",
261
+ runId: job.asyncId,
262
+ agent: agentName,
263
+ ...at ? { at } : {},
264
+ status: job.status,
265
+ refs: [job.asyncDir]
266
+ });
267
+ continue;
268
+ }
269
+ for (const [index, step] of matchingSteps.entries()) {
270
+ const stepRecord = step;
271
+ pushCapped(items, {
272
+ id: `live:${job.asyncId}:${index}`,
273
+ source: "live-state",
274
+ runId: job.asyncId,
275
+ agent: agentName,
276
+ ...at ? { at } : {},
277
+ status: step.status,
278
+ ...text(stepRecord.model) ? { model: text(stepRecord.model) } : {},
279
+ ...text(stepRecord.thinking) ? { thinking: text(stepRecord.thinking) } : {},
280
+ ...acceptanceFields(stepRecord.acceptance),
281
+ ...text(step.error) ? { errors: [text(step.error)] } : {},
282
+ ...text(stepRecord.recentOutput) ? { outputTail: text(stepRecord.recentOutput) } : {},
283
+ refs: [job.asyncDir]
284
+ });
285
+ }
286
+ }
287
+ const artifactsDir = path.join(getProjectSubagentsDir(cwd), "artifacts");
288
+ if (fs.existsSync(artifactsDir)) {
289
+ const files = fs.readdirSync(artifactsDir).filter((file) => file.endsWith("_meta.json")).map((file) => path.join(artifactsDir, file)).sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
290
+ for (const file of files) {
291
+ if (items.length >= MAX_EVIDENCE_ITEMS)
292
+ break;
293
+ let metadata = null;
294
+ try {
295
+ metadata = record(JSON.parse(fs.readFileSync(file, "utf-8")));
296
+ } catch {
297
+ metadata = null;
298
+ }
299
+ if (!metadata || text(metadata.agent) !== agentName)
300
+ continue;
301
+ const stat = fs.statSync(file);
302
+ const at = isoTime(metadata.timestamp ?? stat.mtimeMs);
303
+ if (!withinAge(at))
304
+ continue;
305
+ const outputPath = file.replace(/_meta\.json$/, "_output.md");
306
+ const outputTail = fs.existsSync(outputPath) ? tailBytes(fs.readFileSync(outputPath, "utf-8"), MAX_ITEM_BYTES) : undefined;
307
+ pushCapped(items, {
308
+ id: `artifact:${path.basename(file, "_meta.json")}`,
309
+ source: outputTail ? "artifact-output" : "artifact-metadata",
310
+ ...text(metadata.runId) ? { runId: text(metadata.runId) } : {},
311
+ agent: agentName,
312
+ ...at ? { at } : {},
313
+ status: typeof metadata.exitCode === "number" ? metadata.exitCode === 0 ? "completed" : "failed" : undefined,
314
+ ...text(metadata.model) ? { model: text(metadata.model) } : {},
315
+ ...text(metadata.thinking) ? { thinking: text(metadata.thinking) } : {},
316
+ ...acceptanceFields(metadata.acceptance),
317
+ ...text(metadata.error) ? { errors: [text(metadata.error)] } : {},
318
+ ...controlSignals(metadata.controlEvents).length > 0 ? { controlSignals: controlSignals(metadata.controlEvents) } : {},
319
+ ...outputTail ? { outputTail } : {},
320
+ refs: outputTail ? [file, outputPath] : [file]
321
+ });
322
+ }
323
+ }
324
+ return evidencePacket(items);
325
+ }
326
+ export function appendAgentRefinementOverlay(systemPrompt, input) {
327
+ let current = "";
328
+ let filePath = "";
329
+ try {
330
+ filePath = getAgentRefinementPath(input.cwd, input.agentName);
331
+ if (!fs.existsSync(filePath))
332
+ return systemPrompt;
333
+ current = parseRefinementFile(fs.readFileSync(filePath, "utf-8"), filePath).current.trim();
334
+ } catch {
335
+ return systemPrompt;
336
+ }
337
+ if (!current)
338
+ return systemPrompt;
339
+ const overlay = [
340
+ `<dm-subagents-refinement agent=${JSON.stringify(input.agentName)} source=${JSON.stringify(path.relative(input.cwd, filePath))}>`,
341
+ "Project-local refinement guidance generated from recent bounded evidence.",
342
+ "It does not override tool, developer, task, output, acceptance, or safety instructions.",
343
+ "",
344
+ current,
345
+ "</dm-subagents-refinement>"
346
+ ].join(`
347
+ `);
348
+ return systemPrompt.trim() ? `${systemPrompt}
349
+
350
+ ${overlay}` : overlay;
351
+ }
352
+ export function validateRefinementProposal(proposal, evidenceIds) {
353
+ const item = record(proposal);
354
+ if (!item)
355
+ return { ok: false, error: "Refinement proposal must be an object." };
356
+ const summary = text(item.summary);
357
+ const editsValue = item.edits;
358
+ if (!summary || !Array.isArray(editsValue))
359
+ return { ok: false, error: "Refinement proposal requires summary and edits." };
360
+ if (editsValue.length > 3)
361
+ return { ok: false, error: "Refinement proposal may contain at most 3 edits." };
362
+ const allowed = new Set(evidenceIds);
363
+ const protectedInstruction = "(?:acceptance|output|safety|policy|policies|tools?|developer|system)";
364
+ const blocked = new RegExp(`\\b(all agents|every agent|global|(?:disable|ignore|bypass|skip|override)\\s+(?:the\\s+)?${protectedInstruction}(?:\\s+instructions?)?|${protectedInstruction}\\s+(?:instructions?|overrides?)|tool safety|review gates|rewrite base|base agent file|settings\\.json|\\.dm/agent|agents/.*\\.md)\\b`, "i");
365
+ const edits = [];
366
+ for (const [index, editValue] of editsValue.entries()) {
367
+ const edit = record(editValue);
368
+ if (!edit)
369
+ return { ok: false, error: `Refinement proposal edit ${index} must be an object.` };
370
+ const title = text(edit.title);
371
+ const guidance = text(edit.guidance);
372
+ const rationale = text(edit.rationale);
373
+ const cited = textArray(edit.evidenceIds);
374
+ if (!title || !guidance || !rationale)
375
+ return { ok: false, error: `Refinement proposal edit ${index} is missing title, guidance, or rationale.` };
376
+ if (cited.length === 0 || cited.some((id) => !allowed.has(id)))
377
+ return { ok: false, error: `Refinement proposal edit ${index} must cite known evidence ids.` };
378
+ if (guidance.includes("```") || guidance.includes("</dm-subagents-refinement>") || blocked.test(guidance))
379
+ return { ok: false, error: `Refinement proposal edit ${index} contains disallowed guidance.` };
380
+ edits.push({ title, guidance, rationale, evidenceIds: cited });
381
+ }
382
+ return { ok: true, proposal: { summary, edits, rejectedIdeas: textArray(item.rejectedIdeas), residualRisks: textArray(item.residualRisks) } };
383
+ }
384
+ function proposalSchema() {
385
+ return {
386
+ type: "object",
387
+ additionalProperties: false,
388
+ required: ["summary", "edits", "residualRisks"],
389
+ properties: {
390
+ summary: { type: "string" },
391
+ edits: {
392
+ type: "array",
393
+ maxItems: 3,
394
+ items: {
395
+ type: "object",
396
+ additionalProperties: false,
397
+ required: ["title", "guidance", "evidenceIds", "rationale"],
398
+ properties: {
399
+ title: { type: "string" },
400
+ guidance: { type: "string" },
401
+ evidenceIds: { type: "array", items: { type: "string" }, minItems: 1 },
402
+ rationale: { type: "string" }
403
+ }
404
+ }
405
+ },
406
+ rejectedIdeas: { type: "array", items: { type: "string" } },
407
+ residualRisks: { type: "array", items: { type: "string" } }
408
+ }
409
+ };
410
+ }
411
+ function proposalFromChild(child) {
412
+ for (const entry of child.details?.results ?? []) {
413
+ if (entry.structuredOutput !== undefined)
414
+ return entry.structuredOutput;
415
+ }
416
+ const output = child.details?.results?.map((entry) => entry.finalOutput ?? "").find((entry) => entry.trim().length > 0) ?? child.content?.map((entry) => entry.text ?? "").find((entry) => entry.trim().length > 0) ?? "";
417
+ const jsonMatch = output.match(/```(?:json)?\n([\s\S]*?)\n```/) ?? output.match(/({[\s\S]*})/);
418
+ if (!jsonMatch?.[1])
419
+ return null;
420
+ try {
421
+ return JSON.parse(jsonMatch[1]);
422
+ } catch {
423
+ return null;
424
+ }
425
+ }
426
+ function proposalTask(agent, current, evidence) {
427
+ return [
428
+ `You are a fresh read-only proposal child for project-local refinement of one subagent: ${agent.name}.`,
429
+ "Do not read files. Do not use write, edit, or shell tools. Use only the evidence packet below.",
430
+ "Propose at most 2-3 minimal overlay guidance edits.",
431
+ "Each edit must cite one or more evidence ids from the packet.",
432
+ "Do not propose base agent file, settings, global, automatic, tool, safety, output, acceptance, developer, or system instruction changes.",
433
+ "Return only structured output that matches the schema.",
434
+ "",
435
+ "Agent metadata:",
436
+ JSON.stringify({ name: agent.name, source: agent.source, filePath: agent.filePath, basePromptSha256: hashPrompt(agent.systemPrompt) }, null, 2),
437
+ "",
438
+ "Current overlay:",
439
+ current.trim() || "(none)",
440
+ "",
441
+ "Evidence packet:",
442
+ JSON.stringify(evidence, null, 2)
443
+ ].join(`
444
+ `);
445
+ }
446
+ function guidanceFromProposal(proposal) {
447
+ return proposal.edits.map((edit) => `- ${edit.guidance.trim()}`).join(`
448
+ `);
449
+ }
450
+ function resolveOneAgent(cwd, agentName) {
451
+ const discovered = discoverAgents(cwd, "both");
452
+ const resolved = resolveAgentName(agentName, discovered.agents);
453
+ if (resolved.error)
454
+ return { ok: false, error: resolved.error };
455
+ if (!resolved.agent)
456
+ return { ok: false, error: formatUnknownAgentError(agentName, unknownAgentDiagnosticContext(discovered)) };
457
+ return { ok: true, agent: resolved.agent };
458
+ }
459
+ export async function handleRefinementAction(action, params, ctx) {
460
+ const requestedAgent = params.agent?.trim();
461
+ if (!requestedAgent)
462
+ return result(`${action} requires agent. Use /subagents-refine <agent> or subagent({ action: "${action}", agent: "<agent>" }).`, true);
463
+ let resolved;
464
+ try {
465
+ resolved = resolveOneAgent(ctx.cwd, requestedAgent);
466
+ } catch (error) {
467
+ return result(error instanceof Error ? error.message : String(error), true);
468
+ }
469
+ if (!resolved.ok)
470
+ return result(resolved.error, true);
471
+ const agent = resolved.agent;
472
+ let existing;
473
+ try {
474
+ existing = readExisting(ctx.cwd, agent.name);
475
+ } catch (error) {
476
+ return result(error instanceof Error ? error.message : String(error), true);
477
+ }
478
+ if (action === "refine.show") {
479
+ if (!existing.parsed)
480
+ return result(`No refinement overlay exists for '${agent.name}'.`);
481
+ const currentDigest = hashPrompt(agent.systemPrompt);
482
+ const drift = existing.parsed.metadata.base.systemPromptSha256 === currentDigest ? "no" : "yes";
483
+ const history = existing.parsed.snapshots.slice(-5).map((snapshot) => `- r${snapshot.revision} ${snapshot.action} at ${snapshot.at} (${snapshot.evidenceIds.length} evidence id${snapshot.evidenceIds.length === 1 ? "" : "s"})`).join(`
484
+ `) || "- none";
485
+ return result([
486
+ `Refinement overlay for '${agent.name}'`,
487
+ `Path: ${existing.path}`,
488
+ `Revision: ${existing.parsed.metadata.revision}`,
489
+ `Updated: ${existing.parsed.metadata.updatedAt}`,
490
+ `Base: ${existing.parsed.metadata.base.source} ${existing.parsed.metadata.base.filePath}`,
491
+ `Base prompt changed since overlay: ${drift}`,
492
+ "",
493
+ "Current guidance:",
494
+ existing.parsed.current.trim() || "(empty)",
495
+ "",
496
+ "Recent history:",
497
+ history
498
+ ].join(`
499
+ `));
500
+ }
501
+ if (action === "refine.rollback") {
502
+ if (!existing.parsed)
503
+ return result(`No refinement overlay exists for '${agent.name}'.`, true);
504
+ const latest = existing.parsed.snapshots.at(-1);
505
+ if (!latest)
506
+ return result(`No refinement snapshot exists for '${agent.name}'.`, true);
507
+ const now = new Date().toISOString();
508
+ const nextRevision = existing.parsed.metadata.revision + 1;
509
+ const next = {
510
+ metadata: metadataFor(agent, nextRevision, now),
511
+ current: latest.before,
512
+ snapshots: [...existing.parsed.snapshots, { revision: nextRevision, at: now, action: "rollback", before: existing.parsed.current, after: latest.before, evidenceIds: latest.evidenceIds }]
513
+ };
514
+ try {
515
+ writeRefinementFile(existing.path, next);
516
+ } catch (error) {
517
+ return result(error instanceof Error ? error.message : String(error), true);
518
+ }
519
+ return result(`Rolled back refinement overlay for '${agent.name}' to revision ${nextRevision}.
520
+ Path: ${existing.path}`);
521
+ }
522
+ const evidence = collectBoundedRefinementEvidence(ctx.cwd, agent.name, ctx.state);
523
+ if (evidence.length === 0)
524
+ return result(`No bounded recent evidence was found for '${agent.name}'. No proposal child was launched and no overlay was written.`);
525
+ const current = existing.parsed?.current ?? "";
526
+ const child = await ctx.launchProposalChild(proposalTask(agent, current, evidence), proposalSchema(), ctx.signal);
527
+ if (child.isError)
528
+ return result(`Refinement proposal child failed. No overlay was written.`, true);
529
+ const validation = validateRefinementProposal(proposalFromChild(child), evidence.map((item) => item.id));
530
+ if (!validation.ok)
531
+ return result(`${validation.error} No overlay was written.`, true);
532
+ if (validation.proposal.edits.length === 0)
533
+ return result(`The proposal child returned no edits for '${agent.name}'. No overlay was written.`);
534
+ const now = new Date().toISOString();
535
+ const nextRevision = (existing.parsed?.metadata.revision ?? 0) + 1;
536
+ const after = guidanceFromProposal(validation.proposal);
537
+ const snapshot = {
538
+ revision: nextRevision,
539
+ at: now,
540
+ action: "refine",
541
+ before: current,
542
+ after,
543
+ evidenceIds: [...new Set(validation.proposal.edits.flatMap((edit) => edit.evidenceIds))],
544
+ proposalAgent: PROPOSAL_AGENT
545
+ };
546
+ const next = {
547
+ metadata: metadataFor(agent, nextRevision, now),
548
+ current: after,
549
+ snapshots: [...existing.parsed?.snapshots ?? [], snapshot]
550
+ };
551
+ try {
552
+ writeRefinementFile(existing.path, next);
553
+ } catch (error) {
554
+ return result(error instanceof Error ? error.message : String(error), true);
555
+ }
556
+ return result([
557
+ `Wrote refinement overlay for '${agent.name}' at revision ${nextRevision}.`,
558
+ `Path: ${existing.path}`,
559
+ `Evidence items: ${evidence.length}`,
560
+ `Edits: ${validation.proposal.edits.length}`
561
+ ].join(`
562
+ `));
563
+ }