@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
@@ -2,10 +2,17 @@ import { createHash } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
5
+ import { findConfiguredProjectRoot } from "../../agents/agents.js";
5
6
  import { getAgentDir, getProjectConfigDir } from "../../shared/utils.js";
7
+ import { isMcpServerDefinition, loadAgentPluginMcpServers, loadPackageMcpServers } from "./mcp-config-sources.js";
8
+ import {
9
+ normalizeMcpDirectToolSelectors,
10
+ parseMcpDirectToolSelectors,
11
+ planMcpDirectToolGrant
12
+ } from "./mcp-direct-tool-grant.js";
13
+ export { formatUnresolvedMcpDirectToolSelectors } from "./mcp-direct-tool-grant.js";
6
14
  const CACHE_VERSION = 1;
7
15
  const CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
8
- const BUILTIN_TOOL_NAMES = new Set(["read", "bash", "edit", "write", "grep", "find", "ls", "mcp"]);
9
16
  const GENERIC_GLOBAL_CONFIG_PATH = path.join(os.homedir(), ".config", "mcp", "mcp.json");
10
17
  const IMPORT_PATHS = {
11
18
  cursor: [path.join(os.homedir(), ".cursor", "mcp.json")],
@@ -19,18 +26,41 @@ const IMPORT_PATHS = {
19
26
  windsurf: [path.join(os.homedir(), ".windsurf", "mcp.json")],
20
27
  vscode: [".vscode/mcp.json"]
21
28
  };
22
- export function resolveMcpDirectToolNames(mcpDirectTools, cwd = process.cwd()) {
23
- if (!mcpDirectTools?.length)
24
- return [];
25
- try {
26
- const config = loadMcpConfig(cwd);
27
- const cache = loadMetadataCache();
28
- if (!cache)
29
- return [];
30
- return resolveDirectToolNames(config, cache, getToolPrefix(config.settings?.toolPrefix), mcpDirectTools);
31
- } catch {
32
- return [];
29
+ export const MCP_RUNTIME_SNAPSHOT_EVENT = "dm-mcp-adapter:runtime-snapshot:v1";
30
+ export const MCP_RUNTIME_SNAPSHOT_VERSION = 1;
31
+ export function resolveMcpDirectToolResolution(mcpDirectTools, cwd = process.cwd(), runtimeSnapshotHost, configOverride) {
32
+ const selectors = normalizeMcpDirectToolSelectors(mcpDirectTools);
33
+ if (selectors.length === 0)
34
+ return { selections: [], unresolvedSelectors: [] };
35
+ const config = configOverride ?? loadMcpConfig(cwd);
36
+ const { servers: selectedServers, tools: selectedTools } = parseMcpDirectToolSelectors(selectors);
37
+ const runtimeSelectionServers = new Set([...selectedServers, ...selectedTools.keys()]);
38
+ const runtimeServers = resolveRuntimeMcpServers(config, runtimeSelectionServers, runtimeSnapshotHost);
39
+ const resolvedConfig = Object.keys(runtimeServers).length > 0 ? mergeConfigs(config, { mcpServers: runtimeServers }) : config;
40
+ validateSelectedServerDefinitions(resolvedConfig, selectors);
41
+ const cache = loadMetadataCache();
42
+ if (!cache)
43
+ return { selections: [], unresolvedSelectors: selectors };
44
+ const validMetadata = {};
45
+ for (const [serverName, definition] of Object.entries(resolvedConfig.mcpServers)) {
46
+ const serverCache = cache.servers[serverName];
47
+ if (isServerCacheValid(serverCache, definition))
48
+ validMetadata[serverName] = serverCache;
33
49
  }
50
+ const grant = planMcpDirectToolGrant({
51
+ selectors,
52
+ servers: resolvedConfig.mcpServers,
53
+ metadata: validMetadata,
54
+ toolPrefix: resolvedConfig.settings?.toolPrefix
55
+ });
56
+ return {
57
+ selections: grant.selections,
58
+ unresolvedSelectors: grant.unresolvedSelectors,
59
+ ...Object.keys(runtimeServers).length > 0 ? { mcpConfig: resolvedConfig, runtimeServerNames: Object.keys(runtimeServers) } : {}
60
+ };
61
+ }
62
+ export function resolveMcpDirectToolSelections(mcpDirectTools, cwd = process.cwd(), runtimeSnapshotHost) {
63
+ return resolveMcpDirectToolResolution(mcpDirectTools, cwd, runtimeSnapshotHost).selections;
34
64
  }
35
65
  function loadMetadataCache() {
36
66
  const cachePath = path.join(getAgentDir(), "mcp-cache.json");
@@ -40,28 +70,106 @@ function loadMetadataCache() {
40
70
  } catch {
41
71
  return null;
42
72
  }
43
- if (!parsed || typeof parsed !== "object")
44
- return null;
45
- const raw = parsed;
46
- if (raw.version !== CACHE_VERSION || !raw.servers || typeof raw.servers !== "object" || Array.isArray(raw.servers)) {
73
+ if (!isRecord(parsed) || parsed.version !== CACHE_VERSION || !isRecord(parsed.servers))
47
74
  return null;
75
+ const servers = {};
76
+ for (const [name, value] of Object.entries(parsed.servers)) {
77
+ const entry = parseServerCacheEntry(value);
78
+ if (entry)
79
+ servers[name] = entry;
80
+ }
81
+ return { version: CACHE_VERSION, servers };
82
+ }
83
+ function parseServerCacheEntry(value) {
84
+ if (!isRecord(value))
85
+ return;
86
+ if (value.configHash !== undefined && typeof value.configHash !== "string")
87
+ return;
88
+ if (value.cachedAt !== undefined && (typeof value.cachedAt !== "number" || !Number.isFinite(value.cachedAt)))
89
+ return;
90
+ if (value.tools !== undefined && !Array.isArray(value.tools))
91
+ return;
92
+ if (value.resources !== undefined && !Array.isArray(value.resources))
93
+ return;
94
+ const tools = value.tools?.map(parseCachedTool);
95
+ const resources = value.resources?.map(parseCachedResource);
96
+ if (tools && !tools.every((entry) => entry !== undefined))
97
+ return;
98
+ if (resources && !resources.every((entry) => entry !== undefined))
99
+ return;
100
+ return {
101
+ ...value.configHash !== undefined ? { configHash: value.configHash } : {},
102
+ ...value.cachedAt !== undefined ? { cachedAt: value.cachedAt } : {},
103
+ ...tools ? { tools } : {},
104
+ ...resources ? { resources } : {}
105
+ };
106
+ }
107
+ function parseCachedTool(value) {
108
+ if (!isRecord(value) || value.name !== undefined && typeof value.name !== "string")
109
+ return;
110
+ return value.name === undefined ? {} : { name: value.name };
111
+ }
112
+ function parseCachedResource(value) {
113
+ if (!isRecord(value))
114
+ return;
115
+ if (value.uri !== undefined && typeof value.uri !== "string")
116
+ return;
117
+ if (value.name !== undefined && typeof value.name !== "string")
118
+ return;
119
+ return {
120
+ ...value.uri !== undefined ? { uri: value.uri } : {},
121
+ ...value.name !== undefined ? { name: value.name } : {}
122
+ };
123
+ }
124
+ function resolveRuntimeMcpServers(config, selectedServers, runtimeSnapshotHost) {
125
+ if (!runtimeSnapshotHost)
126
+ return {};
127
+ const runtimeServers = {};
128
+ for (const serverName of selectedServers) {
129
+ if (Object.hasOwn(config.mcpServers, serverName))
130
+ continue;
131
+ try {
132
+ const snapshot = getRuntimeMcpServerSnapshot(runtimeSnapshotHost, serverName);
133
+ runtimeServers[serverName] = snapshot.definition;
134
+ } catch {}
48
135
  }
49
- return raw;
136
+ return runtimeServers;
137
+ }
138
+ function getRuntimeMcpServerSnapshot(host, name) {
139
+ const request = {
140
+ version: MCP_RUNTIME_SNAPSHOT_VERSION,
141
+ name
142
+ };
143
+ host.events.emit(MCP_RUNTIME_SNAPSHOT_EVENT, request);
144
+ if (!request.result)
145
+ throw new Error("dm-mcp-adapter is not installed for this DM instance");
146
+ if (!request.result.ok)
147
+ throw request.result.error;
148
+ const snapshot = request.result.snapshot;
149
+ if (!snapshot || snapshot.name !== name || snapshot.runtime !== true || snapshot.persisted !== false || !isMcpServerDefinition(snapshot.definition)) {
150
+ throw new Error(`Invalid MCP runtime snapshot for server "${name}"`);
151
+ }
152
+ return snapshot;
50
153
  }
51
154
  function loadMcpConfig(cwd) {
155
+ const resolvedCwd = path.resolve(cwd);
156
+ const projectRoot = findConfiguredProjectRoot(resolvedCwd) ?? resolvedCwd;
52
157
  let config = { mcpServers: {} };
53
- for (const sourcePath of getConfigPaths(cwd)) {
158
+ for (const sourcePath of getConfigPaths(projectRoot)) {
54
159
  const loaded = readConfig(sourcePath);
55
160
  if (!loaded)
56
161
  continue;
57
- config = mergeConfigs(config, expandImports(loaded, cwd));
162
+ config = mergeConfigs(config, expandImports(loaded, projectRoot));
58
163
  }
59
- return config;
164
+ const packageServers = loadPackageMcpServers(projectRoot);
165
+ const pluginServers = loadAgentPluginMcpServers(config.settings?.agentPluginPaths, projectRoot);
166
+ const packageOnlyServers = Object.fromEntries(Object.entries(packageServers).filter(([name]) => !Object.hasOwn(pluginServers, name)));
167
+ return mergeConfigs({ mcpServers: packageOnlyServers }, mergeConfigs({ mcpServers: pluginServers }, config));
60
168
  }
61
- function getConfigPaths(cwd) {
169
+ function getConfigPaths(projectRoot) {
62
170
  const piGlobalPath = path.join(getAgentDir(), "mcp.json");
63
- const projectPath = path.resolve(cwd, ".mcp.json");
64
- const projectPiPath = path.resolve(getProjectConfigDir(cwd), "mcp.json");
171
+ const projectPath = path.resolve(projectRoot, ".mcp.json");
172
+ const projectPiPath = path.resolve(getProjectConfigDir(projectRoot), "mcp.json");
65
173
  const sources = [];
66
174
  if (GENERIC_GLOBAL_CONFIG_PATH !== piGlobalPath)
67
175
  sources.push(GENERIC_GLOBAL_CONFIG_PATH);
@@ -82,15 +190,32 @@ function readConfig(configPath) {
82
190
  return validateConfig(parsed);
83
191
  }
84
192
  function validateConfig(raw) {
85
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
193
+ if (!isRecord(raw))
86
194
  return { mcpServers: {} };
87
195
  const obj = raw;
88
196
  const servers = obj.mcpServers ?? obj["mcp-servers"] ?? {};
89
197
  return {
90
- mcpServers: servers && typeof servers === "object" && !Array.isArray(servers) ? servers : {},
198
+ mcpServers: parseServerEntries(servers),
91
199
  imports: Array.isArray(obj.imports) ? obj.imports.filter((value) => isImportKind(value)) : undefined,
92
- settings: obj.settings && typeof obj.settings === "object" && !Array.isArray(obj.settings) ? obj.settings : undefined
200
+ settings: parseSettings(obj.settings)
201
+ };
202
+ }
203
+ function parseServerEntries(value) {
204
+ if (!isRecord(value))
205
+ return {};
206
+ return Object.fromEntries(Object.entries(value).filter((entry) => isMcpServerDefinition(entry[1])));
207
+ }
208
+ function parseSettings(value) {
209
+ if (!isRecord(value))
210
+ return;
211
+ const toolPrefix = value.toolPrefix === "server" || value.toolPrefix === "short" || value.toolPrefix === "none" ? value.toolPrefix : undefined;
212
+ const directTools = typeof value.directTools === "boolean" ? value.directTools : undefined;
213
+ const settings = {
214
+ ...toolPrefix ? { toolPrefix } : {},
215
+ ...directTools !== undefined ? { directTools } : {},
216
+ ...value.agentPluginPaths !== undefined ? { agentPluginPaths: value.agentPluginPaths } : {}
93
217
  };
218
+ return Object.keys(settings).length ? settings : undefined;
94
219
  }
95
220
  function mergeConfigs(base, next) {
96
221
  const imports = [...base.imports ?? [], ...next.imports ?? []];
@@ -134,74 +259,22 @@ function resolveImportPath(importKind, cwd) {
134
259
  return null;
135
260
  }
136
261
  function extractServers(config, kind) {
137
- if (!config || typeof config !== "object" || Array.isArray(config))
262
+ if (!isRecord(config))
138
263
  return {};
139
264
  const obj = config;
140
265
  const servers = kind === "cursor" || kind === "windsurf" || kind === "vscode" ? obj.mcpServers ?? obj["mcp-servers"] : obj.mcpServers;
141
- return servers && typeof servers === "object" && !Array.isArray(servers) ? servers : {};
266
+ return parseServerEntries(servers);
142
267
  }
143
- function resolveDirectToolNames(config, cache, prefix, envOverride) {
144
- const names = [];
145
- const seenNames = new Set;
146
- const { servers: selectedServers, tools: selectedTools } = parseSelections(envOverride);
147
- for (const [serverName, definition] of Object.entries(config.mcpServers)) {
148
- const serverCache = cache.servers[serverName];
149
- if (!isServerCacheValid(serverCache, definition))
150
- continue;
151
- const toolFilter = selectedServers.has(serverName) ? true : selectedTools.get(serverName);
152
- if (!toolFilter)
153
- continue;
154
- for (const tool of Array.isArray(serverCache.tools) ? serverCache.tools : []) {
155
- if (typeof tool?.name !== "string" || !tool.name)
156
- continue;
157
- if (toolFilter !== true && !toolFilter.has(tool.name))
158
- continue;
159
- if (isToolExcluded(tool.name, serverName, prefix, definition.excludeTools))
160
- continue;
161
- const prefixedName = formatToolName(tool.name, serverName, prefix);
162
- if (BUILTIN_TOOL_NAMES.has(prefixedName) || seenNames.has(prefixedName))
163
- continue;
164
- seenNames.add(prefixedName);
165
- names.push(prefixedName);
166
- }
167
- if (definition.exposeResources === false)
168
- continue;
169
- for (const resource of Array.isArray(serverCache.resources) ? serverCache.resources : []) {
170
- if (typeof resource?.name !== "string" || !resource.name || typeof resource.uri !== "string" || !resource.uri)
171
- continue;
172
- const baseName = `get_${resourceNameToToolName(resource.name)}`;
173
- if (toolFilter !== true && !toolFilter.has(baseName))
174
- continue;
175
- if (isToolExcluded(baseName, serverName, prefix, definition.excludeTools))
176
- continue;
177
- const prefixedName = formatToolName(baseName, serverName, prefix);
178
- if (BUILTIN_TOOL_NAMES.has(prefixedName) || seenNames.has(prefixedName))
179
- continue;
180
- seenNames.add(prefixedName);
181
- names.push(prefixedName);
182
- }
183
- }
184
- return names;
185
- }
186
- function parseSelections(selections) {
187
- const servers = new Set;
188
- const tools = new Map;
189
- for (let item of selections) {
190
- item = item.replace(/\/+$/, "");
191
- if (item.includes("/")) {
192
- const [server, tool] = item.split("/", 2);
193
- if (server && tool) {
194
- if (!tools.has(server))
195
- tools.set(server, new Set);
196
- tools.get(server).add(tool);
197
- } else if (server) {
198
- servers.add(server);
199
- }
200
- } else if (item) {
201
- servers.add(item);
202
- }
268
+ export function resolveMcpDirectToolNames(mcpDirectTools, cwd = process.cwd()) {
269
+ return resolveMcpDirectToolSelections(mcpDirectTools, cwd).map((selection) => selection.name);
270
+ }
271
+ function validateSelectedServerDefinitions(config, selectors) {
272
+ const { servers, tools } = parseMcpDirectToolSelectors(selectors);
273
+ for (const serverName of new Set([...servers, ...tools.keys()])) {
274
+ const definition = config.mcpServers[serverName];
275
+ if (definition)
276
+ computeMcpServerHash(definition);
203
277
  }
204
- return { servers, tools };
205
278
  }
206
279
  function isServerCacheValid(entry, definition) {
207
280
  if (!entry || entry.configHash !== computeMcpServerHash(definition))
@@ -214,72 +287,74 @@ export function computeMcpServerHash(definition) {
214
287
  const identity = {
215
288
  command: definition.command,
216
289
  args: definition.args,
290
+ socket: resolveConfigPath(definition.socket),
217
291
  env: interpolateEnvRecord(definition.env),
218
292
  cwd: resolveConfigPath(definition.cwd),
219
- url: definition.url,
293
+ url: resolveServerUrl(definition),
220
294
  headers: interpolateEnvRecord(definition.headers),
295
+ requestHeadersCommand: definition.requestHeadersCommand ? {
296
+ command: interpolateEnvVars(definition.requestHeadersCommand.command),
297
+ args: definition.requestHeadersCommand.args?.map(interpolateEnvVars),
298
+ env: interpolateEnvRecord(definition.requestHeadersCommand.env),
299
+ timeoutMs: definition.requestHeadersCommand.timeoutMs
300
+ } : undefined,
221
301
  auth: definition.auth,
222
302
  bearerToken: resolveBearerToken(definition),
223
303
  bearerTokenEnv: definition.bearerTokenEnv,
224
304
  exposeResources: definition.exposeResources,
225
- excludeTools: definition.excludeTools
305
+ includeTools: definition.includeTools,
306
+ excludeTools: definition.excludeTools,
307
+ protocolVersion: definition.protocolVersion
226
308
  };
227
309
  return createHash("sha256").update(stableStringify(identity)).digest("hex");
228
310
  }
229
- function getToolPrefix(value) {
230
- return value === "none" || value === "short" || value === "server" ? value : "server";
231
- }
232
311
  function isImportKind(value) {
233
312
  return typeof value === "string" && Object.hasOwn(IMPORT_PATHS, value);
234
313
  }
235
- function getServerPrefix(serverName, mode) {
236
- if (mode === "none")
237
- return "";
238
- if (mode === "short") {
239
- const short = serverName.replace(/-?mcp$/i, "").replace(/-/g, "_");
240
- return short || "mcp";
241
- }
242
- return serverName.replace(/-/g, "_");
314
+ function isRecord(value) {
315
+ return value !== null && typeof value === "object" && !Array.isArray(value);
243
316
  }
244
- function formatToolName(toolName, serverName, prefix) {
245
- const serverPrefix = getServerPrefix(serverName, prefix);
246
- return serverPrefix ? `${serverPrefix}_${toolName}` : toolName;
317
+ function interpolateEnvRecord(values) {
318
+ if (!values)
319
+ return;
320
+ return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, interpolateSecretExpression(value)]));
247
321
  }
248
- function isToolExcluded(toolName, serverName, prefix, excludeTools) {
249
- if (!Array.isArray(excludeTools) || excludeTools.length === 0)
250
- return false;
251
- const candidates = new Set([
252
- normalizeToolName(toolName),
253
- normalizeToolName(formatToolName(toolName, serverName, prefix)),
254
- normalizeToolName(formatToolName(toolName, serverName, "server")),
255
- normalizeToolName(formatToolName(toolName, serverName, "short"))
256
- ]);
257
- return excludeTools.some((excluded) => typeof excluded === "string" && candidates.has(normalizeToolName(excluded)));
258
- }
259
- function normalizeToolName(value) {
260
- return value.replace(/-/g, "_");
261
- }
262
- function resourceNameToToolName(name) {
263
- let result = name.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_+/, "").replace(/_+$/, "").toLowerCase();
264
- if (!result || /^\d/.test(result))
265
- result = `resource${result ? `_${result}` : ""}`;
266
- return result;
322
+ function interpolateEnvVars(value) {
323
+ return value.replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] ?? "").replace(/\$env:(\w+)/g, (_, name) => process.env[name] ?? "").replace(/\{env:(\w+)\}/g, (_, name) => process.env[name] ?? "");
267
324
  }
268
- function interpolateEnvRecord(values) {
269
- if (!values || typeof values !== "object" || Array.isArray(values))
325
+ function interpolateSecretExpression(value) {
326
+ if (value.startsWith("!!"))
327
+ return interpolateEnvVars(value.slice(1));
328
+ return value.startsWith("!") ? value : interpolateEnvVars(value);
329
+ }
330
+ function getMissingEnvVars(value) {
331
+ const missing = new Set;
332
+ for (const match of value.matchAll(/\$\{(\w+)\}|\$env:(\w+)|\{env:(\w+)\}/g)) {
333
+ const name = match[1] ?? match[2] ?? match[3];
334
+ if (name && process.env[name] === undefined)
335
+ missing.add(name);
336
+ }
337
+ return [...missing];
338
+ }
339
+ function resolveServerUrl(definition) {
340
+ if (definition.url == null)
270
341
  return;
271
- const resolved = {};
272
- for (const [key, value] of Object.entries(values)) {
273
- if (typeof value === "string")
274
- resolved[key] = interpolateEnvVars(value);
342
+ if (typeof definition.url !== "string")
343
+ throw new Error("MCP server URL must be a string");
344
+ const missing = getMissingEnvVars(definition.url);
345
+ if (missing.length > 0) {
346
+ throw new Error(`Missing environment variable${missing.length === 1 ? "" : "s"} in MCP server URL: ${missing.join(", ")}`);
347
+ }
348
+ const resolved = interpolateEnvVars(definition.url);
349
+ try {
350
+ new URL(resolved);
351
+ } catch (error) {
352
+ throw new Error(`Invalid MCP server URL after environment interpolation: ${resolved}`, { cause: error });
275
353
  }
276
354
  return resolved;
277
355
  }
278
- function interpolateEnvVars(value) {
279
- return value.replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] ?? "").replace(/\$env:(\w+)/g, (_, name) => process.env[name] ?? "");
280
- }
281
356
  function resolveConfigPath(value) {
282
- if (typeof value !== "string")
357
+ if (value === undefined)
283
358
  return;
284
359
  const resolved = interpolateEnvVars(value);
285
360
  if (resolved === "~")
@@ -289,9 +364,9 @@ function resolveConfigPath(value) {
289
364
  return resolved;
290
365
  }
291
366
  function resolveBearerToken(definition) {
292
- if (typeof definition.bearerToken === "string")
293
- return interpolateEnvVars(definition.bearerToken);
294
- return typeof definition.bearerTokenEnv === "string" ? process.env[definition.bearerTokenEnv] : undefined;
367
+ if (definition.bearerToken !== undefined)
368
+ return interpolateSecretExpression(definition.bearerToken);
369
+ return definition.bearerTokenEnv ? process.env[definition.bearerTokenEnv] : undefined;
295
370
  }
296
371
  function stableStringify(value) {
297
372
  if (value === null || value === undefined || typeof value !== "object") {
@@ -0,0 +1,131 @@
1
+ const BUILTIN_TOOL_NAMES = new Set(["read", "bash", "edit", "write", "grep", "find", "ls", "mcp"]);
2
+ export function normalizeMcpDirectToolSelectors(selectors) {
3
+ return [...new Set((selectors ?? []).map((selector) => selector.replace(/\/+$/, "")).filter(Boolean))];
4
+ }
5
+ export function parseMcpDirectToolSelectors(selectors) {
6
+ const servers = new Set;
7
+ const tools = new Map;
8
+ for (const item of selectors) {
9
+ if (item.includes("/")) {
10
+ const [server, tool] = item.split("/", 2);
11
+ if (server && tool) {
12
+ if (!tools.has(server))
13
+ tools.set(server, new Set);
14
+ tools.get(server).add(tool);
15
+ } else if (server) {
16
+ servers.add(server);
17
+ }
18
+ } else if (item) {
19
+ servers.add(item);
20
+ }
21
+ }
22
+ return { servers, tools };
23
+ }
24
+ export function planMcpDirectToolGrant(input) {
25
+ const selectors = normalizeMcpDirectToolSelectors(input.selectors);
26
+ if (selectors.length === 0)
27
+ return { selections: [], unresolvedSelectors: [] };
28
+ const { servers: selectedServers, tools: selectedTools } = parseMcpDirectToolSelectors(selectors);
29
+ const selections = [];
30
+ const seenNames = new Set;
31
+ const prefix = normalizeMcpToolPrefix(input.toolPrefix);
32
+ for (const [serverName, server] of Object.entries(input.servers)) {
33
+ const metadata = input.metadata[serverName];
34
+ if (!metadata)
35
+ continue;
36
+ const toolFilter = selectedServers.has(serverName) ? true : selectedTools.get(serverName);
37
+ if (!toolFilter)
38
+ continue;
39
+ for (const tool of Array.isArray(metadata.tools) ? metadata.tools : []) {
40
+ if (typeof tool?.name !== "string" || !tool.name)
41
+ continue;
42
+ if (toolFilter !== true && !toolFilter.has(tool.name))
43
+ continue;
44
+ if (!isToolAllowed(tool.name, serverName, prefix, server.includeTools, server.excludeTools))
45
+ continue;
46
+ const name = formatToolName(tool.name, serverName, prefix);
47
+ if (BUILTIN_TOOL_NAMES.has(name) || seenNames.has(name))
48
+ continue;
49
+ seenNames.add(name);
50
+ selections.push({ name, selector: `${serverName}/${tool.name}` });
51
+ }
52
+ if (server.exposeResources === false)
53
+ continue;
54
+ for (const resource of Array.isArray(metadata.resources) ? metadata.resources : []) {
55
+ if (typeof resource?.name !== "string" || !resource.name || typeof resource.uri !== "string" || !resource.uri)
56
+ continue;
57
+ const baseName = `get_${resourceNameToToolName(resource.name)}`;
58
+ if (toolFilter !== true && !toolFilter.has(baseName))
59
+ continue;
60
+ if (!isToolAllowed(baseName, serverName, prefix, server.includeTools, server.excludeTools))
61
+ continue;
62
+ const name = formatToolName(baseName, serverName, prefix);
63
+ if (BUILTIN_TOOL_NAMES.has(name) || seenNames.has(name))
64
+ continue;
65
+ seenNames.add(name);
66
+ selections.push({ name, selector: `${serverName}/${baseName}` });
67
+ }
68
+ }
69
+ const unresolvedSelectors = selectors.filter((selector) => selector.includes("/") ? !selections.some((selection) => selection.selector === selector) : !selections.some((selection) => selection.selector.startsWith(`${selector}/`)));
70
+ return { selections, unresolvedSelectors };
71
+ }
72
+ export function normalizeMcpToolPrefix(value) {
73
+ return value === "none" || value === "short" || value === "server" ? value : "server";
74
+ }
75
+ export function formatUnresolvedMcpDirectToolSelectors(selectors) {
76
+ return `Unresolved MCP direct-tool selectors: ${selectors.join(", ")}. Direct MCP tools require a matching configured server and fresh metadata cache; runtime-registered servers require a host/dm-mcp-adapter handoff before child launch.`;
77
+ }
78
+ function getServerPrefix(serverName, mode) {
79
+ if (mode === "none")
80
+ return "";
81
+ if (mode === "short")
82
+ return serverName.replace(/-?mcp$/i, "") || "mcp";
83
+ return serverName;
84
+ }
85
+ function formatToolName(toolName, serverName, prefix) {
86
+ const serverPrefix = getServerPrefix(serverName, prefix);
87
+ return serverPrefix ? `${serverPrefix}_${toolName}` : toolName;
88
+ }
89
+ function isToolAllowed(toolName, serverName, prefix, includeTools, excludeTools) {
90
+ const candidates = toolNameCandidates(toolName, serverName, prefix);
91
+ return (!Array.isArray(includeTools) || includeTools.length === 0 || matchesToolPatterns(candidates, includeTools)) && !matchesToolPatterns(candidates, excludeTools);
92
+ }
93
+ function toolNameCandidates(toolName, serverName, prefix) {
94
+ return new Set([
95
+ toolName,
96
+ `mcp_${toolName}`,
97
+ formatToolName(toolName, serverName, prefix),
98
+ formatToolName(toolName, serverName, "server"),
99
+ formatToolName(toolName, serverName, "short"),
100
+ formatToolName(toolName, serverName, "none")
101
+ ]);
102
+ }
103
+ function matchesToolPatterns(candidates, patterns) {
104
+ if (!Array.isArray(patterns) || patterns.length === 0)
105
+ return false;
106
+ for (const pattern of patterns) {
107
+ if (typeof pattern !== "string")
108
+ continue;
109
+ const normalizedPattern = normalizeToolName(pattern);
110
+ const matcher = normalizedPattern.includes("*") || normalizedPattern.includes("?") ? globToRegExp(normalizedPattern) : undefined;
111
+ for (const candidate of candidates) {
112
+ const normalizedCandidate = normalizeToolName(candidate);
113
+ if (matcher ? matcher.test(normalizedCandidate) : normalizedCandidate === normalizedPattern)
114
+ return true;
115
+ }
116
+ }
117
+ return false;
118
+ }
119
+ function globToRegExp(pattern) {
120
+ const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
121
+ return new RegExp(`^${escaped}$`);
122
+ }
123
+ function normalizeToolName(value) {
124
+ return value.replace(/-/g, "_");
125
+ }
126
+ function resourceNameToToolName(name) {
127
+ let result = name.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_+/, "").replace(/_+$/, "").toLowerCase();
128
+ if (!result || /^\d/.test(result))
129
+ result = `resource${result ? `_${result}` : ""}`;
130
+ return result;
131
+ }