mixdog 0.7.1

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 (404) hide show
  1. package/.claude-plugin/marketplace.json +31 -0
  2. package/.claude-plugin/plugin.json +20 -0
  3. package/.gitattributes +34 -0
  4. package/.mcp.json +14 -0
  5. package/ARCHITECTURE.md +77 -0
  6. package/CHANGELOG.md +7 -0
  7. package/CONTRIBUTING.md +45 -0
  8. package/DATA-FLOW.md +79 -0
  9. package/LICENSE +21 -0
  10. package/README.md +389 -0
  11. package/SECURITY.md +138 -0
  12. package/UNINSTALL.md +112 -0
  13. package/agents/maintenance.md +5 -0
  14. package/agents/memory-classification.md +30 -0
  15. package/agents/scheduler-task.md +18 -0
  16. package/agents/webhook-handler.md +27 -0
  17. package/agents/worker.md +24 -0
  18. package/bin/bridge +133 -0
  19. package/bin/statusline-launcher.mjs +78 -0
  20. package/bin/statusline-lib.mjs +550 -0
  21. package/bin/statusline.mjs +607 -0
  22. package/bun.lock +802 -0
  23. package/commands/config.md +16 -0
  24. package/commands/doctor.md +13 -0
  25. package/commands/setup.md +17 -0
  26. package/defaults/cycle3-review-prompt.md +90 -0
  27. package/defaults/hidden-roles.json +65 -0
  28. package/defaults/memory-chunk-prompt.md +63 -0
  29. package/defaults/memory-promote-prompt.md +135 -0
  30. package/defaults/mixdog-config.template.json +27 -0
  31. package/defaults/user-workflow.json +8 -0
  32. package/defaults/user-workflow.md +12 -0
  33. package/hooks/hooks.json +73 -0
  34. package/hooks/lib/active-instance.cjs +77 -0
  35. package/hooks/lib/permission-evaluator.cjs +411 -0
  36. package/hooks/lib/permission-route.cjs +63 -0
  37. package/hooks/lib/permission-rules.cjs +170 -0
  38. package/hooks/lib/settings-loader.cjs +116 -0
  39. package/hooks/post-tool-use.cjs +84 -0
  40. package/hooks/pre-mcp-sandbox.cjs +158 -0
  41. package/hooks/pre-tool-subagent.cjs +253 -0
  42. package/hooks/session-start.cjs +1372 -0
  43. package/hooks/turn-timer.cjs +82 -0
  44. package/lib/claude-md-writer.cjs +386 -0
  45. package/lib/config-cjs.cjs +61 -0
  46. package/lib/hook-pipe-path.cjs +10 -0
  47. package/lib/keychain-cjs.cjs +263 -0
  48. package/lib/plugin-paths.cjs +61 -0
  49. package/lib/rules-builder.cjs +241 -0
  50. package/lib/text-utils.cjs +61 -0
  51. package/native/README.md +117 -0
  52. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  53. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  54. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  55. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  56. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  57. package/package.json +107 -0
  58. package/prompts/code-review.txt +16 -0
  59. package/prompts/security-audit.txt +17 -0
  60. package/rules/bridge/00-common.md +39 -0
  61. package/rules/bridge/20-skip-protocol.md +18 -0
  62. package/rules/bridge/30-explorer.md +33 -0
  63. package/rules/bridge/40-cycle1-agent.md +52 -0
  64. package/rules/bridge/41-cycle2-agent.md +62 -0
  65. package/rules/bridge/42-cycle3-agent.md +44 -0
  66. package/rules/lead/00-tool-lead.md +61 -0
  67. package/rules/lead/01-general.md +23 -0
  68. package/rules/lead/02-channels.md +49 -0
  69. package/rules/lead/03-team.md +27 -0
  70. package/rules/lead/04-workflow.md +20 -0
  71. package/rules/shared/00-language.md +14 -0
  72. package/rules/shared/01-tool.md +138 -0
  73. package/scripts/bootstrap.mjs +184 -0
  74. package/scripts/bridge-unify-smoke.mjs +308 -0
  75. package/scripts/build-runtime-linux.sh +348 -0
  76. package/scripts/build-runtime-macos.sh +217 -0
  77. package/scripts/build-runtime-windows.ps1 +242 -0
  78. package/scripts/builtin-utils-smoke.mjs +392 -0
  79. package/scripts/check-json.mjs +45 -0
  80. package/scripts/check-syntax-changed.mjs +102 -0
  81. package/scripts/check-syntax.mjs +58 -0
  82. package/scripts/code-graph-batch.test.mjs +33 -0
  83. package/scripts/config-preserve-smoke.mjs +180 -0
  84. package/scripts/doctor.mjs +484 -0
  85. package/scripts/edit-normalize-fuzz.mjs +130 -0
  86. package/scripts/edit-normalize-smoke.mjs +401 -0
  87. package/scripts/edit-operation-smoke.mjs +369 -0
  88. package/scripts/edit2-smoke.mjs +63 -0
  89. package/scripts/fuzzy-e2e.mjs +28 -0
  90. package/scripts/fuzzy-smoke.mjs +26 -0
  91. package/scripts/generate-runtime-manifest.mjs +166 -0
  92. package/scripts/guard-smoke.mjs +66 -0
  93. package/scripts/hidden-role-schema-smoke.mjs +162 -0
  94. package/scripts/hook-routing-smoke.mjs +29 -0
  95. package/scripts/inject-input.ps1 +204 -0
  96. package/scripts/io-complex-smoke.mjs +667 -0
  97. package/scripts/io-explore-bench.mjs +424 -0
  98. package/scripts/io-guardrails-smoke.mjs +205 -0
  99. package/scripts/io-mini-bench-baseline.json +11 -0
  100. package/scripts/io-mini-bench.mjs +216 -0
  101. package/scripts/io-route-harness.mjs +933 -0
  102. package/scripts/io-telemetry-report.mjs +691 -0
  103. package/scripts/mutation-bench.mjs +564 -0
  104. package/scripts/mutation-io-smoke.mjs +1081 -0
  105. package/scripts/native-patch-bridge-smoke.mjs +288 -0
  106. package/scripts/native-patch-smoke.mjs +304 -0
  107. package/scripts/patch-interior-context-smoke.mjs +49 -0
  108. package/scripts/patch-newline-utf8-smoke.mjs +157 -0
  109. package/scripts/perf-hook-smoke.mjs +71 -0
  110. package/scripts/permission-eval-smoke.mjs +426 -0
  111. package/scripts/prep-patch.mjs +53 -0
  112. package/scripts/prep-shim.mjs +96 -0
  113. package/scripts/provider-cache-smoke.mjs +687 -0
  114. package/scripts/report-runtime-health.mjs +132 -0
  115. package/scripts/run-mcp.mjs +1547 -0
  116. package/scripts/salvage-v4a-shatter.test.mjs +58 -0
  117. package/scripts/scoped-cache-io-smoke.mjs +103 -0
  118. package/scripts/shell-policy-round3-smoke.mjs +46 -0
  119. package/scripts/smoke-runtime-negative.ps1 +100 -0
  120. package/scripts/smoke-runtime-negative.sh +95 -0
  121. package/scripts/stall-policy-smoke.mjs +50 -0
  122. package/scripts/start-memory-worker.mjs +23 -0
  123. package/scripts/statusline-launcher-smoke.mjs +82 -0
  124. package/scripts/stress-atomic-write.mjs +1028 -0
  125. package/scripts/test-config-rmw-restore.mjs +122 -0
  126. package/scripts/test-fault-inject.mjs +164 -0
  127. package/scripts/test-large-file.mjs +174 -0
  128. package/scripts/tool-edge-smoke.mjs +209 -0
  129. package/scripts/uninstall.mjs +201 -0
  130. package/scripts/webhook-selfheal-smoke.mjs +29 -0
  131. package/scripts/write-overwrite-guard-smoke.mjs +56 -0
  132. package/server-main.mjs +3055 -0
  133. package/server.mjs +468 -0
  134. package/setup/config-merge.mjs +254 -0
  135. package/setup/install.mjs +120 -0
  136. package/setup/launch-core.mjs +507 -0
  137. package/setup/launch.mjs +101 -0
  138. package/setup/setup-server.mjs +3206 -0
  139. package/setup/setup.html +3693 -0
  140. package/skills/retro-skill-proposer/SKILL.md +92 -0
  141. package/skills/schedule-add/SKILL.md +77 -0
  142. package/skills/setup/SKILL.md +346 -0
  143. package/skills/webhook-add/SKILL.md +81 -0
  144. package/src/agent/bridge-stall-watchdog.mjs +337 -0
  145. package/src/agent/index.mjs +2138 -0
  146. package/src/agent/orchestrator/activity-bus.mjs +38 -0
  147. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +1010 -0
  148. package/src/agent/orchestrator/bridge-retry.mjs +220 -0
  149. package/src/agent/orchestrator/bridge-trace.mjs +583 -0
  150. package/src/agent/orchestrator/cache-mtime.mjs +58 -0
  151. package/src/agent/orchestrator/config.mjs +358 -0
  152. package/src/agent/orchestrator/context/collect.mjs +651 -0
  153. package/src/agent/orchestrator/dispatch-persist.mjs +549 -0
  154. package/src/agent/orchestrator/drain-registry.mjs +50 -0
  155. package/src/agent/orchestrator/explore-validator.mjs +8 -0
  156. package/src/agent/orchestrator/internal-roles.mjs +118 -0
  157. package/src/agent/orchestrator/internal-tools.mjs +88 -0
  158. package/src/agent/orchestrator/jobs.mjs +116 -0
  159. package/src/agent/orchestrator/mcp/client.mjs +364 -0
  160. package/src/agent/orchestrator/providers/anthropic-betas.mjs +21 -0
  161. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +1745 -0
  162. package/src/agent/orchestrator/providers/anthropic.mjs +437 -0
  163. package/src/agent/orchestrator/providers/gemini.mjs +1175 -0
  164. package/src/agent/orchestrator/providers/grok-oauth.mjs +782 -0
  165. package/src/agent/orchestrator/providers/model-catalog.mjs +241 -0
  166. package/src/agent/orchestrator/providers/openai-compat.mjs +1467 -0
  167. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +1890 -0
  168. package/src/agent/orchestrator/providers/openai-oauth.mjs +1307 -0
  169. package/src/agent/orchestrator/providers/openai-ws.mjs +104 -0
  170. package/src/agent/orchestrator/providers/registry.mjs +192 -0
  171. package/src/agent/orchestrator/providers/retry-classifier.mjs +325 -0
  172. package/src/agent/orchestrator/session/abort-lookup.mjs +13 -0
  173. package/src/agent/orchestrator/session/cache/post-edit-marks.mjs +42 -0
  174. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
  175. package/src/agent/orchestrator/session/cache/read-cache.mjs +319 -0
  176. package/src/agent/orchestrator/session/cache/scoped-cache-outcome.mjs +11 -0
  177. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +361 -0
  178. package/src/agent/orchestrator/session/cache/util.mjs +49 -0
  179. package/src/agent/orchestrator/session/loop.mjs +1478 -0
  180. package/src/agent/orchestrator/session/manager.mjs +1975 -0
  181. package/src/agent/orchestrator/session/read-dedup.mjs +6 -0
  182. package/src/agent/orchestrator/session/result-classification.mjs +65 -0
  183. package/src/agent/orchestrator/session/save-session-worker.mjs +18 -0
  184. package/src/agent/orchestrator/session/store.mjs +624 -0
  185. package/src/agent/orchestrator/session/stream-watchdog.mjs +130 -0
  186. package/src/agent/orchestrator/session/tool-result-offload.mjs +166 -0
  187. package/src/agent/orchestrator/session/trim.mjs +491 -0
  188. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +115 -0
  189. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +327 -0
  190. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +150 -0
  191. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +228 -0
  192. package/src/agent/orchestrator/smart-bridge/index.mjs +215 -0
  193. package/src/agent/orchestrator/smart-bridge/profiles.mjs +37 -0
  194. package/src/agent/orchestrator/smart-bridge/registry.mjs +348 -0
  195. package/src/agent/orchestrator/smart-bridge/session-builder.mjs +116 -0
  196. package/src/agent/orchestrator/stall-policy.mjs +195 -0
  197. package/src/agent/orchestrator/tool-loop-guard.mjs +75 -0
  198. package/src/agent/orchestrator/tools/bash-policy-scan.mjs +77 -0
  199. package/src/agent/orchestrator/tools/bash-session.mjs +721 -0
  200. package/src/agent/orchestrator/tools/builtin/advisory-lock.mjs +171 -0
  201. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +455 -0
  202. package/src/agent/orchestrator/tools/builtin/atomic-write.mjs +236 -0
  203. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +480 -0
  204. package/src/agent/orchestrator/tools/builtin/binary-file.mjs +76 -0
  205. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +256 -0
  206. package/src/agent/orchestrator/tools/builtin/cache-layers.mjs +386 -0
  207. package/src/agent/orchestrator/tools/builtin/cwd-utils.mjs +37 -0
  208. package/src/agent/orchestrator/tools/builtin/device-paths.mjs +154 -0
  209. package/src/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +292 -0
  210. package/src/agent/orchestrator/tools/builtin/diff-utils.mjs +109 -0
  211. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +58 -0
  212. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +240 -0
  213. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +113 -0
  214. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +74 -0
  215. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +242 -0
  216. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +211 -0
  217. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +1364 -0
  218. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +126 -0
  219. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +141 -0
  220. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +194 -0
  221. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +60 -0
  222. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +168 -0
  223. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +173 -0
  224. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +48 -0
  225. package/src/agent/orchestrator/tools/builtin/fs-reachability.mjs +48 -0
  226. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +99 -0
  227. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +170 -0
  228. package/src/agent/orchestrator/tools/builtin/grep-formatting.mjs +113 -0
  229. package/src/agent/orchestrator/tools/builtin/hash-utils.mjs +6 -0
  230. package/src/agent/orchestrator/tools/builtin/list-formatting.mjs +7 -0
  231. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +593 -0
  232. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +89 -0
  233. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +300 -0
  234. package/src/agent/orchestrator/tools/builtin/open-config-tool.mjs +26 -0
  235. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +152 -0
  236. package/src/agent/orchestrator/tools/builtin/path-locks.mjs +35 -0
  237. package/src/agent/orchestrator/tools/builtin/path-utils.mjs +201 -0
  238. package/src/agent/orchestrator/tools/builtin/read-args.mjs +103 -0
  239. package/src/agent/orchestrator/tools/builtin/read-batch.mjs +172 -0
  240. package/src/agent/orchestrator/tools/builtin/read-constants.mjs +40 -0
  241. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
  242. package/src/agent/orchestrator/tools/builtin/read-image-resize.mjs +189 -0
  243. package/src/agent/orchestrator/tools/builtin/read-image.mjs +88 -0
  244. package/src/agent/orchestrator/tools/builtin/read-lines.mjs +12 -0
  245. package/src/agent/orchestrator/tools/builtin/read-mode-tool.mjs +455 -0
  246. package/src/agent/orchestrator/tools/builtin/read-open.mjs +190 -0
  247. package/src/agent/orchestrator/tools/builtin/read-range-index.mjs +271 -0
  248. package/src/agent/orchestrator/tools/builtin/read-ranges.mjs +26 -0
  249. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +728 -0
  250. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +173 -0
  251. package/src/agent/orchestrator/tools/builtin/read-special-files.mjs +268 -0
  252. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
  253. package/src/agent/orchestrator/tools/builtin/read-tool.mjs +530 -0
  254. package/src/agent/orchestrator/tools/builtin/read-windows.mjs +107 -0
  255. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +196 -0
  256. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +422 -0
  257. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +158 -0
  258. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +869 -0
  259. package/src/agent/orchestrator/tools/builtin/shell-analysis.mjs +653 -0
  260. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +936 -0
  261. package/src/agent/orchestrator/tools/builtin/shell-output.mjs +36 -0
  262. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +214 -0
  263. package/src/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +143 -0
  264. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +206 -0
  265. package/src/agent/orchestrator/tools/builtin/snapshot-validation.mjs +98 -0
  266. package/src/agent/orchestrator/tools/builtin/text-stats.mjs +69 -0
  267. package/src/agent/orchestrator/tools/builtin/windows-roots.mjs +23 -0
  268. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +401 -0
  269. package/src/agent/orchestrator/tools/builtin.mjs +500 -0
  270. package/src/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +39 -0
  271. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
  272. package/src/agent/orchestrator/tools/code-graph.mjs +4095 -0
  273. package/src/agent/orchestrator/tools/cwd-tool.mjs +298 -0
  274. package/src/agent/orchestrator/tools/destructive-warning.mjs +323 -0
  275. package/src/agent/orchestrator/tools/edit-normalize.mjs +603 -0
  276. package/src/agent/orchestrator/tools/env-scrub.mjs +100 -0
  277. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +144 -0
  278. package/src/agent/orchestrator/tools/graph-manifest.json +26 -0
  279. package/src/agent/orchestrator/tools/host-input.mjs +204 -0
  280. package/src/agent/orchestrator/tools/mutation-content-cache.mjs +67 -0
  281. package/src/agent/orchestrator/tools/mutation-planner.mjs +75 -0
  282. package/src/agent/orchestrator/tools/next-call-utils.mjs +48 -0
  283. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +133 -0
  284. package/src/agent/orchestrator/tools/patch-manifest.json +26 -0
  285. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +20 -0
  286. package/src/agent/orchestrator/tools/patch.mjs +2754 -0
  287. package/src/agent/orchestrator/tools/progress-message.mjs +118 -0
  288. package/src/agent/orchestrator/tools/result-compression.mjs +279 -0
  289. package/src/agent/orchestrator/tools/shell-command.mjs +865 -0
  290. package/src/agent/orchestrator/tools/shell-exec-policy.mjs +89 -0
  291. package/src/agent/orchestrator/tools/shell-policy-danger-target.mjs +27 -0
  292. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +7 -0
  293. package/src/agent/orchestrator/tools/shell-policy.mjs +345 -0
  294. package/src/agent/orchestrator/tools/shell-snapshot.mjs +313 -0
  295. package/src/agent/orchestrator/workflow-store.mjs +93 -0
  296. package/src/agent/tool-defs.mjs +103 -0
  297. package/src/channels/backends/discord.mjs +784 -0
  298. package/src/channels/data/voice-runtime-manifest.json +138 -0
  299. package/src/channels/index.mjs +3229 -0
  300. package/src/channels/lib/cli-worker-host.mjs +12 -0
  301. package/src/channels/lib/config-lock.mjs +13 -0
  302. package/src/channels/lib/config.mjs +292 -0
  303. package/src/channels/lib/drop-trace.mjs +71 -0
  304. package/src/channels/lib/event-pipeline.mjs +81 -0
  305. package/src/channels/lib/event-queue.mjs +345 -0
  306. package/src/channels/lib/executor.mjs +168 -0
  307. package/src/channels/lib/format.mjs +188 -0
  308. package/src/channels/lib/holidays.mjs +138 -0
  309. package/src/channels/lib/hook-pipe-server.mjs +802 -0
  310. package/src/channels/lib/interaction-workflows.mjs +184 -0
  311. package/src/channels/lib/memory-client.mjs +149 -0
  312. package/src/channels/lib/output-forwarder.mjs +765 -0
  313. package/src/channels/lib/runtime-paths.mjs +479 -0
  314. package/src/channels/lib/scheduler.mjs +723 -0
  315. package/src/channels/lib/session-control.mjs +36 -0
  316. package/src/channels/lib/session-discovery.mjs +103 -0
  317. package/src/channels/lib/settings.mjs +11 -0
  318. package/src/channels/lib/state-file.mjs +68 -0
  319. package/src/channels/lib/status-snapshot.mjs +219 -0
  320. package/src/channels/lib/tool-format.mjs +140 -0
  321. package/src/channels/lib/transcript-discovery.mjs +195 -0
  322. package/src/channels/lib/voice-runtime-fetcher.mjs +734 -0
  323. package/src/channels/lib/webhook.mjs +1179 -0
  324. package/src/channels/lib/whisper-server.mjs +477 -0
  325. package/src/channels/tool-defs.mjs +170 -0
  326. package/src/daemon/host.mjs +118 -0
  327. package/src/daemon/mcp-transport.mjs +47 -0
  328. package/src/daemon/session.mjs +100 -0
  329. package/src/daemon/thin-client.mjs +71 -0
  330. package/src/daemon/transport.mjs +163 -0
  331. package/src/memory/data/runtime-manifest.json +40 -0
  332. package/src/memory/index.mjs +3305 -0
  333. package/src/memory/lib/agent-ipc.mjs +93 -0
  334. package/src/memory/lib/bridge-trace-queries.mjs +120 -0
  335. package/src/memory/lib/core-memory-store.mjs +330 -0
  336. package/src/memory/lib/embedding-provider.mjs +269 -0
  337. package/src/memory/lib/embedding-worker.mjs +323 -0
  338. package/src/memory/lib/llm-worker-host.mjs +17 -0
  339. package/src/memory/lib/memory-cycle.mjs +11 -0
  340. package/src/memory/lib/memory-cycle1.mjs +641 -0
  341. package/src/memory/lib/memory-cycle2.mjs +1284 -0
  342. package/src/memory/lib/memory-cycle3.mjs +540 -0
  343. package/src/memory/lib/memory-embed.mjs +299 -0
  344. package/src/memory/lib/memory-extraction.mjs +5 -0
  345. package/src/memory/lib/memory-maintenance-store.mjs +32 -0
  346. package/src/memory/lib/memory-ops-policy.mjs +190 -0
  347. package/src/memory/lib/memory-recall-id-patch.mjs +15 -0
  348. package/src/memory/lib/memory-recall-read-query.mjs +7 -0
  349. package/src/memory/lib/memory-recall-scope-filter.mjs +63 -0
  350. package/src/memory/lib/memory-recall-store.mjs +621 -0
  351. package/src/memory/lib/memory-retrievers.mjs +112 -0
  352. package/src/memory/lib/memory-score.mjs +71 -0
  353. package/src/memory/lib/memory-text-utils.mjs +58 -0
  354. package/src/memory/lib/memory.mjs +412 -0
  355. package/src/memory/lib/model-profile.mjs +85 -0
  356. package/src/memory/lib/pg/adapter.mjs +308 -0
  357. package/src/memory/lib/pg/process.mjs +360 -0
  358. package/src/memory/lib/pg/supervisor.mjs +396 -0
  359. package/src/memory/lib/project-id-resolver.mjs +86 -0
  360. package/src/memory/lib/runtime-fetcher.mjs +442 -0
  361. package/src/memory/lib/trace-store.mjs +728 -0
  362. package/src/memory/tool-defs.mjs +79 -0
  363. package/src/search/index.mjs +1173 -0
  364. package/src/search/lib/backends/anthropic-oauth.mjs +98 -0
  365. package/src/search/lib/backends/exa.mjs +50 -0
  366. package/src/search/lib/backends/firecrawl.mjs +61 -0
  367. package/src/search/lib/backends/gemini-api.mjs +83 -0
  368. package/src/search/lib/backends/grok-oauth.mjs +86 -0
  369. package/src/search/lib/backends/index.mjs +150 -0
  370. package/src/search/lib/backends/openai-api.mjs +144 -0
  371. package/src/search/lib/backends/openai-oauth.mjs +98 -0
  372. package/src/search/lib/backends/openai-web-search.mjs +76 -0
  373. package/src/search/lib/backends/tavily.mjs +55 -0
  374. package/src/search/lib/backends/xai-api.mjs +113 -0
  375. package/src/search/lib/cache.mjs +131 -0
  376. package/src/search/lib/config.mjs +192 -0
  377. package/src/search/lib/formatter.mjs +115 -0
  378. package/src/search/lib/provider-usage.mjs +67 -0
  379. package/src/search/lib/providers.mjs +47 -0
  380. package/src/search/lib/search-intent.mjs +109 -0
  381. package/src/search/lib/setup-handler.mjs +261 -0
  382. package/src/search/lib/state.mjs +201 -0
  383. package/src/search/lib/web-tools.mjs +1207 -0
  384. package/src/search/tool-defs.mjs +83 -0
  385. package/src/setup/defender-exclusion.mjs +183 -0
  386. package/src/shared/abort-controller.mjs +15 -0
  387. package/src/shared/atomic-file.mjs +420 -0
  388. package/src/shared/config.mjs +350 -0
  389. package/src/shared/daemon-recycle.mjs +108 -0
  390. package/src/shared/disable-claude-builtins.mjs +88 -0
  391. package/src/shared/err-text.mjs +12 -0
  392. package/src/shared/llm/cost.mjs +66 -0
  393. package/src/shared/llm/http-agent.mjs +123 -0
  394. package/src/shared/llm/index.mjs +41 -0
  395. package/src/shared/llm/pid-cleanup.mjs +27 -0
  396. package/src/shared/llm/usage-log.mjs +47 -0
  397. package/src/shared/plugin-paths.mjs +58 -0
  398. package/src/shared/schedules-store.mjs +70 -0
  399. package/src/shared/seed.mjs +119 -0
  400. package/src/shared/user-cwd.mjs +213 -0
  401. package/src/shared/user-data-guard.mjs +238 -0
  402. package/src/status/aggregator.mjs +584 -0
  403. package/src/status/server.mjs +413 -0
  404. package/tools.json +1653 -0
