mixdog 0.7.17 → 0.8.0

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 (836) hide show
  1. package/README.md +37 -331
  2. package/package.json +67 -99
  3. package/scripts/boot-smoke.mjs +94 -0
  4. package/scripts/build-tui.mjs +52 -0
  5. package/scripts/compact-smoke.mjs +199 -0
  6. package/scripts/lead-workflow-smoke.mjs +598 -0
  7. package/scripts/live-worker-smoke.mjs +239 -0
  8. package/scripts/output-style-smoke.mjs +101 -0
  9. package/scripts/smoke-loop-report.mjs +221 -0
  10. package/scripts/smoke-loop.mjs +201 -0
  11. package/scripts/smoke.mjs +113 -0
  12. package/scripts/tool-failures.mjs +143 -0
  13. package/scripts/tool-smoke.mjs +456 -0
  14. package/src/agents/debugger/AGENT.md +3 -0
  15. package/src/agents/debugger/agent.json +6 -0
  16. package/src/agents/explore/AGENT.md +4 -0
  17. package/src/agents/explore/agent.json +6 -0
  18. package/src/agents/heavy-worker/AGENT.md +3 -0
  19. package/src/agents/heavy-worker/agent.json +6 -0
  20. package/src/agents/maintainer/AGENT.md +3 -0
  21. package/src/agents/maintainer/agent.json +6 -0
  22. package/src/agents/reviewer/AGENT.md +3 -0
  23. package/src/agents/reviewer/agent.json +6 -0
  24. package/src/agents/scheduler-task.md +3 -0
  25. package/src/agents/web-researcher/AGENT.md +3 -0
  26. package/src/agents/web-researcher/agent.json +6 -0
  27. package/src/agents/webhook-handler.md +3 -0
  28. package/src/agents/worker/AGENT.md +3 -0
  29. package/src/agents/worker/agent.json +6 -0
  30. package/src/app.mjs +90 -0
  31. package/src/cli.mjs +11 -0
  32. package/src/defaults/hidden-roles.json +72 -0
  33. package/src/defaults/mixdog-config.template.json +15 -0
  34. package/src/hooks/lib/permission-evaluator.cjs +488 -0
  35. package/src/hooks/lib/settings-loader.cjs +112 -0
  36. package/src/lib/keychain-cjs.cjs +332 -0
  37. package/src/lib/plugin-paths.cjs +28 -0
  38. package/src/lib/rules-builder.cjs +315 -0
  39. package/src/mixdog-session-runtime.mjs +3704 -0
  40. package/src/output-styles/default.md +38 -0
  41. package/src/output-styles/extreme-simple.md +17 -0
  42. package/src/output-styles/simple.md +17 -0
  43. package/src/repl.mjs +322 -0
  44. package/src/rules/bridge/00-common.md +5 -0
  45. package/src/rules/bridge/20-skip-protocol.md +11 -0
  46. package/src/rules/bridge/30-explorer.md +4 -0
  47. package/src/rules/bridge/40-cycle1-agent.md +28 -0
  48. package/src/rules/bridge/41-cycle2-agent.md +59 -0
  49. package/src/rules/lead/00-tool-lead.md +5 -0
  50. package/src/rules/lead/01-general.md +5 -0
  51. package/src/rules/lead/02-channels.md +3 -0
  52. package/src/rules/lead/04-workflow.md +12 -0
  53. package/src/rules/shared/00-language.md +3 -0
  54. package/src/rules/shared/01-tool.md +3 -0
  55. package/src/runtime/agent/orchestrator/bridge-trace.mjs +814 -0
  56. package/src/runtime/agent/orchestrator/cache-mtime.mjs +60 -0
  57. package/src/runtime/agent/orchestrator/config.mjs +446 -0
  58. package/src/runtime/agent/orchestrator/context/collect.mjs +796 -0
  59. package/src/runtime/agent/orchestrator/dispatch-persist.mjs +417 -0
  60. package/src/runtime/agent/orchestrator/internal-roles.mjs +188 -0
  61. package/src/runtime/agent/orchestrator/internal-tools.mjs +88 -0
  62. package/src/runtime/agent/orchestrator/mcp/client.mjs +345 -0
  63. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2104 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +784 -0
  65. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +341 -0
  66. package/src/runtime/agent/orchestrator/providers/gemini.mjs +1679 -0
  67. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +959 -0
  68. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +213 -0
  69. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +38 -0
  70. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +471 -0
  71. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +615 -0
  72. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +808 -0
  73. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +1719 -0
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2587 -0
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +1953 -0
  76. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +136 -0
  77. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +317 -0
  78. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +109 -0
  79. package/src/runtime/agent/orchestrator/providers/registry.mjs +247 -0
  80. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +332 -0
  81. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +11 -0
  82. package/src/runtime/agent/orchestrator/providers/trace-utils.mjs +50 -0
  83. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
  84. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +318 -0
  85. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +367 -0
  86. package/src/runtime/agent/orchestrator/session/compact.mjs +882 -0
  87. package/src/runtime/agent/orchestrator/session/context-utils.mjs +233 -0
  88. package/src/runtime/agent/orchestrator/session/loop.mjs +2320 -0
  89. package/src/runtime/agent/orchestrator/session/manager.mjs +2960 -0
  90. package/src/runtime/agent/orchestrator/session/result-classification.mjs +65 -0
  91. package/src/runtime/agent/orchestrator/session/store.mjs +663 -0
  92. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +166 -0
  93. package/src/runtime/agent/orchestrator/smart-bridge/bridge-llm.mjs +339 -0
  94. package/src/runtime/agent/orchestrator/smart-bridge/cache-strategy.mjs +419 -0
  95. package/src/runtime/agent/orchestrator/stall-policy.mjs +227 -0
  96. package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +235 -0
  97. package/src/runtime/agent/orchestrator/tools/bash-session.mjs +723 -0
  98. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +389 -0
  99. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +637 -0
  100. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +165 -0
  101. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +104 -0
  102. package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +194 -0
  103. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +596 -0
  104. package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +110 -0
  105. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +153 -0
  106. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
  107. package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +189 -0
  108. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +731 -0
  109. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +168 -0
  110. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
  111. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +465 -0
  112. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +160 -0
  113. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +982 -0
  114. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1087 -0
  115. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +231 -0
  116. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +223 -0
  117. package/src/runtime/agent/orchestrator/tools/builtin.mjs +478 -0
  118. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
  119. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4102 -0
  120. package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +323 -0
  121. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +154 -0
  122. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +26 -0
  123. package/src/runtime/agent/orchestrator/tools/patch-binary-fetcher.mjs +143 -0
  124. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +18 -0
  125. package/src/runtime/agent/orchestrator/tools/patch.mjs +2772 -0
  126. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +114 -0
  127. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +880 -0
  128. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +312 -0
  129. package/src/runtime/channels/backends/discord.mjs +781 -0
  130. package/src/runtime/channels/data/voice-runtime-manifest.json +138 -0
  131. package/src/runtime/channels/index.mjs +3309 -0
  132. package/src/runtime/channels/lib/config.mjs +285 -0
  133. package/src/runtime/channels/lib/drop-trace.mjs +71 -0
  134. package/src/runtime/channels/lib/event-pipeline.mjs +81 -0
  135. package/src/runtime/channels/lib/holidays.mjs +138 -0
  136. package/src/runtime/channels/lib/hook-pipe-server.mjs +671 -0
  137. package/src/runtime/channels/lib/output-forwarder.mjs +765 -0
  138. package/src/runtime/channels/lib/runtime-paths.mjs +497 -0
  139. package/src/runtime/channels/lib/scheduler.mjs +710 -0
  140. package/src/runtime/channels/lib/session-discovery.mjs +102 -0
  141. package/src/runtime/channels/lib/state-file.mjs +68 -0
  142. package/src/runtime/channels/lib/status-snapshot.mjs +224 -0
  143. package/src/runtime/channels/lib/tool-format.mjs +124 -0
  144. package/src/runtime/channels/lib/transcript-discovery.mjs +195 -0
  145. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +734 -0
  146. package/src/runtime/channels/lib/webhook.mjs +1288 -0
  147. package/src/runtime/channels/tool-defs.mjs +177 -0
  148. package/src/runtime/lib/keychain-cjs.cjs +289 -0
  149. package/src/runtime/memory/data/runtime-manifest.json +40 -0
  150. package/src/runtime/memory/index.mjs +3600 -0
  151. package/src/runtime/memory/lib/core-memory-store.mjs +336 -0
  152. package/src/runtime/memory/lib/embedding-provider.mjs +275 -0
  153. package/src/runtime/memory/lib/embedding-worker.mjs +331 -0
  154. package/src/runtime/memory/lib/memory-cycle-requests.mjs +276 -0
  155. package/src/runtime/memory/lib/memory-cycle1.mjs +783 -0
  156. package/src/runtime/memory/lib/memory-cycle2.mjs +1389 -0
  157. package/src/runtime/memory/lib/memory-cycle3.mjs +646 -0
  158. package/src/runtime/memory/lib/memory-embed.mjs +300 -0
  159. package/src/runtime/memory/lib/memory-ops-policy.mjs +149 -0
  160. package/src/runtime/memory/lib/memory-recall-store.mjs +644 -0
  161. package/src/runtime/memory/lib/memory.mjs +418 -0
  162. package/src/runtime/memory/lib/pg/adapter.mjs +314 -0
  163. package/src/runtime/memory/lib/pg/process.mjs +366 -0
  164. package/src/runtime/memory/lib/pg/supervisor.mjs +495 -0
  165. package/src/runtime/memory/lib/runtime-fetcher.mjs +464 -0
  166. package/src/runtime/memory/lib/trace-store.mjs +734 -0
  167. package/src/runtime/memory/tool-defs.mjs +79 -0
  168. package/src/runtime/search/index.mjs +925 -0
  169. package/src/runtime/search/lib/config.mjs +61 -0
  170. package/src/runtime/search/lib/web-tools.mjs +1278 -0
  171. package/src/runtime/search/tool-defs.mjs +64 -0
  172. package/src/runtime/shared/atomic-file.mjs +435 -0
  173. package/src/runtime/shared/background-tasks.mjs +376 -0
  174. package/src/runtime/shared/child-guardian.mjs +98 -0
  175. package/src/runtime/shared/config.mjs +393 -0
  176. package/src/runtime/shared/err-text.mjs +121 -0
  177. package/src/runtime/shared/launcher-control.mjs +259 -0
  178. package/src/runtime/shared/llm/cost.mjs +66 -0
  179. package/src/runtime/shared/llm/http-agent.mjs +129 -0
  180. package/src/runtime/shared/open-url.mjs +37 -0
  181. package/src/runtime/shared/plugin-paths.mjs +25 -0
  182. package/src/runtime/shared/process-shutdown.mjs +147 -0
  183. package/src/runtime/shared/schedules-store.mjs +70 -0
  184. package/src/runtime/shared/tool-execution-contract.mjs +104 -0
  185. package/src/runtime/shared/tool-surface.mjs +950 -0
  186. package/src/runtime/shared/user-cwd.mjs +221 -0
  187. package/src/runtime/shared/user-data-guard.mjs +232 -0
  188. package/src/runtime/shared/workspace-router.mjs +259 -0
  189. package/src/standalone/bridge-tool.mjs +1414 -0
  190. package/src/standalone/channel-admin.mjs +366 -0
  191. package/src/standalone/channel-worker-preload.cjs +3 -0
  192. package/src/standalone/channel-worker.mjs +353 -0
  193. package/src/standalone/explore-tool.mjs +233 -0
  194. package/src/standalone/hook-bus.mjs +246 -0
  195. package/src/standalone/plugin-admin.mjs +247 -0
  196. package/src/standalone/provider-admin.mjs +338 -0
  197. package/src/standalone/seeds.mjs +94 -0
  198. package/src/standalone/usage-dashboard.mjs +510 -0
  199. package/src/tui/App.jsx +5438 -0
  200. package/src/tui/components/AnsiText.jsx +199 -0
  201. package/src/tui/components/ContextPanel.jsx +217 -0
  202. package/src/tui/components/Markdown.jsx +205 -0
  203. package/src/tui/components/MarkdownTable.jsx +204 -0
  204. package/src/tui/components/Message.jsx +103 -0
  205. package/src/tui/components/Picker.jsx +317 -0
  206. package/src/tui/components/PromptInput.jsx +584 -0
  207. package/src/tui/components/QueuedCommands.jsx +47 -0
  208. package/src/tui/components/SlashCommandPalette.jsx +114 -0
  209. package/src/tui/components/Spinner.jsx +317 -0
  210. package/src/tui/components/StatusLine.jsx +87 -0
  211. package/src/tui/components/TextEntryPanel.jsx +323 -0
  212. package/src/tui/components/ToolExecution.jsx +772 -0
  213. package/src/tui/components/TurnDone.jsx +78 -0
  214. package/src/tui/components/UsagePanel.jsx +331 -0
  215. package/src/tui/dist/index.mjs +12359 -0
  216. package/src/tui/engine.mjs +2410 -0
  217. package/src/tui/figures.mjs +50 -0
  218. package/src/tui/hooks/useEngine.mjs +16 -0
  219. package/src/tui/index.jsx +254 -0
  220. package/src/tui/input-editing.mjs +242 -0
  221. package/src/tui/markdown/format-token.mjs +194 -0
  222. package/src/tui/paste-attachments.mjs +198 -0
  223. package/src/tui/runtime/shared/process-shutdown.mjs +1 -0
  224. package/src/tui/spinner-verbs.mjs +45 -0
  225. package/src/tui/theme.mjs +67 -0
  226. package/src/tui/time-format.mjs +53 -0
  227. package/src/ui/ansi.mjs +115 -0
  228. package/src/ui/markdown.mjs +195 -0
  229. package/src/ui/statusline.mjs +730 -0
  230. package/src/ui/tool-card.mjs +101 -0
  231. package/src/vendor/statusline/bin/statusline-lib.mjs +805 -0
  232. package/src/vendor/statusline/bin/statusline-route.mjs +596 -0
  233. package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +285 -0
  234. package/src/vendor/statusline/src/gateway/claude-current.mjs +320 -0
  235. package/src/vendor/statusline/src/gateway/route-meta.mjs +753 -0
  236. package/src/vendor/statusline/src/gateway/session-routes.mjs +244 -0
  237. package/src/workflows/default/WORKFLOW.md +7 -0
  238. package/src/workflows/default/workflow.json +14 -0
  239. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  240. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  241. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  242. package/vendor/ink/build/colorize.d.ts +3 -0
  243. package/vendor/ink/build/colorize.js +48 -0
  244. package/vendor/ink/build/colorize.js.map +1 -0
  245. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  246. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  247. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  248. package/vendor/ink/build/components/AnimationContext.d.ts +9 -0
  249. package/vendor/ink/build/components/AnimationContext.js +13 -0
  250. package/vendor/ink/build/components/AnimationContext.js.map +1 -0
  251. package/vendor/ink/build/components/App.d.ts +24 -0
  252. package/vendor/ink/build/components/App.js +554 -0
  253. package/vendor/ink/build/components/App.js.map +1 -0
  254. package/vendor/ink/build/components/AppContext.d.ts +80 -0
  255. package/vendor/ink/build/components/AppContext.js +25 -0
  256. package/vendor/ink/build/components/AppContext.js.map +1 -0
  257. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  258. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  259. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  260. package/vendor/ink/build/components/Box.d.ts +130 -0
  261. package/vendor/ink/build/components/Box.js +34 -0
  262. package/vendor/ink/build/components/Box.js.map +1 -0
  263. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  264. package/vendor/ink/build/components/CursorContext.js +8 -0
  265. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  266. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  267. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  268. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  269. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  270. package/vendor/ink/build/components/ErrorOverview.js +90 -0
  271. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  272. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  273. package/vendor/ink/build/components/FocusContext.js +17 -0
  274. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  275. package/vendor/ink/build/components/Newline.d.ts +13 -0
  276. package/vendor/ink/build/components/Newline.js +8 -0
  277. package/vendor/ink/build/components/Newline.js.map +1 -0
  278. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  279. package/vendor/ink/build/components/Spacer.js +11 -0
  280. package/vendor/ink/build/components/Spacer.js.map +1 -0
  281. package/vendor/ink/build/components/Static.d.ts +24 -0
  282. package/vendor/ink/build/components/Static.js +28 -0
  283. package/vendor/ink/build/components/Static.js.map +1 -0
  284. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  285. package/vendor/ink/build/components/StderrContext.js +13 -0
  286. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  287. package/vendor/ink/build/components/StdinContext.d.ts +28 -0
  288. package/vendor/ink/build/components/StdinContext.js +20 -0
  289. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  290. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  291. package/vendor/ink/build/components/StdoutContext.js +13 -0
  292. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  293. package/vendor/ink/build/components/Text.d.ts +55 -0
  294. package/vendor/ink/build/components/Text.js +50 -0
  295. package/vendor/ink/build/components/Text.js.map +1 -0
  296. package/vendor/ink/build/components/Transform.d.ts +16 -0
  297. package/vendor/ink/build/components/Transform.js +15 -0
  298. package/vendor/ink/build/components/Transform.js.map +1 -0
  299. package/vendor/ink/build/cursor-helpers.d.ts +39 -0
  300. package/vendor/ink/build/cursor-helpers.js +62 -0
  301. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  302. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  303. package/vendor/ink/build/devtools-window-polyfill.js +68 -0
  304. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  305. package/vendor/ink/build/devtools.d.ts +1 -0
  306. package/vendor/ink/build/devtools.js +36 -0
  307. package/vendor/ink/build/devtools.js.map +1 -0
  308. package/vendor/ink/build/dom.d.ts +62 -0
  309. package/vendor/ink/build/dom.js +143 -0
  310. package/vendor/ink/build/dom.js.map +1 -0
  311. package/vendor/ink/build/get-max-width.d.ts +3 -0
  312. package/vendor/ink/build/get-max-width.js +10 -0
  313. package/vendor/ink/build/get-max-width.js.map +1 -0
  314. package/vendor/ink/build/hooks/use-animation.d.ts +49 -0
  315. package/vendor/ink/build/hooks/use-animation.js +87 -0
  316. package/vendor/ink/build/hooks/use-animation.js.map +1 -0
  317. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  318. package/vendor/ink/build/hooks/use-app.js +8 -0
  319. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  320. package/vendor/ink/build/hooks/use-box-metrics.d.ts +59 -0
  321. package/vendor/ink/build/hooks/use-box-metrics.js +81 -0
  322. package/vendor/ink/build/hooks/use-box-metrics.js.map +1 -0
  323. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  324. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  325. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  326. package/vendor/ink/build/hooks/use-focus-manager.d.ts +43 -0
  327. package/vendor/ink/build/hooks/use-focus-manager.js +18 -0
  328. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  329. package/vendor/ink/build/hooks/use-focus.d.ts +30 -0
  330. package/vendor/ink/build/hooks/use-focus.js +43 -0
  331. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  332. package/vendor/ink/build/hooks/use-input.d.ts +132 -0
  333. package/vendor/ink/build/hooks/use-input.js +126 -0
  334. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  335. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +6 -0
  336. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +12 -0
  337. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  338. package/vendor/ink/build/hooks/use-paste.d.ts +35 -0
  339. package/vendor/ink/build/hooks/use-paste.js +62 -0
  340. package/vendor/ink/build/hooks/use-paste.js.map +1 -0
  341. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  342. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  343. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  344. package/vendor/ink/build/hooks/use-stdin.d.ts +7 -0
  345. package/vendor/ink/build/hooks/use-stdin.js +9 -0
  346. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  347. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  348. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  349. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  350. package/vendor/ink/build/hooks/use-window-size.d.ts +18 -0
  351. package/vendor/ink/build/hooks/use-window-size.js +22 -0
  352. package/vendor/ink/build/hooks/use-window-size.js.map +1 -0
  353. package/vendor/ink/build/index.d.ts +42 -0
  354. package/vendor/ink/build/index.js +24 -0
  355. package/vendor/ink/build/index.js.map +1 -0
  356. package/vendor/ink/build/ink.d.ts +146 -0
  357. package/vendor/ink/build/ink.js +1022 -0
  358. package/vendor/ink/build/ink.js.map +1 -0
  359. package/vendor/ink/build/input-parser.d.ts +10 -0
  360. package/vendor/ink/build/input-parser.js +194 -0
  361. package/vendor/ink/build/input-parser.js.map +1 -0
  362. package/vendor/ink/build/instances.d.ts +3 -0
  363. package/vendor/ink/build/instances.js +8 -0
  364. package/vendor/ink/build/instances.js.map +1 -0
  365. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  366. package/vendor/ink/build/kitty-keyboard.js +32 -0
  367. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  368. package/vendor/ink/build/log-update.d.ts +20 -0
  369. package/vendor/ink/build/log-update.js +261 -0
  370. package/vendor/ink/build/log-update.js.map +1 -0
  371. package/vendor/ink/build/measure-element.d.ts +20 -0
  372. package/vendor/ink/build/measure-element.js +13 -0
  373. package/vendor/ink/build/measure-element.js.map +1 -0
  374. package/vendor/ink/build/measure-text.d.ts +6 -0
  375. package/vendor/ink/build/measure-text.js +21 -0
  376. package/vendor/ink/build/measure-text.js.map +1 -0
  377. package/vendor/ink/build/output.d.ts +35 -0
  378. package/vendor/ink/build/output.js +328 -0
  379. package/vendor/ink/build/output.js.map +1 -0
  380. package/vendor/ink/build/parse-keypress.d.ts +20 -0
  381. package/vendor/ink/build/parse-keypress.js +495 -0
  382. package/vendor/ink/build/parse-keypress.js.map +1 -0
  383. package/vendor/ink/build/reconciler.d.ts +4 -0
  384. package/vendor/ink/build/reconciler.js +306 -0
  385. package/vendor/ink/build/reconciler.js.map +1 -0
  386. package/vendor/ink/build/render-background.d.ts +4 -0
  387. package/vendor/ink/build/render-background.js +25 -0
  388. package/vendor/ink/build/render-background.js.map +1 -0
  389. package/vendor/ink/build/render-border.d.ts +4 -0
  390. package/vendor/ink/build/render-border.js +84 -0
  391. package/vendor/ink/build/render-border.js.map +1 -0
  392. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  393. package/vendor/ink/build/render-node-to-output.js +162 -0
  394. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  395. package/vendor/ink/build/render-to-string.d.ts +38 -0
  396. package/vendor/ink/build/render-to-string.js +116 -0
  397. package/vendor/ink/build/render-to-string.js.map +1 -0
  398. package/vendor/ink/build/render.d.ts +176 -0
  399. package/vendor/ink/build/render.js +71 -0
  400. package/vendor/ink/build/render.js.map +1 -0
  401. package/vendor/ink/build/renderer.d.ts +8 -0
  402. package/vendor/ink/build/renderer.js +64 -0
  403. package/vendor/ink/build/renderer.js.map +1 -0
  404. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  405. package/vendor/ink/build/sanitize-ansi.js +27 -0
  406. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  407. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  408. package/vendor/ink/build/squash-text-nodes.js +36 -0
  409. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  410. package/vendor/ink/build/styles.d.ts +302 -0
  411. package/vendor/ink/build/styles.js +303 -0
  412. package/vendor/ink/build/styles.js.map +1 -0
  413. package/vendor/ink/build/utils.d.ts +9 -0
  414. package/vendor/ink/build/utils.js +19 -0
  415. package/vendor/ink/build/utils.js.map +1 -0
  416. package/vendor/ink/build/wrap-text.d.ts +3 -0
  417. package/vendor/ink/build/wrap-text.js +38 -0
  418. package/vendor/ink/build/wrap-text.js.map +1 -0
  419. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  420. package/vendor/ink/build/write-synchronized.js +9 -0
  421. package/vendor/ink/build/write-synchronized.js.map +1 -0
  422. package/vendor/ink/license +10 -0
  423. package/vendor/ink/package.json +137 -0
  424. package/.claude-plugin/marketplace.json +0 -34
  425. package/.claude-plugin/plugin.json +0 -20
  426. package/.gitattributes +0 -34
  427. package/.mcp.json +0 -14
  428. package/ARCHITECTURE.md +0 -77
  429. package/CHANGELOG.md +0 -30
  430. package/CONTRIBUTING.md +0 -45
  431. package/DATA-FLOW.md +0 -79
  432. package/LICENSE +0 -21
  433. package/SECURITY.md +0 -138
  434. package/UNINSTALL.md +0 -112
  435. package/agents/maintenance.md +0 -5
  436. package/agents/memory-classification.md +0 -30
  437. package/agents/scheduler-task.md +0 -18
  438. package/agents/webhook-handler.md +0 -27
  439. package/agents/worker.md +0 -24
  440. package/bin/bridge +0 -133
  441. package/bin/statusline-launcher.mjs +0 -82
  442. package/bin/statusline-lib.mjs +0 -558
  443. package/bin/statusline.mjs +0 -615
  444. package/bun.lock +0 -927
  445. package/commands/config.md +0 -16
  446. package/commands/doctor.md +0 -13
  447. package/commands/setup.md +0 -17
  448. package/defaults/hidden-roles.json +0 -68
  449. package/defaults/memory-chunk-prompt.md +0 -63
  450. package/defaults/mixdog-config.template.json +0 -27
  451. package/defaults/user-workflow.json +0 -8
  452. package/defaults/user-workflow.md +0 -17
  453. package/hooks/hooks.json +0 -73
  454. package/hooks/lib/active-instance.cjs +0 -77
  455. package/hooks/lib/permission-evaluator.cjs +0 -411
  456. package/hooks/lib/permission-route.cjs +0 -63
  457. package/hooks/lib/settings-loader.cjs +0 -117
  458. package/hooks/post-tool-use.cjs +0 -84
  459. package/hooks/pre-mcp-sandbox.cjs +0 -158
  460. package/hooks/pre-tool-subagent.cjs +0 -258
  461. package/hooks/session-start.cjs +0 -1479
  462. package/hooks/shim-launcher.cjs +0 -65
  463. package/hooks/turn-timer.cjs +0 -82
  464. package/lib/claude-md-writer.cjs +0 -386
  465. package/lib/keychain-cjs.cjs +0 -290
  466. package/lib/plugin-paths.cjs +0 -69
  467. package/lib/rules-builder.cjs +0 -241
  468. package/native/README.md +0 -117
  469. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  470. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  471. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  472. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  473. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  474. package/prompts/code-review.txt +0 -16
  475. package/prompts/security-audit.txt +0 -17
  476. package/rules/bridge/00-common.md +0 -39
  477. package/rules/bridge/20-skip-protocol.md +0 -18
  478. package/rules/bridge/30-explorer.md +0 -33
  479. package/rules/bridge/40-cycle1-agent.md +0 -52
  480. package/rules/bridge/41-cycle2-agent.md +0 -62
  481. package/rules/lead/00-tool-lead.md +0 -61
  482. package/rules/lead/01-general.md +0 -23
  483. package/rules/lead/02-channels.md +0 -49
  484. package/rules/lead/03-team.md +0 -27
  485. package/rules/lead/04-workflow.md +0 -20
  486. package/rules/shared/00-language.md +0 -14
  487. package/rules/shared/01-tool.md +0 -138
  488. package/scripts/bootstrap.mjs +0 -130
  489. package/scripts/bridge-unify-smoke.mjs +0 -308
  490. package/scripts/build-runtime-linux.sh +0 -348
  491. package/scripts/build-runtime-macos.sh +0 -217
  492. package/scripts/build-runtime-windows.ps1 +0 -242
  493. package/scripts/builtin-utils-smoke.mjs +0 -398
  494. package/scripts/bump.mjs +0 -80
  495. package/scripts/check-json.mjs +0 -45
  496. package/scripts/check-syntax-changed.mjs +0 -102
  497. package/scripts/check-syntax.mjs +0 -58
  498. package/scripts/code-graph-batch.test.mjs +0 -33
  499. package/scripts/config-preserve-smoke.mjs +0 -180
  500. package/scripts/doctor.mjs +0 -489
  501. package/scripts/edit-normalize-fuzz.mjs +0 -130
  502. package/scripts/edit-normalize-smoke.mjs +0 -401
  503. package/scripts/edit-operation-smoke.mjs +0 -369
  504. package/scripts/edit2-smoke.mjs +0 -63
  505. package/scripts/ensure-deps.mjs +0 -259
  506. package/scripts/fuzzy-e2e.mjs +0 -28
  507. package/scripts/fuzzy-smoke.mjs +0 -26
  508. package/scripts/generate-runtime-manifest.mjs +0 -166
  509. package/scripts/guard-smoke.mjs +0 -66
  510. package/scripts/hidden-role-schema-smoke.mjs +0 -162
  511. package/scripts/hook-routing-smoke.mjs +0 -29
  512. package/scripts/inject-input.ps1 +0 -204
  513. package/scripts/io-complex-smoke.mjs +0 -667
  514. package/scripts/io-explore-bench.mjs +0 -424
  515. package/scripts/io-guardrails-smoke.mjs +0 -205
  516. package/scripts/io-mini-bench-baseline.json +0 -11
  517. package/scripts/io-mini-bench.mjs +0 -216
  518. package/scripts/io-route-harness.mjs +0 -933
  519. package/scripts/io-telemetry-report.mjs +0 -691
  520. package/scripts/mutation-bench.mjs +0 -564
  521. package/scripts/mutation-io-smoke.mjs +0 -1097
  522. package/scripts/native-patch-bridge-smoke.mjs +0 -288
  523. package/scripts/native-patch-smoke.mjs +0 -304
  524. package/scripts/openai-oauth-catalog-smoke.mjs +0 -53
  525. package/scripts/patch-interior-context-smoke.mjs +0 -49
  526. package/scripts/patch-newline-utf8-smoke.mjs +0 -157
  527. package/scripts/perf-hook-smoke.mjs +0 -71
  528. package/scripts/permission-eval-smoke.mjs +0 -443
  529. package/scripts/prep-patch.mjs +0 -53
  530. package/scripts/prep-shim.mjs +0 -96
  531. package/scripts/provider-cache-smoke.mjs +0 -687
  532. package/scripts/report-runtime-health.mjs +0 -132
  533. package/scripts/resolve-bun.mjs +0 -60
  534. package/scripts/run-mcp.mjs +0 -1448
  535. package/scripts/salvage-v4a-shatter.test.mjs +0 -58
  536. package/scripts/scoped-cache-io-smoke.mjs +0 -103
  537. package/scripts/shell-policy-round3-smoke.mjs +0 -46
  538. package/scripts/smoke-runtime-negative.ps1 +0 -100
  539. package/scripts/smoke-runtime-negative.sh +0 -95
  540. package/scripts/stall-policy-smoke.mjs +0 -50
  541. package/scripts/start-memory-worker.mjs +0 -23
  542. package/scripts/statusline-launcher-smoke.mjs +0 -82
  543. package/scripts/stress-atomic-write.mjs +0 -1028
  544. package/scripts/test-fault-inject.mjs +0 -164
  545. package/scripts/test-large-file.mjs +0 -174
  546. package/scripts/tool-edge-smoke.mjs +0 -209
  547. package/scripts/uninstall.mjs +0 -201
  548. package/scripts/webhook-selfheal-smoke.mjs +0 -27
  549. package/scripts/write-overwrite-guard-smoke.mjs +0 -56
  550. package/server-main.mjs +0 -3109
  551. package/server.mjs +0 -468
  552. package/setup/config-merge.mjs +0 -246
  553. package/setup/install.mjs +0 -574
  554. package/setup/launch-core.mjs +0 -617
  555. package/setup/launch.mjs +0 -101
  556. package/setup/locate-claude.mjs +0 -56
  557. package/setup/mixdog-cli.mjs +0 -122
  558. package/setup/setup-server.mjs +0 -3305
  559. package/setup/setup.html +0 -3740
  560. package/setup/tui.mjs +0 -325
  561. package/skills/retro-skill-proposer/SKILL.md +0 -92
  562. package/skills/schedule-add/SKILL.md +0 -77
  563. package/skills/setup/SKILL.md +0 -356
  564. package/skills/webhook-add/SKILL.md +0 -81
  565. package/src/agent/bridge-stall-watchdog.mjs +0 -337
  566. package/src/agent/index.mjs +0 -2138
  567. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +0 -1010
  568. package/src/agent/orchestrator/bridge-retry.mjs +0 -220
  569. package/src/agent/orchestrator/bridge-trace.mjs +0 -583
  570. package/src/agent/orchestrator/cache-mtime.mjs +0 -58
  571. package/src/agent/orchestrator/config.mjs +0 -405
  572. package/src/agent/orchestrator/context/collect.mjs +0 -651
  573. package/src/agent/orchestrator/dispatch-persist.mjs +0 -549
  574. package/src/agent/orchestrator/drain-registry.mjs +0 -50
  575. package/src/agent/orchestrator/explore-validator.mjs +0 -8
  576. package/src/agent/orchestrator/internal-roles.mjs +0 -118
  577. package/src/agent/orchestrator/internal-tools.mjs +0 -88
  578. package/src/agent/orchestrator/jobs.mjs +0 -116
  579. package/src/agent/orchestrator/mcp/client.mjs +0 -364
  580. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +0 -1881
  581. package/src/agent/orchestrator/providers/anthropic.mjs +0 -594
  582. package/src/agent/orchestrator/providers/gemini.mjs +0 -1530
  583. package/src/agent/orchestrator/providers/grok-oauth.mjs +0 -779
  584. package/src/agent/orchestrator/providers/model-catalog.mjs +0 -374
  585. package/src/agent/orchestrator/providers/openai-compat-stream.mjs +0 -366
  586. package/src/agent/orchestrator/providers/openai-compat.mjs +0 -1511
  587. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +0 -1891
  588. package/src/agent/orchestrator/providers/openai-oauth.mjs +0 -1456
  589. package/src/agent/orchestrator/providers/openai-ws.mjs +0 -127
  590. package/src/agent/orchestrator/providers/registry.mjs +0 -192
  591. package/src/agent/orchestrator/providers/retry-classifier.mjs +0 -325
  592. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +0 -142
  593. package/src/agent/orchestrator/session/cache/read-cache.mjs +0 -319
  594. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +0 -361
  595. package/src/agent/orchestrator/session/loop.mjs +0 -1478
  596. package/src/agent/orchestrator/session/manager.mjs +0 -1991
  597. package/src/agent/orchestrator/session/result-classification.mjs +0 -65
  598. package/src/agent/orchestrator/session/store.mjs +0 -632
  599. package/src/agent/orchestrator/session/stream-watchdog.mjs +0 -130
  600. package/src/agent/orchestrator/session/tool-result-offload.mjs +0 -166
  601. package/src/agent/orchestrator/session/trim.mjs +0 -491
  602. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +0 -115
  603. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +0 -331
  604. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +0 -150
  605. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +0 -228
  606. package/src/agent/orchestrator/smart-bridge/index.mjs +0 -215
  607. package/src/agent/orchestrator/smart-bridge/profiles.mjs +0 -37
  608. package/src/agent/orchestrator/smart-bridge/registry.mjs +0 -348
  609. package/src/agent/orchestrator/stall-policy.mjs +0 -201
  610. package/src/agent/orchestrator/tool-loop-guard.mjs +0 -75
  611. package/src/agent/orchestrator/tools/bash-session.mjs +0 -722
  612. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +0 -455
  613. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -480
  614. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +0 -256
  615. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +0 -58
  616. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +0 -240
  617. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +0 -113
  618. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +0 -74
  619. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +0 -242
  620. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +0 -211
  621. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +0 -1364
  622. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +0 -126
  623. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +0 -141
  624. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +0 -194
  625. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +0 -60
  626. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +0 -168
  627. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +0 -173
  628. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +0 -48
  629. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +0 -99
  630. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +0 -193
  631. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +0 -597
  632. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
  633. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +0 -300
  634. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +0 -152
  635. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +0 -118
  636. package/src/agent/orchestrator/tools/builtin/read-open.mjs +0 -190
  637. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +0 -728
  638. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +0 -173
  639. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +0 -602
  640. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +0 -196
  641. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +0 -422
  642. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +0 -158
  643. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +0 -869
  644. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +0 -962
  645. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +0 -223
  646. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +0 -206
  647. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +0 -401
  648. package/src/agent/orchestrator/tools/builtin.mjs +0 -503
  649. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +0 -24
  650. package/src/agent/orchestrator/tools/code-graph.mjs +0 -4095
  651. package/src/agent/orchestrator/tools/cwd-tool.mjs +0 -298
  652. package/src/agent/orchestrator/tools/destructive-warning.mjs +0 -323
  653. package/src/agent/orchestrator/tools/edit-normalize.mjs +0 -603
  654. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +0 -154
  655. package/src/agent/orchestrator/tools/graph-manifest.json +0 -26
  656. package/src/agent/orchestrator/tools/host-input.mjs +0 -204
  657. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +0 -143
  658. package/src/agent/orchestrator/tools/patch-manifest.json +0 -26
  659. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +0 -20
  660. package/src/agent/orchestrator/tools/patch.mjs +0 -2754
  661. package/src/agent/orchestrator/tools/progress-message.mjs +0 -118
  662. package/src/agent/orchestrator/tools/shell-command.mjs +0 -865
  663. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +0 -7
  664. package/src/agent/orchestrator/tools/shell-snapshot.mjs +0 -313
  665. package/src/agent/orchestrator/workflow-store.mjs +0 -93
  666. package/src/agent/tool-defs.mjs +0 -103
  667. package/src/channels/backends/discord.mjs +0 -784
  668. package/src/channels/data/voice-runtime-manifest.json +0 -138
  669. package/src/channels/index.mjs +0 -3268
  670. package/src/channels/lib/config.mjs +0 -292
  671. package/src/channels/lib/drop-trace.mjs +0 -71
  672. package/src/channels/lib/event-pipeline.mjs +0 -81
  673. package/src/channels/lib/holidays.mjs +0 -138
  674. package/src/channels/lib/hook-pipe-server.mjs +0 -822
  675. package/src/channels/lib/output-forwarder.mjs +0 -765
  676. package/src/channels/lib/runtime-paths.mjs +0 -517
  677. package/src/channels/lib/scheduler.mjs +0 -723
  678. package/src/channels/lib/session-discovery.mjs +0 -103
  679. package/src/channels/lib/state-file.mjs +0 -68
  680. package/src/channels/lib/status-snapshot.mjs +0 -219
  681. package/src/channels/lib/tool-format.mjs +0 -140
  682. package/src/channels/lib/transcript-discovery.mjs +0 -195
  683. package/src/channels/lib/voice-runtime-fetcher.mjs +0 -734
  684. package/src/channels/lib/webhook.mjs +0 -1318
  685. package/src/channels/tool-defs.mjs +0 -170
  686. package/src/daemon/host.mjs +0 -118
  687. package/src/daemon/mcp-transport.mjs +0 -47
  688. package/src/daemon/session.mjs +0 -100
  689. package/src/daemon/thin-client.mjs +0 -71
  690. package/src/daemon/transport.mjs +0 -163
  691. package/src/memory/data/runtime-manifest.json +0 -40
  692. package/src/memory/index.mjs +0 -3332
  693. package/src/memory/lib/core-memory-store.mjs +0 -330
  694. package/src/memory/lib/embedding-provider.mjs +0 -269
  695. package/src/memory/lib/embedding-worker.mjs +0 -323
  696. package/src/memory/lib/memory-cycle1.mjs +0 -645
  697. package/src/memory/lib/memory-cycle2.mjs +0 -1284
  698. package/src/memory/lib/memory-cycle3.mjs +0 -540
  699. package/src/memory/lib/memory-embed.mjs +0 -299
  700. package/src/memory/lib/memory-ops-policy.mjs +0 -190
  701. package/src/memory/lib/memory-recall-store.mjs +0 -638
  702. package/src/memory/lib/memory.mjs +0 -412
  703. package/src/memory/lib/pg/adapter.mjs +0 -308
  704. package/src/memory/lib/pg/process.mjs +0 -360
  705. package/src/memory/lib/pg/supervisor.mjs +0 -396
  706. package/src/memory/lib/runtime-fetcher.mjs +0 -458
  707. package/src/memory/lib/trace-store.mjs +0 -728
  708. package/src/memory/tool-defs.mjs +0 -79
  709. package/src/search/index.mjs +0 -1173
  710. package/src/search/lib/backends/anthropic-oauth.mjs +0 -98
  711. package/src/search/lib/backends/exa.mjs +0 -50
  712. package/src/search/lib/backends/firecrawl.mjs +0 -61
  713. package/src/search/lib/backends/gemini-api.mjs +0 -83
  714. package/src/search/lib/backends/grok-oauth.mjs +0 -86
  715. package/src/search/lib/backends/index.mjs +0 -150
  716. package/src/search/lib/backends/openai-api.mjs +0 -144
  717. package/src/search/lib/backends/openai-oauth.mjs +0 -102
  718. package/src/search/lib/backends/openai-web-search.mjs +0 -76
  719. package/src/search/lib/backends/tavily.mjs +0 -55
  720. package/src/search/lib/backends/xai-api.mjs +0 -113
  721. package/src/search/lib/config.mjs +0 -192
  722. package/src/search/lib/provider-usage.mjs +0 -67
  723. package/src/search/lib/providers.mjs +0 -47
  724. package/src/search/lib/search-intent.mjs +0 -109
  725. package/src/search/lib/setup-handler.mjs +0 -261
  726. package/src/search/lib/web-tools.mjs +0 -1219
  727. package/src/search/tool-defs.mjs +0 -83
  728. package/src/setup/defender-exclusion.mjs +0 -183
  729. package/src/shared/atomic-file.mjs +0 -436
  730. package/src/shared/config.mjs +0 -372
  731. package/src/shared/daemon-recycle.mjs +0 -108
  732. package/src/shared/disable-claude-builtins.mjs +0 -91
  733. package/src/shared/err-text.mjs +0 -12
  734. package/src/shared/llm/cost.mjs +0 -66
  735. package/src/shared/llm/http-agent.mjs +0 -123
  736. package/src/shared/open-url.mjs +0 -62
  737. package/src/shared/plugin-paths.mjs +0 -58
  738. package/src/shared/schedules-store.mjs +0 -70
  739. package/src/shared/seed.mjs +0 -136
  740. package/src/shared/user-cwd.mjs +0 -225
  741. package/src/shared/user-data-guard.mjs +0 -244
  742. package/src/status/aggregator.mjs +0 -584
  743. package/src/status/server.mjs +0 -413
  744. package/tools.json +0 -1653
  745. /package/{defaults → src/defaults}/cycle3-review-prompt.md +0 -0
  746. /package/{defaults → src/defaults}/memory-promote-prompt.md +0 -0
  747. /package/{hooks → src/hooks}/lib/permission-rules.cjs +0 -0
  748. /package/{lib → src/lib}/config-cjs.cjs +0 -0
  749. /package/{lib → src/lib}/hook-pipe-path.cjs +0 -0
  750. /package/{lib → src/lib}/mixdog-debug.cjs +0 -0
  751. /package/{lib → src/lib}/text-utils.cjs +0 -0
  752. /package/{rules → src/rules}/bridge/42-cycle3-agent.md +0 -0
  753. /package/src/{agent → runtime/agent}/orchestrator/activity-bus.mjs +0 -0
  754. /package/src/{agent → runtime/agent}/orchestrator/providers/anthropic-betas.mjs +0 -0
  755. /package/src/{agent → runtime/agent}/orchestrator/session/abort-lookup.mjs +0 -0
  756. /package/src/{agent → runtime/agent}/orchestrator/session/cache/post-edit-marks.mjs +0 -0
  757. /package/src/{agent → runtime/agent}/orchestrator/session/cache/scoped-cache-outcome.mjs +0 -0
  758. /package/src/{agent → runtime/agent}/orchestrator/session/cache/util.mjs +0 -0
  759. /package/src/{agent → runtime/agent}/orchestrator/session/read-dedup.mjs +0 -0
  760. /package/src/{agent → runtime/agent}/orchestrator/session/save-session-worker.mjs +0 -0
  761. /package/src/{agent → runtime/agent}/orchestrator/smart-bridge/session-builder.mjs +0 -0
  762. /package/src/{agent → runtime/agent}/orchestrator/tools/bash-policy-scan.mjs +0 -0
  763. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/advisory-lock.mjs +0 -0
  764. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/atomic-write.mjs +0 -0
  765. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/binary-file.mjs +0 -0
  766. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cache-layers.mjs +0 -0
  767. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cwd-utils.mjs +0 -0
  768. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/device-paths.mjs +0 -0
  769. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -0
  770. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diff-utils.mjs +0 -0
  771. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/fs-reachability.mjs +0 -0
  772. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/grep-formatting.mjs +0 -0
  773. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/hash-utils.mjs +0 -0
  774. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/list-formatting.mjs +0 -0
  775. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/open-config-tool.mjs +0 -0
  776. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-locks.mjs +0 -0
  777. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-utils.mjs +0 -0
  778. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-args.mjs +0 -0
  779. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-batch.mjs +0 -0
  780. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-constants.mjs +0 -0
  781. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image-resize.mjs +0 -0
  782. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image.mjs +0 -0
  783. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-lines.mjs +0 -0
  784. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-mode-tool.mjs +0 -0
  785. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-range-index.mjs +0 -0
  786. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-ranges.mjs +0 -0
  787. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-special-files.mjs +0 -0
  788. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-tool.mjs +0 -0
  789. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-windows.mjs +0 -0
  790. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-analysis.mjs +0 -0
  791. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-output.mjs +0 -0
  792. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-helpers.mjs +0 -0
  793. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-validation.mjs +0 -0
  794. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/text-stats.mjs +0 -0
  795. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/windows-roots.mjs +0 -0
  796. /package/src/{agent → runtime/agent}/orchestrator/tools/code-graph-prewarm-worker.mjs +0 -0
  797. /package/src/{agent → runtime/agent}/orchestrator/tools/env-scrub.mjs +0 -0
  798. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-content-cache.mjs +0 -0
  799. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-planner.mjs +0 -0
  800. /package/src/{agent → runtime/agent}/orchestrator/tools/next-call-utils.mjs +0 -0
  801. /package/src/{agent → runtime/agent}/orchestrator/tools/result-compression.mjs +0 -0
  802. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-exec-policy.mjs +0 -0
  803. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy-danger-target.mjs +0 -0
  804. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy.mjs +0 -0
  805. /package/src/{channels → runtime/channels}/lib/cli-worker-host.mjs +0 -0
  806. /package/src/{channels → runtime/channels}/lib/config-lock.mjs +0 -0
  807. /package/src/{channels → runtime/channels}/lib/event-queue.mjs +0 -0
  808. /package/src/{channels → runtime/channels}/lib/executor.mjs +0 -0
  809. /package/src/{channels → runtime/channels}/lib/format.mjs +0 -0
  810. /package/src/{channels → runtime/channels}/lib/interaction-workflows.mjs +0 -0
  811. /package/src/{channels → runtime/channels}/lib/memory-client.mjs +0 -0
  812. /package/src/{channels → runtime/channels}/lib/session-control.mjs +0 -0
  813. /package/src/{channels → runtime/channels}/lib/settings.mjs +0 -0
  814. /package/src/{channels → runtime/channels}/lib/whisper-server.mjs +0 -0
  815. /package/src/{memory → runtime/memory}/lib/agent-ipc.mjs +0 -0
  816. /package/src/{memory → runtime/memory}/lib/bridge-trace-queries.mjs +0 -0
  817. /package/src/{memory → runtime/memory}/lib/llm-worker-host.mjs +0 -0
  818. /package/src/{memory → runtime/memory}/lib/memory-cycle.mjs +0 -0
  819. /package/src/{memory → runtime/memory}/lib/memory-extraction.mjs +0 -0
  820. /package/src/{memory → runtime/memory}/lib/memory-maintenance-store.mjs +0 -0
  821. /package/src/{memory → runtime/memory}/lib/memory-recall-id-patch.mjs +0 -0
  822. /package/src/{memory → runtime/memory}/lib/memory-recall-read-query.mjs +0 -0
  823. /package/src/{memory → runtime/memory}/lib/memory-recall-scope-filter.mjs +0 -0
  824. /package/src/{memory → runtime/memory}/lib/memory-retrievers.mjs +0 -0
  825. /package/src/{memory → runtime/memory}/lib/memory-score.mjs +0 -0
  826. /package/src/{memory → runtime/memory}/lib/memory-text-utils.mjs +0 -0
  827. /package/src/{memory → runtime/memory}/lib/model-profile.mjs +0 -0
  828. /package/src/{memory → runtime/memory}/lib/project-id-resolver.mjs +0 -0
  829. /package/src/{search → runtime/search}/lib/cache.mjs +0 -0
  830. /package/src/{search → runtime/search}/lib/formatter.mjs +0 -0
  831. /package/src/{search → runtime/search}/lib/state.mjs +0 -0
  832. /package/src/{shared → runtime/shared}/abort-controller.mjs +0 -0
  833. /package/src/{shared → runtime/shared}/llm/index.mjs +0 -0
  834. /package/src/{shared → runtime/shared}/llm/pid-cleanup.mjs +0 -0
  835. /package/src/{shared → runtime/shared}/llm/usage-log.mjs +0 -0
  836. /package/src/{shared → runtime/shared}/wsl.mjs +0 -0
