@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
@@ -10,8 +10,9 @@ import {
10
10
  SUBAGENT_RUN_ID_ENV,
11
11
  SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV
12
12
  } from "../runs/shared/dm-args.js";
13
- import { POLL_INTERVAL_MS, TEMP_ROOT_DIR } from "../shared/types.js";
13
+ import { INTERCOM_DETACH_REQUEST_EVENT, POLL_INTERVAL_MS, TEMP_ROOT_DIR } from "../shared/types.js";
14
14
  import { writeAtomicJson } from "../shared/atomic-json.js";
15
+ import { shouldUseNativeFsWatch } from "../shared/watch-strategy.js";
15
16
  const SUPERVISOR_CHANNEL_ROOT = path.join(TEMP_ROOT_DIR, "supervisor-channels");
16
17
  const REQUESTS_DIR = "requests";
17
18
  const REPLIES_DIR = "replies";
@@ -19,6 +20,9 @@ export const NATIVE_SUPERVISOR_TOOL_NAME = "subagent_supervisor";
19
20
  const MAX_MESSAGE_BYTES = 64 * 1024;
20
21
  const DEFAULT_ASK_TIMEOUT_MS = 10 * 60 * 1000;
21
22
  const CHANNEL_POLL_MS = Math.min(POLL_INTERVAL_MS, 500);
23
+ const CHANNEL_SAFETY_POLL_MS = 5000;
24
+ const STALE_EMPTY_CHANNEL_AGE_MS = 60 * 1000;
25
+ const STALE_EMPTY_CHANNEL_CLEANUP_INTERVAL_MS = 60 * 1000;
22
26
  const ContactSupervisorParamsSchema = Type.Object({
23
27
  reason: Type.String({ enum: ["need_decision", "interview_request", "progress_update"] }),
24
28
  message: Type.Optional(Type.String()),
@@ -131,9 +135,8 @@ function delay(ms, signal) {
131
135
  signal?.addEventListener("abort", onAbort, { once: true });
132
136
  });
133
137
  }