@@ -0,0 +1,687 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Provider cache smoke/diagnostic runner.
4
+ *
5
+ * Static mode (default) prints the provider cache capability matrix and an
6
+ * in-memory SmartBridge registry probe. Live mode makes small sequential
7
+ * calls to enabled providers and reports normalized usage/cache metrics
8
+ * without printing secrets or prompt bodies.
9
+ *
10
+ * Usage:
11
+ * node scripts/provider-cache-smoke.mjs
12
+ * node scripts/provider-cache-smoke.mjs --live --providers gemini,openai-oauth --repeat 2
13
+ * node scripts/provider-cache-smoke.mjs --live --gemini-trace --stable-chars 6000
14
+ */
15
+
16
+ import { dirname, join, resolve } from 'node:path';
17
+ import { fileURLToPath } from 'node:url';
18
+ import { homedir } from 'node:os';
19
+ import { existsSync, readFileSync } from 'node:fs';
20
+ import { createHash } from 'node:crypto';
21
+
22
+ const HERE = dirname(fileURLToPath(import.meta.url));
23
+ const PLUGIN_ROOT = resolve(HERE, '..');
24
+
25
+ const opts = parseArgs(process.argv.slice(2));
26
+ if (opts.help) {
27
+ printHelp();
28
+ process.exit(0);
29
+ }
30
+
31
+ process.env.CLAUDE_PLUGIN_ROOT ||= PLUGIN_ROOT;
32
+ process.env.CLAUDE_PLUGIN_DATA ||= join(homedir(), '.claude', 'plugins', 'data', 'mixdog-trib-plugin');
33
+ if (opts.geminiTrace) process.env.MIXDOG_GEMINI_CACHE_TRACE = '1';
34
+ if (opts.compatTrace) process.env.MIXDOG_COMPAT_CACHE_TRACE = '1';
35
+
36
+ const { loadConfig, listPresets } = await import('../src/agent/orchestrator/config.mjs');
37
+ const { initProviders, getAllProviders } = await import('../src/agent/orchestrator/providers/registry.mjs');
38
+ const {
39
+ buildProviderCacheOpts,
40
+ cacheCapabilityForProvider,
41
+ computePrefixContent,
42
+ shouldMarkWarmForProvider,
43
+ shouldRecordObservedForProvider,
44
+ } = await import('../src/agent/orchestrator/smart-bridge/cache-strategy.mjs');
45
+ const { CacheRegistry } = await import('../src/agent/orchestrator/smart-bridge/registry.mjs');
46
+ const { SmartBridge } = await import('../src/agent/orchestrator/smart-bridge/index.mjs');
47
+ const { drainOpenaiWsPool } = await import('../src/agent/orchestrator/providers/openai-oauth-ws.mjs');
48
+ const { createSession, closeSession } = await import('../src/agent/orchestrator/session/manager.mjs');
49
+
50
+ const config = loadConfig();
51
+ const allProviderNames = Object.keys(config.providers || {}).sort();
52
+ const selectedProviders = opts.providers
53
+ ? opts.providers.filter(p => allProviderNames.includes(p))
54
+ : allProviderNames;
55
+
56
+ const modelOverrides = parseModelOverrides(opts.model);
57
+ const registryProbe = runRegistryProbe(selectedProviders);
58
+ const staticRows = selectedProviders.map((provider) => {
59
+ const providerConfig = config.providers?.[provider] || {};
60
+ const cacheOpts = buildProviderCacheOpts(provider, 'provider-cache-smoke-session', 'provider-cache-smoke');
61
+ return {
62
+ provider,
63
+ enabled: providerConfig.enabled === true,
64
+ capability: cacheCapabilityForProvider(provider),
65
+ markWarm: shouldMarkWarmForProvider(provider),
66
+ observedOnly: shouldRecordObservedForProvider(provider),
67
+ cacheOpts: Object.keys(cacheOpts).sort(),
68
+ configuredModel: chooseModel(provider, config, modelOverrides) || '(provider default)',
69
+ registryWarm: registryProbe[provider]?.warm === true,
70
+ registryReason: registryProbe[provider]?.reason || 'not-probed',
71
+ };
72
+ });
73
+
74
+ let liveRows = [];
75
+ let initError = null;
76
+ if (opts.live) {
77
+ try {
78
+ if (opts.actualContext) await initActualContextRuntime();
79
+ else await initProviders(config.providers || {});
80
+ } catch (err) {
81
+ initError = sanitizeError(err);
82
+ }
83
+ if (!initError) {
84
+ const providers = getAllProviders();
85
+ for (const row of staticRows) {
86
+ if (!row.enabled) {
87
+ liveRows.push({ provider: row.provider, status: 'skipped', reason: 'disabled' });
88
+ continue;
89
+ }
90
+ const provider = providers.get(row.provider);
91
+ if (!provider) {
92
+ liveRows.push({ provider: row.provider, status: 'skipped', reason: 'not-initialized' });
93
+ continue;
94
+ }
95
+ liveRows.push(await runLiveProviderSmoke({
96
+ providerName: row.provider,
97
+ provider,
98
+ model: row.configuredModel === '(provider default)' ? undefined : row.configuredModel,
99
+ repeat: opts.repeat,
100
+ delayMs: opts.delayMs,
101
+ stableChars: opts.stableChars,
102
+ timeoutMs: opts.timeoutMs,
103
+ actualContext: opts.actualContext,
104
+ singleSession: opts.singleSession,
105
+ role: opts.role,
106
+ cwd: opts.cwd,
107
+ }));
108
+ }
109
+ }
110
+ }
111
+
112
+ const report = {
113
+ generatedAt: new Date().toISOString(),
114
+ pluginRoot: PLUGIN_ROOT,
115
+ pluginData: process.env.CLAUDE_PLUGIN_DATA,
116
+ live: opts.live,
117
+ actualContext: opts.actualContext,
118
+ singleSession: opts.singleSession,
119
+ role: opts.role,
120
+ cwd: opts.cwd,
121
+ repeat: opts.repeat,
122
+ delayMs: opts.delayMs,
123
+ stableChars: opts.stableChars,
124
+ providers: staticRows,
125
+ ...(opts.live ? { initError, liveResults: liveRows } : {}),
126
+ };
127
+
128
+ if (opts.json) {
129
+ console.log(JSON.stringify(report, null, 2));
130
+ } else {
131
+ printHumanReport(report);
132
+ }
133
+
134
+ try { drainOpenaiWsPool('provider-cache-smoke-complete'); } catch {}
135
+
136
+ if (opts.live && !opts.allowFail) {
137
+ const failed = initError || liveRows.some(r => r.status === 'failed');
138
+ if (failed) process.exitCode = 1;
139
+ }
140
+
141
+ function parseArgs(args) {
142
+ const out = {
143
+ live: false,
144
+ providers: null,
145
+ repeat: 2,
146
+ delayMs: 0,
147
+ stableChars: 6000,
148
+ timeoutMs: 90_000,
149
+ json: false,
150
+ geminiTrace: false,
151
+ compatTrace: false,
152
+ actualContext: false,
153
+ singleSession: false,
154
+ role: 'worker',
155
+ cwd: null,
156
+ model: [],
157
+ allowFail: false,
158
+ help: false,
159
+ };
160
+ for (let i = 0; i < args.length; i++) {
161
+ const arg = args[i];
162
+ if (arg === '--help' || arg === '-h') out.help = true;
163
+ else if (arg === '--live') out.live = true;
164
+ else if (arg === '--no-live') out.live = false;
165
+ else if (arg === '--json') out.json = true;
166
+ else if (arg === '--gemini-trace') out.geminiTrace = true;
167
+ else if (arg === '--compat-trace') out.compatTrace = true;
168
+ else if (arg === '--actual-context') out.actualContext = true;
169
+ else if (arg === '--single-session') out.singleSession = true;
170
+ else if (arg === '--allow-fail') out.allowFail = true;
171
+ else if (arg === '--providers') out.providers = parseCsv(args[++i]);
172
+ else if (arg.startsWith('--providers=')) out.providers = parseCsv(arg.slice('--providers='.length));
173
+ else if (arg === '--role') out.role = String(args[++i] || out.role);
174
+ else if (arg.startsWith('--role=')) out.role = String(arg.slice('--role='.length) || out.role);
175
+ else if (arg === '--cwd') out.cwd = normalizeCwdArg(args[++i]);
176
+ else if (arg.startsWith('--cwd=')) out.cwd = normalizeCwdArg(arg.slice('--cwd='.length));
177
+ else if (arg === '--repeat') out.repeat = clampInt(args[++i], 1, 10, out.repeat);
178
+ else if (arg.startsWith('--repeat=')) out.repeat = clampInt(arg.slice('--repeat='.length), 1, 10, out.repeat);
179
+ else if (arg === '--delay-ms') out.delayMs = clampInt(args[++i], 0, 60_000, out.delayMs);
180
+ else if (arg.startsWith('--delay-ms=')) out.delayMs = clampInt(arg.slice('--delay-ms='.length), 0, 60_000, out.delayMs);
181
+ else if (arg === '--stable-chars') out.stableChars = clampInt(args[++i], 256, 120_000, out.stableChars);
182
+ else if (arg.startsWith('--stable-chars=')) out.stableChars = clampInt(arg.slice('--stable-chars='.length), 256, 120_000, out.stableChars);
183
+ else if (arg === '--timeout-ms') out.timeoutMs = clampInt(args[++i], 5_000, 300_000, out.timeoutMs);
184
+ else if (arg.startsWith('--timeout-ms=')) out.timeoutMs = clampInt(arg.slice('--timeout-ms='.length), 5_000, 300_000, out.timeoutMs);
185
+ else if (arg === '--model') out.model.push(String(args[++i] || ''));
186
+ else if (arg.startsWith('--model=')) out.model.push(arg.slice('--model='.length));
187
+ else throw new Error(`unknown argument: ${arg}`);
188
+ }
189
+ return out;
190
+ }
191
+
192
+ function normalizeCwdArg(value) {
193
+ const raw = String(value || '').trim();
194
+ if (!raw || raw === 'null' || raw === 'none') return null;
195
+ return resolve(raw.replace(/^~(?=$|[\\/])/, homedir()));
196
+ }
197
+
198
+ function parseCsv(value) {
199
+ return String(value || '')
200
+ .split(',')
201
+ .map(s => s.trim())
202
+ .filter(Boolean);
203
+ }
204
+
205
+ function clampInt(value, min, max, fallback) {
206
+ const n = Number(value);
207
+ if (!Number.isFinite(n)) return fallback;
208
+ return Math.max(min, Math.min(max, Math.trunc(n)));
209
+ }
210
+
211
+ function sleep(ms) {
212
+ return new Promise(resolve => setTimeout(resolve, ms));
213
+ }
214
+
215
+ function parseModelOverrides(values) {
216
+ const map = new Map();
217
+ for (const raw of values || []) {
218
+ for (const item of parseCsv(raw)) {
219
+ const idx = item.indexOf('=');
220
+ if (idx <= 0) continue;
221
+ const provider = item.slice(0, idx).trim();
222
+ const model = item.slice(idx + 1).trim();
223
+ if (provider && model) map.set(provider, model);
224
+ }
225
+ }
226
+ return map;
227
+ }
228
+
229
+ function chooseModel(provider, cfg, overrides) {
230
+ if (overrides.has(provider)) return overrides.get(provider);
231
+ const preset = listPresets(cfg).find(p => p?.provider === provider && p?.model);
232
+ if (preset?.model) return preset.model;
233
+ const fallback = {
234
+ anthropic: 'claude-haiku-4-5-20251001',
235
+ 'anthropic-oauth': 'claude-haiku-4-5-20251001',
236
+ gemini: 'gemini-3.5-flash',
237
+ openai: 'gpt-5.5',
238
+ 'openai-oauth': 'gpt-5.5',
239
+ };
240
+ return fallback[provider] || undefined;
241
+ }
242
+
243
+ function runRegistryProbe(providerNames) {
244
+ const registry = new CacheRegistry();
245
+ registry.loaded = true;
246
+ registry.data = { version: 2, profiles: {}, openaiKeys: {}, updatedAt: new Date().toISOString() };
247
+ registry.save = () => { registry.dirty = false; };
248
+ const bridge = new SmartBridge({ registry });
249
+ const profile = { id: 'provider-cache-smoke' };
250
+ const systemPrompt = ['stable-system'];
251
+ const tools = [{ name: 'noop', description: 'No-op smoke tool.', inputSchema: { type: 'object' } }];
252
+ const prefix = computePrefixContent(systemPrompt, tools);
253
+ const out = {};
254
+ for (const provider of providerNames) {
255
+ bridge.recordCall(profile, provider, {
256
+ systemPrompt,
257
+ tools,
258
+ usage: { inputTokens: 100, promptTokens: 100, cachedTokens: provider === 'gemini' ? 0 : 25 },
259
+ });
260
+ out[provider] = registry.checkWarm(profile.id, provider, prefix);
261
+ }
262
+ return out;
263
+ }
264
+
265
+ async function runLiveProviderSmoke({ providerName, provider, model, repeat, delayMs, stableChars, timeoutMs, actualContext, singleSession, role, cwd }) {
266
+ const started = Date.now();
267
+ const attempts = [];
268
+ const cacheKey = `mixdog-provider-cache-smoke-${providerName}`;
269
+ const cacheOpts = buildProviderCacheOpts(providerName, cacheKey, 'provider-cache-smoke');
270
+ let sharedActual = null;
271
+ let sharedMessages = null;
272
+ let sharedProviderState = undefined;
273
+
274
+ try {
275
+ if (actualContext && singleSession) {
276
+ sharedActual = buildActualRequestContext({
277
+ providerName,
278
+ model,
279
+ role,
280
+ cwd,
281
+ sourceName: `provider-cache-smoke-${providerName}`,
282
+ });
283
+ }
284
+
285
+ for (let i = 1; i <= repeat; i++) {
286
+ const ac = new AbortController();
287
+ const timer = setTimeout(() => {
288
+ try { ac.abort(new Error(`provider-cache-smoke timeout after ${timeoutMs}ms`)); } catch {}
289
+ }, timeoutMs);
290
+ if (timer.unref) timer.unref();
291
+ const t0 = Date.now();
292
+ let lastStage = null;
293
+ let actual = null;
294
+ try {
295
+ actual = actualContext
296
+ ? (sharedActual || buildActualRequestContext({
297
+ providerName,
298
+ model,
299
+ role,
300
+ cwd,
301
+ sourceName: `provider-cache-smoke-${providerName}`,
302
+ }))
303
+ : null;
304
+ let messages = actualContext
305
+ ? actual.messages
306
+ : makeSmokeMessages(stableChars);
307
+ if (actualContext && singleSession) {
308
+ if (!sharedMessages) sharedMessages = [...actual.messages];
309
+ else {
310
+ sharedMessages = [
311
+ ...sharedMessages,
312
+ { role: 'user', content: `Reply with exactly: SMOKE_OK_${i}` },
313
+ ];
314
+ }
315
+ messages = sharedMessages;
316
+ } else if (actualContext) {
317
+ messages = makeActualSmokeMessages(actual.messages, i);
318
+ }
319
+ const tools = actual?.tools || [];
320
+ const sessionId = actual?.sessionId || `${cacheKey}-${Date.now()}-${i}`;
321
+ const result = await provider.send(messages, model, actualContext ? tools : [], {
322
+ ...cacheOpts,
323
+ sessionId,
324
+ providerCacheKey: cacheKey,
325
+ promptCacheKey: cacheKey,
326
+ providerState: actualContext && singleSession ? sharedProviderState : undefined,
327
+ role: 'provider-cache-smoke',
328
+ iteration: i,
329
+ signal: ac.signal,
330
+ session: {
331
+ id: sessionId,
332
+ owner: 'smoke',
333
+ role: 'provider-cache-smoke',
334
+ permission: 'read',
335
+ toolPermission: 'none',
336
+ profileId: 'provider-cache-smoke',
337
+ sourceType: 'diagnostic',
338
+ sourceName: 'provider-cache-smoke',
339
+ },
340
+ onStageChange: (stage) => { lastStage = stage; },
341
+ onStreamDelta: () => {},
342
+ });
343
+ attempts.push({
344
+ iteration: i,
345
+ status: 'ok',
346
+ ms: Date.now() - t0,
347
+ stage: lastStage,
348
+ model: result?.model || model || null,
349
+ textChars: String(result?.content || '').length,
350
+ usage: summarizeUsage(result?.usage),
351
+ ...(actual?.session ? { context: summarizeActualContext(actual.session, messages) } : (actual?.shape ? { context: actual.shape } : {})),
352
+ });
353
+ if (actualContext && singleSession) {
354
+ sharedProviderState = result?.providerState ?? sharedProviderState;
355
+ sharedMessages = [
356
+ ...messages,
357
+ {
358
+ role: 'assistant',
359
+ content: String(result?.content || ''),
360
+ ...(typeof result?.reasoningContent === 'string' && result.reasoningContent
361
+ ? { reasoningContent: result.reasoningContent }
362
+ : {}),
363
+ },
364
+ ];
365
+ }
366
+ } catch (err) {
367
+ attempts.push({
368
+ iteration: i,
369
+ status: 'failed',
370
+ ms: Date.now() - t0,
371
+ stage: lastStage,
372
+ error: sanitizeError(err),
373
+ });
374
+ break;
375
+ } finally {
376
+ clearTimeout(timer);
377
+ if (!singleSession && actual?.sessionId) {
378
+ try { closeSession(actual.sessionId, 'provider-cache-smoke-complete'); } catch {}
379
+ }
380
+ }
381
+ if (delayMs > 0 && i < repeat) await sleep(delayMs);
382
+ }
383
+ } catch (err) {
384
+ attempts.push({
385
+ iteration: attempts.length + 1,
386
+ status: 'failed',
387
+ ms: Date.now() - started,
388
+ stage: null,
389
+ error: sanitizeError(err),
390
+ });
391
+ } finally {
392
+ if (sharedActual?.sessionId) {
393
+ try { closeSession(sharedActual.sessionId, 'provider-cache-smoke-complete'); } catch {}
394
+ }
395
+ }
396
+
397
+ const totals = attempts.reduce((acc, attempt) => {
398
+ if (attempt.status !== 'ok') return acc;
399
+ const u = attempt.usage || {};
400
+ acc.ok += 1;
401
+ acc.inputTokens += u.inputTokens || 0;
402
+ acc.promptTokens += u.promptTokens || 0;
403
+ acc.outputTokens += u.outputTokens || 0;
404
+ acc.cachedTokens += u.cachedTokens || 0;
405
+ acc.cacheWriteTokens += u.cacheWriteTokens || 0;
406
+ return acc;
407
+ }, { ok: 0, inputTokens: 0, promptTokens: 0, outputTokens: 0, cachedTokens: 0, cacheWriteTokens: 0 });
408
+ totals.cacheHitRate = totals.promptTokens > 0
409
+ ? Number((totals.cachedTokens / totals.promptTokens).toFixed(6))
410
+ : null;
411
+
412
+ return {
413
+ provider: providerName,
414
+ status: attempts.every(a => a.status === 'ok') ? 'ok' : 'failed',
415
+ model: attempts.find(a => a.model)?.model || model || null,
416
+ ms: Date.now() - started,
417
+ totals,
418
+ attempts,
419
+ };
420
+ }
421
+
422
+ function makeActualSmokeMessages(baseMessages, iteration) {
423
+ const out = [...(baseMessages || [])];
424
+ for (let n = 2; n <= iteration; n++) {
425
+ out.push({ role: 'user', content: `Reply with exactly: SMOKE_OK_${n}` });
426
+ }
427
+ return out;
428
+ }
429
+
430
+ function buildActualRequestContext({ providerName, model, role, cwd, sourceName }) {
431
+ const preset = {
432
+ id: `provider-cache-smoke-${providerName}`,
433
+ name: `PROVIDER CACHE SMOKE ${providerName}`,
434
+ type: 'bridge',
435
+ provider: providerName,
436
+ model,
437
+ tools: 'full',
438
+ };
439
+ const session = createSession({
440
+ owner: 'bridge',
441
+ role,
442
+ preset,
443
+ cwd,
444
+ sourceType: 'diagnostic',
445
+ sourceName,
446
+ taskType: 'provider-cache-smoke',
447
+ });
448
+ const userMessage = { role: 'user', content: 'Reply with exactly: SMOKE_OK' };
449
+ const messages = [...session.messages, userMessage];
450
+ return {
451
+ sessionId: session.id,
452
+ session,
453
+ messages,
454
+ tools: session.tools || [],
455
+ shape: summarizeActualContext(session, messages),
456
+ };
457
+ }
458
+
459
+ function summarizeActualContext(session, messages) {
460
+ const systemMessages = messages.filter(m => m?.role === 'system').map(m => String(m.content || ''));
461
+ const nonSystem = messages.filter(m => m?.role !== 'system');
462
+ const tools = session.tools || [];
463
+ const toolShape = tools.map(t => ({
464
+ name: t?.name || null,
465
+ description: t?.description || '',
466
+ inputSchema: t?.inputSchema || null,
467
+ }));
468
+ return {
469
+ role: session.role || null,
470
+ provider: session.provider || null,
471
+ model: session.model || null,
472
+ owner: session.owner || null,
473
+ cwd: session.cwd || null,
474
+ messageCount: messages.length,
475
+ systemCount: systemMessages.length,
476
+ systemChars: systemMessages.reduce((n, s) => n + s.length, 0),
477
+ systemHash: shortHash(JSON.stringify(systemMessages)),
478
+ nonSystemTurns: nonSystem.map((m, index) => ({
479
+ index,
480
+ role: m?.role || null,
481
+ chars: String(m?.content || '').length,
482
+ hash: shortHash(String(m?.content || '')),
483
+ })),
484
+ toolCount: tools.length,
485
+ toolSchemaHash: shortHash(stableStringify(toolShape)),
486
+ toolNames: tools.map(t => t?.name).filter(Boolean).sort(),
487
+ promptCacheKey: session.promptCacheKey || null,
488
+ profileId: session.profileId || null,
489
+ };
490
+ }
491
+
492
+ async function initActualContextRuntime() {
493
+ const agentMod = await import('../src/agent/index.mjs');
494
+ if (typeof agentMod.init === 'function') {
495
+ await agentMod.init({ notification: () => {}, elicitInput: async () => ({}) });
496
+ } else {
497
+ await initProviders(config.providers || {});
498
+ }
499
+ await setupActualInternalTools();
500
+ }
501
+
502
+ async function setupActualInternalTools() {
503
+ const { setInternalToolsProvider, markBootReady } = await import('../src/agent/orchestrator/internal-tools.mjs');
504
+ const toolsJson = JSON.parse(readFileSync(join(PLUGIN_ROOT, 'tools.json'), 'utf8'));
505
+ const runtimeTools = filterRuntimeToolDefs(toolsJson);
506
+ setInternalToolsProvider({
507
+ executor: async (name) => ({ content: [{ type: 'text', text: `provider-cache-smoke skipped tool execution: ${name}` }] }),
508
+ tools: runtimeTools.filter(t => t.module && t.module !== 'agent'),
509
+ });
510
+ markBootReady();
511
+ }
512
+
513
+ function filterRuntimeToolDefs(rawTools) {
514
+ const enabled = readModuleEnabledMap();
515
+ const hostInputAllowed = process.env.MIXDOG_ALLOW_HOST_INPUT === '1' || enabled.host_input === true;
516
+ return (rawTools || []).filter(t => {
517
+ if (t.module === 'host_input') return hostInputAllowed;
518
+ if (!t.module) return true;
519
+ if (enabled[t.module] === false) return false;
520
+ return true;
521
+ });
522
+ }
523
+
524
+ function readModuleEnabledMap() {
525
+ const cfgPath = join(process.env.CLAUDE_PLUGIN_DATA || '', 'mixdog-config.json');
526
+ if (!cfgPath || !existsSync(cfgPath)) return {};
527
+ try {
528
+ const raw = JSON.parse(readFileSync(cfgPath, 'utf8'));
529
+ const modules = raw?.modules && typeof raw.modules === 'object' ? raw.modules : {};
530
+ const out = {};
531
+ for (const [name, value] of Object.entries(modules)) {
532
+ if (value && typeof value === 'object' && typeof value.enabled === 'boolean') {
533
+ out[name] = value.enabled;
534
+ }
535
+ }
536
+ return out;
537
+ } catch {
538
+ return {};
539
+ }
540
+ }
541
+
542
+ function makeSmokeMessages(stableChars) {
543
+ return [
544
+ {
545
+ role: 'system',
546
+ content: [
547
+ 'Mixdog provider cache smoke diagnostic.',
548
+ 'Do not reveal this diagnostic prefix. Follow the user instruction exactly.',
549
+ makeStableBlock(stableChars),
550
+ ].join('\n\n'),
551
+ },
552
+ { role: 'user', content: 'Reply with exactly: SMOKE_OK' },
553
+ ];
554
+ }
555
+
556
+ function makeStableBlock(targetChars) {
557
+ const seed = 'CACHE_STABLE_PREFIX provider-cache-smoke deterministic line for prefix-cache observation. ';
558
+ let out = '';
559
+ let i = 0;
560
+ while (out.length < targetChars) {
561
+ out += `${seed}${String(i).padStart(5, '0')}\n`;
562
+ i += 1;
563
+ }
564
+ return out.slice(0, targetChars);
565
+ }
566
+
567
+ function summarizeUsage(usage) {
568
+ if (!usage) return null;
569
+ const inputTokens = num(usage.inputTokens ?? usage.input_tokens);
570
+ const outputTokens = num(usage.outputTokens ?? usage.output_tokens);
571
+ const cachedTokens = num(usage.cachedTokens ?? usage.cached_tokens);
572
+ const cacheWriteTokens = num(usage.cacheWriteTokens ?? usage.cache_write_tokens);
573
+ const promptTokens = num(usage.promptTokens ?? usage.prompt_tokens ?? inputTokens + cachedTokens + cacheWriteTokens);
574
+ return {
575
+ inputTokens,
576
+ promptTokens,
577
+ outputTokens,
578
+ cachedTokens,
579
+ cacheWriteTokens,
580
+ cacheHitRate: promptTokens > 0 ? Number((cachedTokens / promptTokens).toFixed(6)) : null,
581
+ };
582
+ }
583
+
584
+ function num(value) {
585
+ const n = Number(value || 0);
586
+ return Number.isFinite(n) ? n : 0;
587
+ }
588
+
589
+ function sanitizeError(err) {
590
+ const msg = err instanceof Error ? err.message : String(err || '');
591
+ return msg
592
+ .replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/ig, 'Bearer ***')
593
+ .replace(/sk-[A-Za-z0-9_-]{8,}/g, 'sk-***')
594
+ .replace(/AIza[A-Za-z0-9_-]{20,}/g, 'AIza***')
595
+ .replace(/access_token["']?\s*[:=]\s*["']?[^"',\s]+/ig, 'access_token=***')
596
+ .slice(0, 500);
597
+ }
598
+
599
+ function shortHash(value) {
600
+ return createHash('sha256').update(String(value ?? '')).digest('hex').slice(0, 16);
601
+ }
602
+
603
+ function stableStringify(value, seen = new WeakSet()) {
604
+ if (value === null || typeof value !== 'object') return JSON.stringify(value);
605
+ if (seen.has(value)) return JSON.stringify('[Circular]');
606
+ seen.add(value);
607
+ if (Array.isArray(value)) {
608
+ const out = '[' + value.map(v => stableStringify(v, seen)).join(',') + ']';
609
+ seen.delete(value);
610
+ return out;
611
+ }
612
+ const parts = [];
613
+ for (const key of Object.keys(value).sort()) {
614
+ const v = value[key];
615
+ if (v === undefined || typeof v === 'function') continue;
616
+ parts.push(JSON.stringify(key) + ':' + stableStringify(v, seen));
617
+ }
618
+ seen.delete(value);
619
+ return '{' + parts.join(',') + '}';
620
+ }
621
+
622
+ function printHumanReport(report) {
623
+ console.log('Provider cache smoke');
624
+ console.log(`generatedAt=${report.generatedAt}`);
625
+ console.log(`pluginRoot=${report.pluginRoot}`);
626
+ console.log(`pluginData=${report.pluginData}`);
627
+ console.log('');
628
+ console.log('Static capability matrix');
629
+ console.log('| provider | enabled | capability | markWarm | observedOnly | cacheOpts | model | registry |');
630
+ console.log('|---|---:|---|---:|---:|---|---|---|');
631
+ for (const row of report.providers) {
632
+ console.log(`| ${row.provider} | ${row.enabled ? 'yes' : 'no'} | ${row.capability} | ${row.markWarm ? 'yes' : 'no'} | ${row.observedOnly ? 'yes' : 'no'} | ${row.cacheOpts.join(',') || '-'} | ${row.configuredModel} | ${row.registryWarm ? 'warm' : row.registryReason} |`);
633
+ }
634
+ if (!report.live) {
635
+ console.log('');
636
+ console.log('Live mode not requested. Add --live to call enabled providers.');
637
+ return;
638
+ }
639
+ console.log('');
640
+ console.log(`Live smoke repeat=${report.repeat} stableChars=${report.stableChars} actualContext=${report.actualContext ? 'yes' : 'no'} singleSession=${report.singleSession ? 'yes' : 'no'} role=${report.role || '-'}`);
641
+ if (report.initError) {
642
+ console.log(`provider init failed: ${report.initError}`);
643
+ return;
644
+ }
645
+ console.log('| provider | status | model | ok | input | prompt | cached | write | hit% | output | ms |');
646
+ console.log('|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|');
647
+ for (const row of report.liveResults) {
648
+ if (row.status === 'skipped') {
649
+ console.log(`| ${row.provider} | skipped:${row.reason} | - | 0 | 0 | 0 | 0 | 0 | - | 0 | 0 |`);
650
+ continue;
651
+ }
652
+ const t = row.totals || {};
653
+ const hit = t.cacheHitRate == null ? '-' : `${(t.cacheHitRate * 100).toFixed(1)}%`;
654
+ console.log(`| ${row.provider} | ${row.status} | ${row.model || '-'} | ${t.ok || 0} | ${t.inputTokens || 0} | ${t.promptTokens || 0} | ${t.cachedTokens || 0} | ${t.cacheWriteTokens || 0} | ${hit} | ${t.outputTokens || 0} | ${row.ms || 0} |`);
655
+ const context = row.attempts?.find(a => a.context)?.context;
656
+ if (context) {
657
+ console.log(` - actual-context role=${context.role} messages=${context.messageCount} systemChars=${context.systemChars} tools=${context.toolCount} systemHash=${context.systemHash} toolSchemaHash=${context.toolSchemaHash}`);
658
+ }
659
+ for (const attempt of row.attempts || []) {
660
+ if (attempt.status === 'failed') {
661
+ console.log(` - ${row.provider} iter${attempt.iteration} failed after ${attempt.ms}ms: ${attempt.error}`);
662
+ }
663
+ }
664
+ }
665
+ }
666
+
667
+ function printHelp() {
668
+ console.log(`Provider cache smoke
669
+
670
+ Options:
671
+ --live Call enabled providers.
672
+ --providers a,b Limit providers.
673
+ --repeat N Sequential calls per live provider (default 2).
674
+ --delay-ms N Delay between repeated live calls (default 0).
675
+ --stable-chars N Stable system-prefix size for cache smoke (default 6000).
676
+ --actual-context Use real createSession(owner=bridge) worker messages/tools.
677
+ --single-session Reuse one actual-context session across repeated live calls.
678
+ --role NAME Bridge role for --actual-context (default worker).
679
+ --cwd PATH|null cwd for actual context. Default null, matching internal bridge calls.
680
+ --timeout-ms N Per-call timeout (default 90000).
681
+ --model provider=model Override a provider model. Repeatable or comma-separated.
682
+ --gemini-trace Enable MIXDOG_GEMINI_CACHE_TRACE=1 for this process.
683
+ --compat-trace Enable MIXDOG_COMPAT_CACHE_TRACE=1 for OpenAI-compatible providers.
684
+ --json Print JSON.
685
+ --allow-fail Keep exit code 0 even if live providers fail.
686
+ `);
687
+ }