@@ -0,0 +1,925 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js'
4
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
5
+ import { z } from 'zod'
6
+ import fs from 'fs'
7
+ import path from 'path'
8
+ import {
9
+ ensureDataDir,
10
+ getRequestTimeoutMs,
11
+ loadConfig,
12
+ } from './lib/config.mjs'
13
+ import { normalizeErrorMessage } from '../agent/orchestrator/tools/builtin/path-diagnostics.mjs'
14
+ import { presentErrorText } from '../shared/err-text.mjs'
15
+
16
+ function readPluginVersion() {
17
+ try {
18
+ return JSON.parse(fs.readFileSync(new URL('../../../package.json', import.meta.url), 'utf8')).version || '0.0.1'
19
+ } catch { return '0.0.1' }
20
+ }
21
+ const PLUGIN_VERSION = readPluginVersion()
22
+ import {
23
+ buildCacheKey,
24
+ buildCacheMeta,
25
+ flushCacheState,
26
+ getCachedEntry,
27
+ loadCacheState,
28
+ setCachedEntry,
29
+ } from './lib/cache.mjs'
30
+ import {
31
+ flushUsageState,
32
+ loadUsageState,
33
+ noteProviderFailure,
34
+ classifyProviderError,
35
+ noteProviderSuccess,
36
+ saveUsageState,
37
+ updateProviderState,
38
+ } from './lib/state.mjs'
39
+ import { assertPublicUrl, crawlSite, getScrapeCapabilities, pinnedFetch, scrapeUrls } from './lib/web-tools.mjs'
40
+ import { formatResponse } from './lib/formatter.mjs'
41
+ import {
42
+ cancelBackgroundTask,
43
+ getBackgroundTask,
44
+ renderBackgroundTask,
45
+ renderBackgroundTaskList,
46
+ resolveExecutionMode,
47
+ startBackgroundTask,
48
+ taskIdFromArgs,
49
+ } from '../shared/background-tasks.mjs'
50
+
51
+
52
+ ensureDataDir()
53
+
54
+ const searchArgsSchema = z.object({
55
+ keywords: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).describe('Search query string or array of queries.'),
56
+ mode: z.enum(['sync', 'async']).optional(),
57
+ action: z.enum(['run', 'list', 'status', 'read', 'cancel']).optional(),
58
+ task_id: z.string().optional(),
59
+ firstResponseTimeoutMs: z.number().int().min(0).optional(),
60
+ idleTimeoutMs: z.number().int().min(0).optional(),
61
+ site: z.string().optional().describe('Restrict results to a specific domain.'),
62
+ type: z.enum(['web', 'news', 'images']).optional().describe('Search type. Default: web.'),
63
+ maxResults: z.number().int().min(1).max(20).optional().describe('Maximum number of results to return (1-20).'),
64
+ locale: z.union([
65
+ z.string(),
66
+ z.object({
67
+ country: z.string().optional(),
68
+ language: z.string().optional(),
69
+ region: z.string().optional(),
70
+ city: z.string().optional(),
71
+ timezone: z.string().optional(),
72
+ }),
73
+ ]).optional().describe('Explicit search locale. String such as "ko-KR" or object with country/language/city/region/timezone.'),
74
+ contextSize: z.enum(['low', 'medium', 'high']).optional().describe('Search context size hint. Default: low.'),
75
+ })
76
+
77
+ const searchUrlArgsSchema = z.object({
78
+ url: z.union([z.string().url(), z.array(z.string().url()).min(1)]).describe('Single URL or array of URLs to fetch.'),
79
+ startIndex: z.number().int().min(0).optional().describe('Character offset to start the slice from (default 0). For chunked reading of large pages, pass the previous response\'s nextStartIndex.'),
80
+ maxLength: z.number().int().min(0).optional().describe('Max characters to return per call (default 50000). Pass 0 for unlimited.'),
81
+ cwd: z.string().optional(),
82
+ })
83
+
84
+ const SEARCH_EMPTY_STRING_FIELDS = ['keywords', 'site', 'type', 'locale', 'contextSize', 'mode', 'action', 'task_id', 'firstResponseTimeoutMs', 'idleTimeoutMs']
85
+
86
+ function normalizeSearchArgs(rawArgs) {
87
+ if (!rawArgs || typeof rawArgs !== 'object' || Array.isArray(rawArgs)) return rawArgs
88
+ const args = { ...rawArgs }
89
+ for (const key of SEARCH_EMPTY_STRING_FIELDS) {
90
+ const value = args[key]
91
+ if (typeof value === 'string') {
92
+ const trimmed = value.trim()
93
+ if (!trimmed) delete args[key]
94
+ else args[key] = trimmed
95
+ }
96
+ }
97
+ if (Array.isArray(args.keywords)) {
98
+ const keywords = args.keywords
99
+ .map(value => typeof value === 'string' ? value.trim() : value)
100
+ .filter(value => typeof value === 'string' ? value.length > 0 : Boolean(value))
101
+ if (keywords.length > 0) args.keywords = keywords
102
+ else delete args.keywords
103
+ }
104
+ return args
105
+ }
106
+
107
+ function normalizeSearchUrlArgs(rawArgs) {
108
+ if (!rawArgs || typeof rawArgs !== 'object' || Array.isArray(rawArgs)) return rawArgs
109
+ const args = { ...rawArgs }
110
+ if (typeof args.url === 'string') args.url = args.url.trim()
111
+ if (Array.isArray(args.url)) {
112
+ const urls = args.url
113
+ .map(value => typeof value === 'string' ? value.trim() : value)
114
+ .filter(value => typeof value === 'string' ? value.length > 0 : Boolean(value))
115
+ if (urls.length > 0) args.url = urls
116
+ else delete args.url
117
+ }
118
+ return args
119
+ }
120
+
121
+ function formattedText(tool, payload) {
122
+ const text = formatResponse(tool, tool === 'search' ? dropInvalidSearchResults(payload) : payload)
123
+ return {
124
+ content: [{ type: 'text', text }],
125
+ }
126
+ }
127
+
128
+ function toolText(response) {
129
+ if (typeof response === 'string') return response
130
+ const parts = Array.isArray(response?.content) ? response.content : []
131
+ const text = parts
132
+ .filter(part => part?.type === 'text')
133
+ .map(part => part.text)
134
+ .join('\n')
135
+ return text || JSON.stringify(response, null, 2)
136
+ }
137
+
138
+ function okText(text) {
139
+ return { content: [{ type: 'text', text }], isError: false }
140
+ }
141
+
142
+ function searchTaskControl(action, args = {}, options = {}) {
143
+ if (action === 'list') return okText(renderBackgroundTaskList({ surface: 'search', context: options }))
144
+ const taskId = taskIdFromArgs(args)
145
+ if (!taskId) return { ...okText('Error: task_id is required'), isError: true }
146
+ const task = getBackgroundTask(taskId, { surface: 'search', context: options })
147
+ if (!task) return { ...okText(`Error: search task not found: ${taskId}`), isError: true }
148
+ if (action === 'cancel') {
149
+ cancelBackgroundTask(taskId, 'cancelled by search control')
150
+ return okText(renderBackgroundTask(task, { includeResult: true }))
151
+ }
152
+ return okText(renderBackgroundTask(task, { includeResult: action === 'read' }))
153
+ }
154
+
155
+ function isInvalidSearchResult(result) {
156
+ const title = String(result?.title || '').trim()
157
+ return /\bpage not found\b|\b404\b.*\bnot found\b/i.test(title)
158
+ }
159
+
160
+ function dropInvalidSearchResults(payload) {
161
+ if (!payload || typeof payload !== 'object') return payload
162
+ const response = payload.response
163
+ if (!response || typeof response !== 'object' || !Array.isArray(response.results)) return payload
164
+ const results = response.results.filter(result => !isInvalidSearchResult(result))
165
+ if (results.length === response.results.length) return payload
166
+ return {
167
+ ...payload,
168
+ response: {
169
+ ...response,
170
+ results,
171
+ droppedInvalidResults: (response.droppedInvalidResults || 0) + (response.results.length - results.length),
172
+ },
173
+ }
174
+ }
175
+
176
+ function getSearchCacheTtlMs(type = 'web') {
177
+ switch (type) {
178
+ case 'news':
179
+ return 20 * 60 * 1000
180
+ case 'images':
181
+ return 60 * 60 * 1000
182
+ case 'web':
183
+ default:
184
+ return 30 * 60 * 1000
185
+ }
186
+ }
187
+
188
+ function getScrapeCacheTtlMs(isXRoute = false) {
189
+ return isXRoute ? 10 * 60 * 1000 : 60 * 60 * 1000
190
+ }
191
+
192
+ function normalizeCacheUrl(url) {
193
+ try {
194
+ return new URL(url).toString()
195
+ } catch {
196
+ return String(url)
197
+ }
198
+ }
199
+
200
+ const DOC_INDEX_MAX_BYTES = 2 * 1024 * 1024
201
+ const DOC_INDEX_MAX_FETCHES = 8
202
+ const DOC_INDEX_COMMON_PATHS = ['docs', 'api', 'reference', 'api/reference']
203
+ const DOC_INDEX_STOPWORDS = new Set([
204
+ 'about', 'after', 'again', 'also', 'and', 'are', 'can', 'com', 'doc', 'docs',
205
+ 'documentation', 'for', 'from', 'how', 'http', 'https', 'into', 'official',
206
+ 'page', 'pages', 'site', 'the', 'this', 'title', 'url', 'use', 'using', 'what',
207
+ 'when', 'where', 'which', 'with', 'www',
208
+ ])
209
+
210
+ function keywordsText(keywords) {
211
+ return Array.isArray(keywords) ? keywords.join(' ') : String(keywords || '')
212
+ }
213
+
214
+ function queryTokens(keywords) {
215
+ const tokens = keywordsText(keywords)
216
+ .toLowerCase()
217
+ .match(/[\p{L}\p{N}][\p{L}\p{N}._-]{1,}/gu) || []
218
+ return [...new Set(tokens
219
+ .filter(token => token.length >= 3 && !DOC_INDEX_STOPWORDS.has(token)))]
220
+ }
221
+
222
+ // Weighted scoring across title/path/url/snippet. Title hit is the strongest
223
+ // signal (8) because llms.txt entries are hand-curated; path-segment hits
224
+ // (5) and last-segment hits (3..10) catch /api/foo over /blog/foo. Url and
225
+ // snippet (2 / 1) act as tiebreakers when title misses. .md penalty -2 so
226
+ // raw markdown sources lose to rendered docs when both are listed.
227
+ function docLinkScore(link, tokens) {
228
+ if (!tokens.length) return 0
229
+ const title = String(link.title || '').toLowerCase()
230
+ const url = String(link.url || '').toLowerCase()
231
+ const snippet = String(link.snippet || '').toLowerCase()
232
+ let pathname = ''
233
+ try {
234
+ pathname = new URL(link.url).pathname.toLowerCase()
235
+ } catch {}
236
+ const segments = pathname.split('/').filter(Boolean)
237
+ let score = 0
238
+ for (const token of tokens) {
239
+ if (title.includes(token)) score += 8
240
+ if (segments.includes(token)) score += 5
241
+ if (segments.at(-1) === token) score += 3 + Math.max(0, 7 - segments.length)
242
+ if (url.includes(token)) score += 2
243
+ if (snippet.includes(token)) score += 1
244
+ }
245
+ if (/\.md$/i.test(pathname)) score -= 2
246
+ return score
247
+ }
248
+
249
+ function docIndexUrlCandidates(site, keywords) {
250
+ if (!site) return []
251
+ let parsed
252
+ try {
253
+ parsed = new URL(/^https?:\/\//i.test(site) ? site : `https://${site}`)
254
+ } catch {
255
+ return []
256
+ }
257
+ const candidates = []
258
+ const add = (url) => {
259
+ try {
260
+ const normalized = new URL(url).toString()
261
+ if (!candidates.includes(normalized)) candidates.push(normalized)
262
+ } catch {}
263
+ }
264
+ const pathParts = parsed.pathname.split('/').filter(Boolean)
265
+ for (let i = pathParts.length; i >= 0; i -= 1) {
266
+ const prefix = pathParts.slice(0, i).join('/')
267
+ add(`${parsed.origin}${prefix ? `/${prefix}` : ''}/llms.txt`)
268
+ }
269
+ // When the user asks an api/docs question on a bare-host site, also probe
270
+ // the common doc-prefix llms.txt locations the host might publish under.
271
+ const docsIntent = /\b(?:api|docs?|documentation|reference)\b/i.test(keywordsText(keywords))
272
+ if (docsIntent && pathParts.length === 0) {
273
+ for (const prefix of DOC_INDEX_COMMON_PATHS) {
274
+ add(`${parsed.origin}/${prefix}/llms.txt`)
275
+ }
276
+ }
277
+ return candidates
278
+ }
279
+
280
+
281
+ function docIndexAbortSignal(timeoutMs, parentSignal) {
282
+ const ms = Math.min(Math.max(Number(timeoutMs) || 10_000, 1000), 10_000)
283
+ if (typeof AbortSignal.any === 'function') {
284
+ const parts = [AbortSignal.timeout(ms)]
285
+ if (parentSignal) parts.push(parentSignal)
286
+ return AbortSignal.any(parts)
287
+ }
288
+ const controller = new AbortController()
289
+ let timer
290
+ let onParentAbort
291
+ const abortWith = reason => {
292
+ if (timer !== undefined) {
293
+ clearTimeout(timer)
294
+ timer = undefined
295
+ }
296
+ if (parentSignal && onParentAbort) {
297
+ parentSignal.removeEventListener('abort', onParentAbort)
298
+ onParentAbort = undefined
299
+ }
300
+ if (!controller.signal.aborted) controller.abort(reason)
301
+ }
302
+ timer = setTimeout(
303
+ () => abortWith(new DOMException('The operation was aborted due to timeout', 'TimeoutError')),
304
+ ms,
305
+ )
306
+ if (parentSignal) {
307
+ if (parentSignal.aborted) {
308
+ abortWith(parentSignal.reason)
309
+ return controller.signal
310
+ }
311
+ onParentAbort = () => abortWith(parentSignal.reason)
312
+ parentSignal.addEventListener('abort', onParentAbort, { once: true })
313
+ }
314
+ return controller.signal
315
+ }
316
+
317
+ async function fetchDocIndex(url, timeoutMs, parentSignal) {
318
+ // SSRF: reuse the guarded web_fetch path's public-URL/private-IP check so
319
+ // docs-index discovery cannot be steered into localhost / link-local /
320
+ // cloud-metadata addresses by a hostile site override. Follow redirects
321
+ // manually and re-validate each hop so a 30x Location can't steer us to
322
+ // a private/loopback address after the initial check.
323
+ const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308])
324
+ const MAX_REDIRECTS = 5
325
+ const signal = docIndexAbortSignal(timeoutMs, parentSignal)
326
+ let currentUrl = url
327
+ let response
328
+ for (let hops = 0; ; hops++) {
329
+ assertPublicUrl(currentUrl)
330
+ // pinnedFetch resolves+validates the host once and pins the connection
331
+ // to the validated IP, closing the validate-then-fetch DNS-rebinding /
332
+ // TOCTOU window that bare `fetch` left open.
333
+ response = await pinnedFetch(currentUrl, {
334
+ headers: { Accept: 'text/markdown,text/plain,text/*,*/*' },
335
+ signal,
336
+ redirect: 'manual',
337
+ })
338
+ if (!REDIRECT_STATUSES.has(response.status)) break
339
+ try { await response.body?.cancel() } catch {}
340
+ if (hops >= MAX_REDIRECTS) {
341
+ throw new Error(`docs index too many redirects (max ${MAX_REDIRECTS})`)
342
+ }
343
+ const location = response.headers.get('location')
344
+ if (!location) {
345
+ throw new Error(`docs index redirect ${response.status} without Location header`)
346
+ }
347
+ currentUrl = new URL(location, currentUrl).toString()
348
+ }
349
+ if (!response.ok) {
350
+ try { await response.body?.cancel() } catch {}
351
+ throw new Error(`docs index fetch failed: ${response.status}`)
352
+ }
353
+ const contentLength = Number(response.headers.get('content-length') || 0)
354
+ if (contentLength > DOC_INDEX_MAX_BYTES) {
355
+ try { await response.body?.cancel() } catch {}
356
+ throw new Error(`docs index too large: ${contentLength}`)
357
+ }
358
+ // Enforce DOC_INDEX_MAX_BYTES while streaming so chunked / missing-length
359
+ // responses can't blow past the 2MB cap by deferring the check until after
360
+ // the whole body is buffered.
361
+ const reader = response.body?.getReader?.()
362
+ let text
363
+ if (!reader) {
364
+ // Buffer as bytes and cap by byte length — string.length counts UTF-16
365
+ // code units, which under-counts multi-byte characters and lets the
366
+ // body blow past DOC_INDEX_MAX_BYTES.
367
+ const buf = new Uint8Array(await response.arrayBuffer())
368
+ const capped = buf.byteLength > DOC_INDEX_MAX_BYTES ? buf.subarray(0, DOC_INDEX_MAX_BYTES) : buf
369
+ text = new TextDecoder('utf-8', { fatal: false }).decode(capped)
370
+ } else {
371
+ const chunks = []
372
+ let total = 0
373
+ let capped = false
374
+ try {
375
+ while (true) {
376
+ const { done, value } = await reader.read()
377
+ if (done) break
378
+ total += value.byteLength
379
+ chunks.push(value)
380
+ if (total >= DOC_INDEX_MAX_BYTES) {
381
+ capped = true
382
+ try { await reader.cancel() } catch {}
383
+ break
384
+ }
385
+ }
386
+ } finally {
387
+ try { reader.releaseLock() } catch {}
388
+ }
389
+ const decoder = new TextDecoder('utf-8', { fatal: false })
390
+ let buf = ''
391
+ for (const chunk of chunks) buf += decoder.decode(chunk, { stream: true })
392
+ buf += decoder.decode()
393
+ text = capped || buf.length > DOC_INDEX_MAX_BYTES ? buf.slice(0, DOC_INDEX_MAX_BYTES) : buf
394
+ }
395
+ return {
396
+ text,
397
+ url: response.url || url,
398
+ }
399
+ }
400
+
401
+ function parseDocIndexLinks(text, sourceUrl) {
402
+ const links = []
403
+ const seen = new Set()
404
+ const add = (title, rawUrl, snippet = '') => {
405
+ if (!title || !rawUrl) return
406
+ let url
407
+ try {
408
+ url = new URL(rawUrl, sourceUrl).toString()
409
+ } catch {
410
+ return
411
+ }
412
+ if (!/^https?:\/\//i.test(url) || seen.has(url)) return
413
+ seen.add(url)
414
+ links.push({
415
+ title: String(title).trim(),
416
+ url,
417
+ snippet: String(snippet || '').trim(),
418
+ sourceUrl,
419
+ })
420
+ }
421
+
422
+ for (const line of String(text || '').split(/\r?\n/)) {
423
+ const item = line.match(/^\s*[-*]\s+\[([^\]]{1,180})\]\(([^)\s]+)\)\s*:?\s*(.*)$/)
424
+ if (item) add(item[1], item[2], item[3])
425
+ }
426
+ const inlineRe = /\[([^\]]{1,180})\]\((https?:\/\/[^)\s]+)\)/g
427
+ let match
428
+ while ((match = inlineRe.exec(String(text || '')))) {
429
+ add(match[1], match[2])
430
+ }
431
+ return links
432
+ }
433
+
434
+
435
+ function isDocIndexLink(url) {
436
+ try {
437
+ return /\/llms(?:-full)?\.txt$/i.test(new URL(url).pathname)
438
+ } catch {
439
+ return false
440
+ }
441
+ }
442
+
443
+ function hostFromUrl(url) {
444
+ try {
445
+ return new URL(/^https?:\/\//i.test(url) ? url : `https://${url}`).hostname.toLowerCase()
446
+ } catch {
447
+ return ''
448
+ }
449
+ }
450
+
451
+ function isBaseHost(host) {
452
+ return host.split('.').filter(Boolean).length <= 2
453
+ }
454
+
455
+ function hostMatchesScope(host, scopedHost) {
456
+ if (!host || !scopedHost) return false
457
+ if (host === scopedHost) return true
458
+ return isBaseHost(scopedHost) && host.endsWith(`.${scopedHost}`)
459
+ }
460
+
461
+ function sameDocIndexScope(url, site, requestedIndexUrl) {
462
+ const linkHost = hostFromUrl(url)
463
+ if (!linkHost) return false
464
+ // Always require the link to match the original requested site host.
465
+ const siteHost = hostFromUrl(site)
466
+ if (siteHost && !hostMatchesScope(linkHost, siteHost)) return false
467
+ const scopes = [
468
+ siteHost,
469
+ hostFromUrl(requestedIndexUrl),
470
+ ].filter(Boolean)
471
+ return scopes.some(scope => hostMatchesScope(linkHost, scope))
472
+ }
473
+
474
+ async function discoverDocsIndexResults(args, timeoutMs, parentSignal) {
475
+ if (!args?.site || (args.type && args.type !== 'web')) return []
476
+ const tokens = queryTokens(args.keywords)
477
+ if (!tokens.length) return []
478
+
479
+ const queue = docIndexUrlCandidates(args.site, args.keywords)
480
+ const seenIndexes = new Set()
481
+ const candidates = []
482
+
483
+ while (queue.length > 0 && seenIndexes.size < DOC_INDEX_MAX_FETCHES) {
484
+ if (parentSignal?.aborted) return []
485
+ const indexUrl = queue.shift()
486
+ if (!indexUrl || seenIndexes.has(indexUrl)) continue
487
+ seenIndexes.add(indexUrl)
488
+ let index = null
489
+ try {
490
+ index = await fetchDocIndex(indexUrl, timeoutMs, parentSignal)
491
+ } catch {
492
+ continue
493
+ }
494
+ const sourceUrl = index.url || indexUrl
495
+ const links = parseDocIndexLinks(index.text, sourceUrl)
496
+ for (const link of links) {
497
+ if (isDocIndexLink(link.url)) {
498
+ if (!seenIndexes.has(link.url) && queue.length + seenIndexes.size < DOC_INDEX_MAX_FETCHES) queue.push(link.url)
499
+ continue
500
+ }
501
+ if (!sameDocIndexScope(link.url, args.site, indexUrl)) continue
502
+ const score = docLinkScore(link, tokens)
503
+ if (score <= 0) continue
504
+ candidates.push({
505
+ ...link,
506
+ score,
507
+ })
508
+ }
509
+ }
510
+
511
+ const seenUrls = new Set()
512
+ return candidates
513
+ .sort((a, b) => b.score - a.score)
514
+ .filter((item) => {
515
+ if (seenUrls.has(item.url)) return false
516
+ seenUrls.add(item.url)
517
+ return true
518
+ })
519
+ .slice(0, Math.min(Number(args.maxResults) || 5, 5))
520
+ .map(item => ({
521
+ title: item.title,
522
+ url: item.url,
523
+ snippet: item.snippet || `Matched docs index: ${item.sourceUrl}`,
524
+ source: 'docs-index',
525
+ provider: 'docs-index',
526
+ publishedDate: null,
527
+ meta: { score: item.score, sourceUrl: item.sourceUrl },
528
+ }))
529
+ }
530
+
531
+ async function augmentSearchPayloadWithDocsIndex(payload, args, timeoutMs, parentSignal) {
532
+ if (!payload || typeof payload !== 'object') return payload
533
+ const response = payload.response
534
+ if (!response || typeof response !== 'object' || !Array.isArray(response.results)) return payload
535
+ const indexResults = await discoverDocsIndexResults(args, timeoutMs, parentSignal)
536
+ if (!indexResults.length) return payload
537
+ const seen = new Set()
538
+ const results = []
539
+ for (const result of [...indexResults, ...response.results]) {
540
+ const url = String(result?.url || '')
541
+ const key = url || `${result?.title || ''}\n${result?.snippet || ''}`
542
+ if (seen.has(key)) continue
543
+ seen.add(key)
544
+ results.push(result)
545
+ }
546
+ return {
547
+ ...payload,
548
+ response: {
549
+ ...response,
550
+ results: results.slice(0, Math.max(Number(args.maxResults) || results.length, indexResults.length)),
551
+ docsIndexAugmented: {
552
+ added: indexResults.length,
553
+ sources: [...new Set(indexResults.map(item => item.meta?.sourceUrl).filter(Boolean))],
554
+ },
555
+ },
556
+ }
557
+ }
558
+
559
+ async function writeStartupSnapshot() {
560
+ loadConfig()
561
+ const usageState = loadUsageState()
562
+ const scrapeCapabilities = getScrapeCapabilities()
563
+
564
+ updateProviderState(usageState, 'readability', {
565
+ available: scrapeCapabilities.readability,
566
+ connection: 'builtin',
567
+ source: 'local',
568
+ })
569
+
570
+ updateProviderState(usageState, 'puppeteer', {
571
+ available: scrapeCapabilities.puppeteer,
572
+ connection: 'local-browser',
573
+ source: 'local',
574
+ })
575
+ }
576
+
577
+ // ── Core action implementations (shared by individual and batch handlers) ──
578
+
579
+ const _searchInFlight = new Map()
580
+
581
+ function searchArgsForCacheKey(args) {
582
+ const keywords = Array.isArray(args.keywords)
583
+ ? [...new Set(args.keywords.map(v => String(v || '').trim()).filter(Boolean))]
584
+ : String(args.keywords || '').trim()
585
+ return {
586
+ keywords,
587
+ site: args.site || null,
588
+ type: args.type || 'web',
589
+ locale: args.locale || null,
590
+ contextSize: args.contextSize || 'low',
591
+ maxResults: Math.max(1, Math.min(20, Number(args.maxResults) || 10)),
592
+ }
593
+ }
594
+
595
+ function buildAgentSearchPrompt(args) {
596
+ const query = Array.isArray(args.keywords) ? args.keywords.join('\n') : String(args.keywords || '')
597
+ const lines = [
598
+ 'Perform a concise web research task for Mixdog search.',
599
+ '',
600
+ `Query: ${query}`,
601
+ args.site ? `Site/domain restriction: ${args.site}` : null,
602
+ args.type ? `Search type: ${args.type}` : null,
603
+ args.locale ? `Locale: ${typeof args.locale === 'string' ? args.locale : JSON.stringify(args.locale)}` : null,
604
+ `Max results: ${Math.max(1, Math.min(20, Number(args.maxResults) || 10))}`,
605
+ '',
606
+ 'Return a short answer first, then cite useful results as title + URL + one-line snippet.',
607
+ 'Do not edit files.',
608
+ ].filter(Boolean)
609
+ return lines.join('\n')
610
+ }
611
+
612
+ async function _searchCore(args, { cacheState, agentSearch, signal }) {
613
+ const cacheArgs = searchArgsForCacheKey(args)
614
+ const searchCacheKey = buildCacheKey('search', {
615
+ provider: 'web-researcher',
616
+ ...cacheArgs,
617
+ })
618
+ const cachedSearch = getCachedEntry(cacheState, searchCacheKey)
619
+ if (cachedSearch) return { ...cachedSearch.payload, cache: buildCacheMeta(cachedSearch, true) }
620
+
621
+ const existing = _searchInFlight.get(searchCacheKey)
622
+ if (existing) return existing
623
+
624
+ const run = (async () => {
625
+ if (signal?.aborted) throw signal.reason || new Error('search aborted')
626
+ if (typeof agentSearch !== 'function') {
627
+ throw new Error('search provider unavailable: Web Researcher agent bridge is not attached')
628
+ }
629
+ const startedAt = Date.now()
630
+ const content = await agentSearch({
631
+ ...args,
632
+ ...cacheArgs,
633
+ prompt: buildAgentSearchPrompt({ ...args, ...cacheArgs }),
634
+ })
635
+ const answer = String(content || '').trim()
636
+ const payload = {
637
+ tool: 'search',
638
+ provider: 'web-researcher',
639
+ response: {
640
+ usedProvider: 'web-researcher',
641
+ query: Array.isArray(cacheArgs.keywords) ? cacheArgs.keywords.join('\n') : cacheArgs.keywords,
642
+ rawQuery: Array.isArray(cacheArgs.keywords) ? cacheArgs.keywords.join('\n') : cacheArgs.keywords,
643
+ answer,
644
+ model: null,
645
+ durationMs: Date.now() - startedAt,
646
+ usage: null,
647
+ results: [],
648
+ warnings: [],
649
+ type: cacheArgs.type,
650
+ site: cacheArgs.site,
651
+ locale: cacheArgs.locale,
652
+ },
653
+ }
654
+ const cachedEntry = setCachedEntry(cacheState, searchCacheKey, payload, getSearchCacheTtlMs(cacheArgs.type))
655
+ flushCacheState()
656
+ return { ...payload, cache: buildCacheMeta(cachedEntry, false) }
657
+ })()
658
+
659
+ run.catch(() => {})
660
+ _searchInFlight.set(searchCacheKey, run)
661
+ try {
662
+ return await run
663
+ } finally {
664
+ if (_searchInFlight.get(searchCacheKey) === run) _searchInFlight.delete(searchCacheKey)
665
+ }
666
+ }
667
+
668
+ const DEFAULT_FETCH_MAX_LENGTH = 50000
669
+ const FETCH_CACHE_VERSION = 'auto-render-js-fallback-v1'
670
+
671
+ // Apply character-level pagination to a cached or fresh fetch payload. Mirrors
672
+ // the mcp-server-fetch reference: caller passes startIndex/maxLength and
673
+ // receives a slice plus pointers (nextStartIndex, hasMore) for the next chunk.
674
+ // totalLength is preserved so the caller can decide whether to keep paging.
675
+ function applyFetchPagination(payload, args) {
676
+ const fullContent = String(payload?.content ?? '')
677
+ const totalLength = fullContent.length
678
+ const startIndex = Math.max(0, Number.isFinite(args?.startIndex) ? args.startIndex : 0)
679
+ const rawLimit = args?.maxLength
680
+ const limit = rawLimit === 0
681
+ ? Infinity
682
+ : (rawLimit == null ? DEFAULT_FETCH_MAX_LENGTH : Math.max(0, Number(rawLimit)))
683
+ if (startIndex >= totalLength) {
684
+ return {
685
+ ...payload,
686
+ content: '',
687
+ bytes: 0,
688
+ totalLength,
689
+ range: { startIndex, endIndex: startIndex },
690
+ hasMore: false,
691
+ nextStartIndex: null,
692
+ truncated: false,
693
+ }
694
+ }
695
+ const endIndex = Math.min(totalLength, startIndex + (Number.isFinite(limit) ? limit : totalLength - startIndex))
696
+ const slice = fullContent.slice(startIndex, endIndex)
697
+ const hasMore = endIndex < totalLength
698
+ return {
699
+ ...payload,
700
+ content: slice,
701
+ bytes: Buffer.byteLength(slice, 'utf-8'),
702
+ totalLength,
703
+ range: { startIndex, endIndex },
704
+ hasMore,
705
+ nextStartIndex: hasMore ? endIndex : null,
706
+ truncated: hasMore || startIndex > 0,
707
+ }
708
+ }
709
+
710
+ async function _fetchCore(args, { usageState, cacheState, timeoutMs, signal }) {
711
+ const FETCH_URL_CAP = Math.max(1, Number(process.env.FETCH_URL_CAP) || 10)
712
+ // Bound how many URLs scrape concurrently. Each non-cached URL can launch a
713
+ // Puppeteer browser; running all FETCH_URL_CAP (default 10) at once can spawn
714
+ // up to 10 Chromium processes simultaneously and exhaust memory/file handles.
715
+ const FETCH_CONCURRENCY = Math.max(1, Number(process.env.FETCH_CONCURRENCY) || 3)
716
+ const allUrls = Array.isArray(args.url) ? args.url : [args.url]
717
+ const urls = allUrls.slice(0, FETCH_URL_CAP)
718
+
719
+ const runOne = async (url, index) => {
720
+ const normalizedUrl = normalizeCacheUrl(url)
721
+ const fetchCacheKey = buildCacheKey('fetch:url', { url: normalizedUrl, version: FETCH_CACHE_VERSION })
722
+ const cached = getCachedEntry(cacheState, fetchCacheKey)
723
+ if (cached) {
724
+ return {
725
+ index: index + 1,
726
+ status: 'success',
727
+ ...applyFetchPagination(cached.payload, args),
728
+ cache: buildCacheMeta(cached, true),
729
+ }
730
+ }
731
+
732
+ try {
733
+ const [page] = await scrapeUrls([url], timeoutMs, usageState, signal)
734
+ if (page?.error) {
735
+ return {
736
+ index: index + 1,
737
+ status: 'error',
738
+ tool: 'web_fetch',
739
+ url,
740
+ error: page.error,
741
+ }
742
+ }
743
+ const payload = { tool: 'web_fetch', ...page }
744
+ const cachedEntry = setCachedEntry(cacheState, fetchCacheKey, payload, getScrapeCacheTtlMs(false))
745
+ return {
746
+ index: index + 1,
747
+ status: 'success',
748
+ ...applyFetchPagination(payload, args),
749
+ cache: buildCacheMeta(cachedEntry, false),
750
+ }
751
+ } catch (error) {
752
+ // Pre-extractor failures (e.g. assertPublicUrl in web-tools) throw
753
+ // before scrapeUrls returns a page-shaped error. Surface the raw
754
+ // message verbatim so the caller sees the actual cause rather than
755
+ // a silenced/swallowed result.
756
+ const message = error instanceof Error
757
+ ? (error.message || error.name || 'fetch failed')
758
+ : String(error)
759
+ const code = error?.code || error?.name || null
760
+ return {
761
+ index: index + 1,
762
+ status: 'error',
763
+ tool: 'web_fetch',
764
+ url,
765
+ error: message,
766
+ ...(code ? { errorCode: code } : {}),
767
+ }
768
+ }
769
+ }
770
+
771
+ // Bounded worker pool: at most FETCH_CONCURRENCY runOne() calls in flight.
772
+ const results = new Array(urls.length)
773
+ let next = 0
774
+ const worker = async () => {
775
+ while (next < urls.length) {
776
+ const i = next++
777
+ results[i] = await runOne(urls[i], i)
778
+ }
779
+ }
780
+ await Promise.all(
781
+ Array.from({ length: Math.min(FETCH_CONCURRENCY, urls.length) }, worker),
782
+ )
783
+
784
+ return { tool: 'web_fetch', results, urlsTruncated: allUrls.length > urls.length ? allUrls.length : 0 }
785
+ }
786
+
787
+ // Only `web_fetch` remains in the direct web module. Web search is routed
788
+ // through the Web Researcher agent, so there is no standalone search provider
789
+ // configuration or search backend selection surface.
790
+ import { TOOL_DEFS as toolDefinitions } from './tool-defs.mjs'
791
+
792
+ const SEARCH_INSTRUCTIONS = '';
793
+
794
+ const server = new Server(
795
+ {
796
+ name: 'mixdog-web',
797
+ version: PLUGIN_VERSION,
798
+ },
799
+ {
800
+ capabilities: {
801
+ tools: {},
802
+ },
803
+ instructions: SEARCH_INSTRUCTIONS,
804
+ },
805
+ )
806
+
807
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
808
+ tools: toolDefinitions.filter(t => t.public !== false),
809
+ }))
810
+
811
+ async function handleToolCall(name, rawArgs, options = {}) {
812
+ const { signal, agentSearch } = options || {}
813
+ const config = loadConfig()
814
+ const usageState = loadUsageState()
815
+ const cacheState = loadCacheState()
816
+ const timeoutMs = getRequestTimeoutMs(config)
817
+
818
+ switch (name) {
819
+ case 'search': {
820
+ let args
821
+ const rawAction = String(rawArgs?.action || 'run').trim().toLowerCase()
822
+ if (['list', 'status', 'read', 'cancel'].includes(rawAction)) {
823
+ return searchTaskControl(rawAction, rawArgs || {}, options)
824
+ }
825
+ if (rawArgs && rawArgs.pattern !== undefined && rawArgs.query === undefined && rawArgs.keywords === undefined) {
826
+ return { content: [{ type: 'text', text: 'Error: web search requires query; use glob(pattern=...) for file paths.' }], isError: true }
827
+ }
828
+ if (rawArgs && rawArgs.query !== undefined && rawArgs.keywords === undefined) {
829
+ rawArgs = { ...rawArgs, keywords: rawArgs.query }
830
+ delete rawArgs.query
831
+ }
832
+ try {
833
+ args = searchArgsSchema.parse(normalizeSearchArgs(rawArgs || {}))
834
+ } catch (e) {
835
+ if (e instanceof z.ZodError) {
836
+ return { content: [{ type: 'text', text: JSON.stringify({ error: 'Invalid arguments', details: e.errors }) }], isError: true }
837
+ }
838
+ throw e
839
+ }
840
+ const runSearchNow = async () => {
841
+ if (Array.isArray(args.keywords) && args.keywords.length > 1) {
842
+ const SEARCH_FANOUT_CAP = Math.max(1, Number(process.env.SEARCH_FANOUT_CAP) || 10)
843
+ const keywords = [...new Set(args.keywords.map(kw => String(kw || '').trim()).filter(Boolean))].slice(0, SEARCH_FANOUT_CAP)
844
+ const sections = await Promise.all(keywords.map(async (kw) => {
845
+ const sub = await handleToolCall('search', { ...rawArgs, keywords: kw, mode: 'sync', action: 'run' }, { signal, agentSearch })
846
+ const text = (sub.content || []).filter(p => p.type === 'text').map(p => p.text).join('\n')
847
+ return `### Query: ${kw}\n\n${text}`
848
+ }))
849
+ return { content: [{ type: 'text', text: sections.join('\n\n---\n\n') }] }
850
+ }
851
+ try {
852
+ const result = await _searchCore(args, { cacheState, agentSearch, signal })
853
+ flushUsageState()
854
+ return formattedText('search', result)
855
+ } catch (error) {
856
+ flushUsageState()
857
+ const _rawErr = normalizeErrorMessage(error instanceof Error ? error.message : String(error))
858
+ const _cleanErr = presentErrorText(_rawErr, { surface: 'search' })
859
+ return { content: [{ type: 'text', text: `Search failed: ${_cleanErr}` }], isError: true }
860
+ }
861
+ }
862
+ if (resolveExecutionMode(args, 'sync') === 'async') {
863
+ const label = Array.isArray(args.keywords)
864
+ ? args.keywords.join(' | ')
865
+ : String(args.keywords || '')
866
+ const task = startBackgroundTask({
867
+ surface: 'search',
868
+ operation: 'search',
869
+ label: label.replace(/\s+/g, ' ').slice(0, 120),
870
+ input: { keywords: args.keywords, site: args.site || null, type: args.type || 'web' },
871
+ context: options,
872
+ resultType: 'search_task_result',
873
+ renderResult: (text) => String(text || ''),
874
+ run: async () => {
875
+ const response = await runSearchNow()
876
+ const text = toolText(response)
877
+ if (response?.isError) throw new Error(text)
878
+ return text
879
+ },
880
+ })
881
+ return okText(renderBackgroundTask(task))
882
+ }
883
+ return runSearchNow()
884
+ }
885
+ case 'web_fetch': {
886
+ let urlArgs
887
+ try {
888
+ urlArgs = searchUrlArgsSchema.parse(normalizeSearchUrlArgs(rawArgs || {}))
889
+ } catch (e) {
890
+ if (e instanceof z.ZodError) {
891
+ return { content: [{ type: 'text', text: JSON.stringify({ error: 'Invalid arguments', details: e.errors }) }], isError: true }
892
+ }
893
+ throw e
894
+ }
895
+ try {
896
+ const result = await _fetchCore(urlArgs, { config, usageState, cacheState, timeoutMs, signal })
897
+ flushCacheState()
898
+ flushUsageState()
899
+ return {
900
+ ...formattedText('fetch', result),
901
+ ...(result.results.some(item => item.status === 'success') ? {} : { isError: true }),
902
+ }
903
+ } catch (error) {
904
+ flushUsageState()
905
+ const _rawErr = normalizeErrorMessage(error instanceof Error ? error.message : String(error))
906
+ const _cleanErr = presentErrorText(_rawErr, { surface: 'web_fetch' })
907
+ return { content: [{ type: 'text', text: `Fetch failed: ${_cleanErr}` }], isError: true }
908
+ }
909
+ }
910
+ default:
911
+ throw new Error(`Unknown tool: ${name}`)
912
+ }
913
+ }
914
+
915
+ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
916
+ return handleToolCall(request.params.name, request.params.arguments, { signal: extra?.signal })
917
+ })
918
+
919
+ /* ── Module exports (used when imported by mixdog-unified) ── */
920
+ export { toolDefinitions as TOOL_DEFS }
921
+ export { SEARCH_INSTRUCTIONS as instructions }
922
+
923
+ export { handleToolCall }
924
+ export async function start() { await writeStartupSnapshot() }
925
+ export function stop() { flushUsageState(); flushCacheState() }