134
- async function waitForReply(channelDir, requestId, signal) {
138
+ async function waitForReply(channelDir, requestId, deadline, signal) {
135
139
  const file = replyPath(channelDir, requestId);
136
- const deadline = Date.now() + askTimeoutMs();
137
140
  while (Date.now() <= deadline) {
138
141
  if (signal?.aborted)
139
142
  throw new Error("Supervisor request cancelled.");
@@ -157,11 +160,15 @@ async function sendSupervisorRequest(params, signal) {
157
160
  ensureSupervisorChannelDir(metadata.channelDir);
158
161
  const requestId = randomUUID();
159
162
  const expectsReply = params.reason !== "progress_update";
163
+ const createdAt = Date.now();
164
+ const replyDeadline = createdAt + askTimeoutMs();
165
+ const expiresAt = expectsReply ? replyDeadline : undefined;
160
166
  const message = formatChildMessage({ ...metadata, reason: params.reason, message: params.message, interview: params.interview });
161
167
  const request = {
162
168
  type: "subagent.supervisor.request",
163
169
  id: requestId,
164
- createdAt: Date.now(),
170
+ createdAt,
171
+ ...expiresAt !== undefined ? { expiresAt } : {},
165
172
  reason: params.reason,
166
173
  message,
167
174
  expectsReply,
@@ -183,65 +190,46 @@ async function sendSupervisorRequest(params, signal) {
183
190
  details: { delivered: true, requestId, reason: params.reason }
184
191
  };
185
192
  }
186
- const reply = await waitForReply(metadata.channelDir, requestId, signal);
187
- const details = { requestId, reason: params.reason };
188
- if (params.reason === "interview_request") {
189
- const structured = parseStructuredReply(reply.message);
190
- if (structured.error)
191
- details.structuredReplyParseError = structured.error;
192
- else
193
- details.structuredReply = structured.value;
194
- }
195
- return {
196
- content: [{ type: "text", text: `**Reply from supervisor:**
193
+ try {
194
+ const reply = await waitForReply(metadata.channelDir, requestId, replyDeadline, signal);
195
+ const details = { requestId, reason: params.reason };
196
+ if (params.reason === "interview_request") {
197
+ const structured = parseStructuredReply(reply.message);
198
+ if (structured.error)
199
+ details.structuredReplyParseError = structured.error;
200
+ else
201
+ details.structuredReply = structured.value;
202
+ }
203
+ return {
204
+ content: [{ type: "text", text: `**Reply from supervisor:**
197
205
  ${reply.message}` }],
198
- details
199
- };
206
+ details
207
+ };
208
+ } catch (error) {
209
+ removeRequestFile(requestPath(metadata.channelDir, requestId));
210
+ throw error;
211
+ }
200
212
  }
201
- function hasTool(pi, name) {
213
+ function hasTool(dm, name) {
202
214
  try {
203
- return pi.getAllTools?.().some((tool) => tool.name === name) === true;
215
+ return dm.getAllTools?.().some((tool) => tool.name === name) === true;
204
216
  } catch {
205
217
  return false;
206
218
  }
207
219
  }
208
- export function registerNativeSupervisorClient(pi, options = {}) {
209
- if (!readChildMetadata())
220
+ export function registerNativeSupervisorClient(dm) {
221
+ if (!readChildMetadata() || hasTool(dm, "contact_supervisor"))
210
222
  return;
211
- const includeIntercomFallback = options.includeIntercomFallback !== false;
212
- if (!hasTool(pi, "contact_supervisor")) {
213
- const tool = {
214
- name: "contact_supervisor",
215
- label: "Contact Supervisor",
216
- description: "Contact the parent/supervisor session for a blocking decision, structured interview, or progress update.",
217
- parameters: ContactSupervisorParamsSchema,
218
- execute(_id, params, signal) {
219
- return sendSupervisorRequest(params, signal);
220
- }
221
- };
222
- pi.registerTool(tool);
223
- }
224
- if (includeIntercomFallback && !hasTool(pi, "intercom")) {
225
- const tool = {
226
- name: "intercom",
227
- label: "Intercom",
228
- description: "Native supervisor-channel intercom fallback for subagents. Prefer contact_supervisor when available.",
229
- parameters: IntercomParamsSchema,
230
- async execute(_id, params, signal) {
231
- const action = params.action;
232
- if (action === "status")
233
- return { content: [{ type: "text", text: "Native supervisor channel is active." }], details: { active: true } };
234
- if (action === "list")
235
- return { content: [{ type: "text", text: "Supervisor session available through contact_supervisor." }], details: { sessions: [] } };
236
- if (action === "send")
237
- return sendSupervisorRequest({ reason: "progress_update", message: params.message ?? "" }, signal);
238
- if (action === "ask")
239
- return sendSupervisorRequest({ reason: "need_decision", message: params.message ?? "" }, signal);
240
- throw new Error("Native child intercom supports status, list, send, and ask. Use parent intercom reply from the supervisor session.");
241
- }
242
- };
243
- pi.registerTool(tool);
244
- }
223
+ const tool = {
224
+ name: "contact_supervisor",
225
+ label: "Contact Supervisor",
226
+ description: "Contact the parent/supervisor session for a blocking decision, structured interview, or progress update.",
227
+ parameters: ContactSupervisorParamsSchema,
228
+ execute(_id, params, signal) {
229
+ return sendSupervisorRequest(params, signal);
230
+ }
231
+ };
232
+ dm.registerTool(tool);
245
233
  }
246
234
  function parseRequestFile(file, channelDir) {
247
235
  try {
@@ -289,6 +277,75 @@ function listRequestFiles() {
289
277
  }
290
278
  return files;
291
279
  }
280
+ function readDirectoryEntries(dir) {
281
+ try {
282
+ return fs.readdirSync(dir, { withFileTypes: true });
283
+ } catch (error) {
284
+ if (error.code === "ENOENT")
285
+ return [];
286
+ return;
287
+ }
288
+ }
289
+ function directoryMtimeMs(dir) {
290
+ try {
291
+ return fs.statSync(dir).mtimeMs;
292
+ } catch {
293
+ return 0;
294
+ }
295
+ }
296
+ function removeEmptyDirectory(dir) {
297
+ try {
298
+ fs.rmdirSync(dir);
299
+ return true;
300
+ } catch (error) {
301
+ const code = error.code;
302
+ if (code === "ENOENT")
303
+ return true;
304
+ if (code === "ENOTEMPTY" || code === "EEXIST" || code === "EPERM" || code === "EBUSY")
305
+ return false;
306
+ throw error;
307
+ }
308
+ }
309
+ function removeStaleEmptySupervisorChannel(channelDir, nowMs) {
310
+ const requestsDir = path.join(channelDir, REQUESTS_DIR);
311
+ const repliesDir = path.join(channelDir, REPLIES_DIR);
312
+ const newestKnownMtimeMs = Math.max(directoryMtimeMs(channelDir), directoryMtimeMs(requestsDir), directoryMtimeMs(repliesDir));
313
+ if (nowMs - newestKnownMtimeMs < STALE_EMPTY_CHANNEL_AGE_MS)
314
+ return false;
315
+ const requestEntries = readDirectoryEntries(requestsDir);
316
+ if (!requestEntries || requestEntries.length > 0)
317
+ return false;
318
+ const replyEntries = readDirectoryEntries(repliesDir);
319
+ if (!replyEntries || replyEntries.length > 0)
320
+ return false;
321
+ if (!removeEmptyDirectory(requestsDir))
322
+ return false;
323
+ if (!removeEmptyDirectory(repliesDir))
324
+ return false;
325
+ if (!removeEmptyDirectory(channelDir))
326
+ return false;
327
+ return true;
328
+ }
329
+ function cleanupStaleEmptySupervisorChannels(nowMs = Date.now()) {
330
+ let channelEntries;
331
+ try {
332
+ channelEntries = fs.readdirSync(SUPERVISOR_CHANNEL_ROOT, { withFileTypes: true });
333
+ } catch (error) {
334
+ if (error.code === "ENOENT")
335
+ return 0;
336
+ throw error;
337
+ }
338
+ let removed = 0;
339
+ for (const entry of channelEntries) {
340
+ if (!entry.isDirectory())
341
+ continue;
342
+ try {
343
+ if (removeStaleEmptySupervisorChannel(path.join(SUPERVISOR_CHANNEL_ROOT, entry.name), nowMs))
344
+ removed++;
345
+ } catch {}
346
+ }
347
+ return removed;
348
+ }
292
349
  function currentContextSessionId(state, ctx) {
293
350
  try {
294
351
  const sessionId = ctx.sessionManager.getSessionId();
@@ -301,6 +358,89 @@ function requestMatchesContext(request, state, ctx) {
301
358
  const currentSessionId = currentContextSessionId(state, ctx);
302
359
  return Boolean(currentSessionId && request.orchestratorSessionId === currentSessionId);
303
360
  }
361
+ function rememberedForegroundChild(request, state) {
362
+ const run = state.foregroundRuns?.get(request.runId);
363
+ const child = run?.children.find((candidate) => candidate.index === request.childIndex && candidate.agent === request.agent) ?? run?.children[request.childIndex];
364
+ return run && child ? { run, child } : undefined;
365
+ }
366
+ function markForegroundSupervisorAttention(request, state) {
367
+ const remembered = rememberedForegroundChild(request, state);
368
+ if (!remembered || remembered.child.status !== "detached")
369
+ return;
370
+ const updatedAt = Date.now();
371
+ remembered.run.updatedAt = updatedAt;
372
+ remembered.child.activityState = "needs_attention";
373
+ remembered.child.lastActivityAt = request.createdAt;
374
+ remembered.child.currentTool = "contact_supervisor";
375
+ remembered.child.currentToolStartedAt = request.createdAt;
376
+ remembered.child.updatedAt = updatedAt;
377
+ }
378
+ function clearForegroundSupervisorAttention(request, pending, state) {
379
+ if ([...pending.values()].some((candidate) => candidate.expectsReply && candidate.runId === request.runId && candidate.agent === request.agent && candidate.childIndex === request.childIndex))
380
+ return;
381
+ const remembered = rememberedForegroundChild(request, state);
382
+ if (!remembered || remembered.child.status !== "detached")
383
+ return;
384
+ const updatedAt = Date.now();
385
+ remembered.run.updatedAt = updatedAt;
386
+ remembered.child.activityState = undefined;
387
+ remembered.child.lastActivityAt = updatedAt;
388
+ remembered.child.currentTool = undefined;
389
+ remembered.child.currentToolStartedAt = undefined;
390
+ remembered.child.updatedAt = updatedAt;
391
+ }
392
+ function removeRequestFile(file) {
393
+ try {
394
+ fs.rmSync(file, { force: true });
395
+ } catch {}
396
+ }
397
+ function requestExpiresAt(request, now) {
398
+ const expiresAt = request.expiresAt;
399
+ if (typeof expiresAt === "number" && Number.isFinite(expiresAt))
400
+ return expiresAt;
401
+ return Number.isFinite(request.createdAt) ? request.createdAt + askTimeoutMs() : now;
402
+ }
403
+ function requestRunInactive(request, state) {
404
+ if (state.foregroundControls.has(request.runId))
405
+ return false;
406
+ const foreground = rememberedForegroundChild(request, state);
407
+ if (foreground)
408
+ return foreground.child.status !== "detached";
409
+ const asyncJob = state.asyncJobs.get(request.runId);
410
+ if (!asyncJob)
411
+ return false;
412
+ if (asyncJob.status === "complete" || asyncJob.status === "failed" || asyncJob.status === "paused")
413
+ return true;
414
+ const stepStatus = asyncJob.steps?.[request.childIndex]?.status;
415
+ return stepStatus === "complete" || stepStatus === "completed" || stepStatus === "failed" || stepStatus === "paused";
416
+ }
417
+ function requestLifecycle(request, state, ctx, now) {
418
+ if (ctx && !requestMatchesContext(request, state, ctx))
419
+ return "wrong-session";
420
+ if (!fs.existsSync(request.requestFile))
421
+ return "missing";
422
+ if (request.expectsReply && fs.existsSync(replyPath(request.channelDir, request.id)))
423
+ return "resolved";
424
+ if (request.expectsReply && now > requestExpiresAt(request, now))
425
+ return "expired";
426
+ if (request.expectsReply && requestRunInactive(request, state))
427
+ return "inactive";
428
+ return "pending";
429
+ }
430
+ function cleanupRequestLifecycle(request, lifecycle) {
431
+ if (lifecycle === "resolved" || lifecycle === "expired" || lifecycle === "inactive")
432
+ removeRequestFile(request.requestFile);
433
+ }
434
+ function refreshPendingRequests(pending, state, ctx) {
435
+ const now = Date.now();
436
+ for (const request of pending.values()) {
437
+ const lifecycle = requestLifecycle(request, state, ctx, now);
438
+ if (lifecycle === "pending")
439
+ continue;
440
+ pending.delete(request.id);
441
+ cleanupRequestLifecycle(request, lifecycle);
442
+ }
443
+ }
304
444
  function formatPendingLine(request) {
305
445
  const replyHint = request.expectsReply ? ` Reply: ${NATIVE_SUPERVISOR_TOOL_NAME}({ action: "reply", replyTo: "${request.id}", message: "..." })` : "";
306
446
  return `- ${request.id}: ${request.agent} [${request.runId}#${request.childIndex}] ${request.reason}.${replyHint}`;
@@ -323,9 +463,7 @@ function writeReply(request, message) {
323
463
  message: message.trim()
324
464
  };
325
465
  writeAtomicJson(replyPath(request.channelDir, request.id), reply);
326
- try {
327
- fs.rmSync(request.requestFile, { force: true });
328
- } catch {}
466
+ removeRequestFile(request.requestFile);
329
467
  }
330
468
  function resolvePendingRequest(pending, params) {
331
469
  if (params.replyTo) {
@@ -359,13 +497,14 @@ function publicPendingRequests(pending) {
359
497
  expectsReply: request.expectsReply
360
498
  }));
361
499
  }
362
- function buildParentIntercomTool(pending, name = "intercom") {
500
+ function buildParentSupervisorTool(pending, state) {
363
501
  return {
364
- name,
365
- label: name === "intercom" ? "Intercom" : "Subagent Supervisor",
366
- description: name === "intercom" ? "Native dm-subagents supervisor channel. Use reply/pending/status to answer child subagent requests." : "Native dm-subagents supervisor channel. Use reply/pending/status to answer child subagent requests without overriding the optional intercom compatibility extension.",
502
+ name: NATIVE_SUPERVISOR_TOOL_NAME,
503
+ label: "Subagent Supervisor",
504
+ description: "Native dm-subagents supervisor channel. Use reply/pending/status to answer child subagent requests without overriding dm-intercom.",
367
505
  parameters: IntercomParamsSchema,
368
506
  async execute(_id, params) {
507
+ refreshPendingRequests(pending, state, state.lastUiContext ?? undefined);
369
508
  const input = params;
370
509
  if (input.action === "status") {
371
510
  return { content: [{ type: "text", text: `Native supervisor channel active. Pending replies: ${pending.size}.` }], details: { active: true, pending: pending.size, root: SUPERVISOR_CHANNEL_ROOT } };
@@ -379,44 +518,77 @@ function buildParentIntercomTool(pending, name = "intercom") {
379
518
  const request = resolvePendingRequest(pending, input);
380
519
  writeReply(request, input.message ?? "");
381
520
  pending.delete(request.id);
521
+ clearForegroundSupervisorAttention(request, pending, state);
382
522
  return { content: [{ type: "text", text: `Replied to supervisor request ${request.id}.` }], details: { replyTo: request.id, runId: request.runId, agent: request.agent } };
383
523
  }
384
524
  if (input.action === "send" || input.action === "ask") {
385
- throw new Error("Native dm-subagents intercom currently handles supervisor replies. Child agents initiate asks with contact_supervisor.");
525
+ throw new Error("The native subagent supervisor handles replies only. Child agents initiate asks with contact_supervisor.");
386
526
  }
387
- throw new Error(`Unsupported intercom action: ${input.action}`);
527
+ throw new Error(`Unsupported supervisor action: ${input.action}`);
388
528
  }
389
529
  };
390
530
  }
391
- export function createNativeSupervisorChannel(pi, state) {
531
+ export function createNativeSupervisorChannel(dm, state, deps = {}) {
532
+ const watch = deps.watch ?? fs.watch;
533
+ const timers = deps.timers ?? globalThis;
392
534
  const pending = new Map;
393
535
  const seenFiles = new Set;
536
+ const requestWatchers = new Map;
537
+ let rootWatcher;
394
538
  let poller;
539
+ let safetyPoller;
540
+ let deferredWatcherRefresh;
541
+ let started = false;
542
+ let lastStaleCleanupAt = 0;
543
+ const platform = deps.platform ?? process.platform;
544
+ const useNativeWatcher = () => shouldUseNativeFsWatch("supervisor-channel", platform) && platform !== "win32";
545
+ const hasTransportDemand = () => {
546
+ if (pending.size > 0)
547
+ return true;
548
+ if (state.foregroundControls.size > 0)
549
+ return true;
550
+ return [...state.asyncJobs.values()].some((job) => job.status === "queued" || job.status === "running");
551
+ };
395
552
  const registerParentTools = () => {
396
- if (!hasTool(pi, NATIVE_SUPERVISOR_TOOL_NAME))
397
- pi.registerTool(buildParentIntercomTool(pending, NATIVE_SUPERVISOR_TOOL_NAME));
398
- if (!hasTool(pi, "intercom"))
399
- pi.registerTool(buildParentIntercomTool(pending));
553
+ if (!hasTool(dm, NATIVE_SUPERVISOR_TOOL_NAME))
554
+ dm.registerTool(buildParentSupervisorTool(pending, state));
555
+ };
556
+ const cleanupStaleChannelsIfDue = () => {
557
+ const nowMs = Date.now();
558
+ if (nowMs - lastStaleCleanupAt < STALE_EMPTY_CHANNEL_CLEANUP_INTERVAL_MS)
559
+ return;
560
+ lastStaleCleanupAt = nowMs;
561
+ try {
562
+ cleanupStaleEmptySupervisorChannels(nowMs);
563
+ } catch {}
400
564
  };
401
565
  const poll = () => {
566
+ cleanupStaleChannelsIfDue();
402
567
  const ctx = state.lastUiContext;
403
568
  if (!ctx)
404
569
  return;
570
+ refreshPendingRequests(pending, state, ctx);
571
+ const now = Date.now();
405
572
  for (const { channelDir, file } of listRequestFiles()) {
406
573
  if (seenFiles.has(file))
407
574
  continue;
408
575
  const request = parseRequestFile(file, channelDir);
409
576
  if (!request || !requestMatchesContext(request, state, ctx))
410
577
  continue;
578
+ const lifecycle = requestLifecycle(request, state, undefined, now);
579
+ if (lifecycle !== "pending") {
580
+ seenFiles.add(file);
581
+ cleanupRequestLifecycle(request, lifecycle);
582
+ continue;
583
+ }
411
584
  seenFiles.add(file);
412
- if (request.expectsReply)
585
+ if (request.expectsReply) {
413
586
  pending.set(request.id, request);
414
- else {
415
- try {
416
- fs.rmSync(request.requestFile, { force: true });
417
- } catch {}
587
+ markForegroundSupervisorAttention(request, state);
588
+ } else {
589
+ removeRequestFile(request.requestFile);
418
590
  }
419
- pi.sendMessage({
591
+ dm.sendMessage({
420
592
  customType: "subagent_supervisor_request",
421
593
  content: requestVisibleText(request),
422
594
  display: true,
@@ -428,22 +600,142 @@ export function createNativeSupervisorChannel(pi, state) {
428
600
  agent: request.agent,
429
601
  childIndex: request.childIndex
430
602
  }
603
+ }, { triggerTurn: true });
604
+ if (request.expectsReply) {
605
+ dm.events?.emit(INTERCOM_DETACH_REQUEST_EVENT, {
606
+ requestId: request.id,
607
+ runId: request.runId,
608
+ agent: request.agent,
609
+ childIndex: request.childIndex
610
+ });
611
+ if (pending.has(request.id))
612
+ markForegroundSupervisorAttention(request, state);
613
+ }
614
+ }
615
+ };
616
+ const startPolling = () => {
617
+ if (poller)
618
+ return;
619
+ poller = timers.setInterval(() => {
620
+ poll();
621
+ if (!useNativeWatcher() && platform === "darwin" && !hasTransportDemand()) {
622
+ if (poller)
623
+ timers.clearInterval(poller);
624
+ poller = undefined;
625
+ }
626
+ }, CHANNEL_POLL_MS);
627
+ poller.unref?.();
628
+ };
629
+ const startSafetyPolling = () => {
630
+ if (safetyPoller)
631
+ return;
632
+ safetyPoller = timers.setInterval(() => {
633
+ watchExistingRequestDirs();
634
+ poll();
635
+ }, CHANNEL_SAFETY_POLL_MS);
636
+ safetyPoller.unref?.();
637
+ };
638
+ const watchRequestDir = (requestsDir) => {
639
+ if (requestWatchers.has(requestsDir))
640
+ return;
641
+ try {
642
+ const watcher = watch(requestsDir, () => poll());
643
+ watcher.on("error", () => {
644
+ try {
645
+ watcher.close();
646
+ } catch {}
647
+ requestWatchers.delete(requestsDir);
648
+ startPolling();
431
649
  });
650
+ watcher.unref?.();
651
+ requestWatchers.set(requestsDir, watcher);
652
+ } catch (error) {
653
+ if (error.code !== "ENOENT")
654
+ startPolling();
432
655
  }
433
656
  };
657
+ const watchExistingRequestDirs = () => {
658
+ let channelEntries;
659
+ try {
660
+ channelEntries = fs.readdirSync(SUPERVISOR_CHANNEL_ROOT, { withFileTypes: true });
661
+ } catch (error) {
662
+ if (error.code === "ENOENT")
663
+ return;
664
+ startPolling();
665
+ return;
666
+ }
667
+ for (const entry of channelEntries) {
668
+ if (entry.isDirectory())
669
+ watchRequestDir(path.join(SUPERVISOR_CHANNEL_ROOT, entry.name, REQUESTS_DIR));
670
+ }
671
+ };
672
+ const scheduleWatcherRefresh = () => {
673
+ if (deferredWatcherRefresh)
674
+ return;
675
+ deferredWatcherRefresh = timers.setImmediate(() => {
676
+ deferredWatcherRefresh = undefined;
677
+ if (!started)
678
+ return;
679
+ watchExistingRequestDirs();
680
+ poll();
681
+ });
682
+ deferredWatcherRefresh.unref?.();
683
+ };
434
684
  return {
685
+ activateTransport: () => {
686
+ if (!started)
687
+ return;
688
+ poll();
689
+ if (!useNativeWatcher() && hasTransportDemand())
690
+ startPolling();
691
+ },
435
692
  start: () => {
436
- if (poller)
693
+ if (started)
437
694
  return;
695
+ started = true;
438
696
  registerParentTools();
439
697
  poll();
440
- poller = setInterval(poll, CHANNEL_POLL_MS);
441
- poller.unref?.();
698
+ try {
699
+ fs.mkdirSync(SUPERVISOR_CHANNEL_ROOT, { recursive: true });
700
+ if (!useNativeWatcher()) {
701
+ if (platform === "win32")
702
+ startPolling();
703
+ return;
704
+ }
705
+ watchExistingRequestDirs();
706
+ rootWatcher = watch(SUPERVISOR_CHANNEL_ROOT, () => {
707
+ watchExistingRequestDirs();
708
+ poll();
709
+ scheduleWatcherRefresh();
710
+ });
711
+ rootWatcher.on("error", startPolling);
712
+ startSafetyPolling();
713
+ scheduleWatcherRefresh();
714
+ } catch {
715
+ startPolling();
716
+ }
442
717
  },
443
718
  dispose: () => {
719
+ started = false;
720
+ try {
721
+ rootWatcher?.close();
722
+ } catch {}
723
+ rootWatcher = undefined;
724
+ for (const watcher of requestWatchers.values()) {
725
+ try {
726
+ watcher.close();
727
+ } catch {}
728
+ }
729
+ requestWatchers.clear();
444
730
  if (poller)
445
- clearInterval(poller);
731
+ timers.clearInterval(poller);
446
732
  poller = undefined;
733
+ if (safetyPoller)
734
+ timers.clearInterval(safetyPoller);
735
+ safetyPoller = undefined;
736
+ if (deferredWatcherRefresh)
737
+ timers.clearImmediate(deferredWatcherRefresh);
738
+ deferredWatcherRefresh = undefined;
447
739
  pending.clear();
448
740
  seenFiles.clear();
449
741
  },