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,228 @@
1
+ /**
2
+ * Smart Bridge — Cache Strategy
3
+ *
4
+ * Provider-level cache policy. Anthropic supports explicit cache_control
5
+ * breakpoints (up to 4 per request) — we use all 4 slots. Non-breakpoint
6
+ * providers rely on server-side automatic prefix matching or observation.
7
+ *
8
+ * Anthropic 4-BP layout (bridge/agent use case — no interactive idle):
9
+ * BP_1 tools (1h) — tool schemas, stable per schema profile
10
+ * BP_2 system (1h) — Tier 2 shared rules
11
+ * BP_3 tier3 (1h) — role/permission meta (messages[1] system-reminder)
12
+ * BP_4 messages (5m) — last message only; sliding extends prefix loss-free
13
+ *
14
+ * Tier 3 gets its own BP because role meta is stable per dispatch, so a
15
+ * dedicated slot gives a reliable hit across the entire tool loop while
16
+ * the sliding messages BP handles volatile tool_result accumulation.
17
+ *
18
+ * Non-breakpoint providers:
19
+ * - OpenAI (public): prompt_cache_key + prompt_cache_retention=24h
20
+ * - OpenAI OAuth (Codex): prompt_cache_key only (server in-memory 5-10min)
21
+ * - Gemini: implicit caching does NOT report cachedContentTokenCount on
22
+ * 3.5+. Explicit cachedContents API required for measurable cache hits.
23
+ * - xAI: x-grok-conv-id (server routing pin) + prompt_cache_key on
24
+ * Responses API. Treat as key-prefix, not implicit.
25
+ * - DeepSeek: automatic KV prompt cache; observe prompt_cache_hit_tokens
26
+ * - Groq: auto 50% cache (gpt-oss-120b) — no knob
27
+ * - Copilot / Ollama / LMStudio: no API-level cache
28
+ */
29
+
30
+ import { getHiddenRole } from '../internal-roles.mjs';
31
+
32
+ /**
33
+ * One-shot, LLM-only maintenance hidden roles (cycle1/cycle2/cycle3-agent):
34
+ * a fresh stateless session is created per call, asked exactly once, and
35
+ * closed (bridge-llm.mjs) — the per-batch user prompt can NEVER be reused.
36
+ * Writing a message-tail cache breakpoint on it just pays the 1.25x write
37
+ * premium for content read back 0 times. Identified by the declarative
38
+ * (kind:'maintenance' + toolSchemaProfile:'llm-only') pair rather than
39
+ * hardcoded names, so new roles sharing the pattern are covered for free.
40
+ * Multi-turn maintenance roles (scheduler-task / webhook-handler) are
41
+ * 'unified' and therefore excluded — they run a tool loop whose tail caches
42
+ * legitimately reuse across iterations.
43
+ */
44
+ function isOneShotMaintenanceRole(role) {
45
+ const hidden = getHiddenRole(role);
46
+ return Boolean(
47
+ hidden
48
+ && hidden.kind === 'maintenance'
49
+ && hidden.toolSchemaProfile === 'llm-only',
50
+ );
51
+ }
52
+
53
+ /**
54
+ * Return the layered cache policy for Anthropic-family providers.
55
+ *
56
+ * Values:
57
+ * '1h' → ephemeral 1h TTL (2x write premium, 0.1x read)
58
+ * '5m' → ephemeral 5m TTL (1.25x write premium, 0.1x read)
59
+ * 'none' → no breakpoint written on this layer
60
+ *
61
+ * Public bridge workers (any user-workflow.json role) stay resumable for up to
62
+ * 1h (the terminal-reap window) for same-task reuse, so their message tail uses
63
+ * 1h too — a resume within that window reads the conversation from cache instead
64
+ * of re-writing it. Hidden multi-turn roles (explorer / scheduler / webhook) run
65
+ * a single fan-out or entry-driven session that is not resumed for same-task
66
+ * reuse, so their volatile tail stays at the cheaper 5m TTL. (Tail TTL only
67
+ * affects explicit-breakpoint providers — Anthropic; no-op elsewhere.)
68
+ *
69
+ * Exception: one-shot LLM-only maintenance roles are asked once on a fresh
70
+ * session and closed, so their volatile per-call message tail is never read
71
+ * back — and trace data (2026-06) shows the 1h system/tools prefix never
72
+ * gets read back either: cycle1's prompt sits below Anthropic's minimum
73
+ * cacheable length (0 writes), and cycle2's 1h run interval lands at/after
74
+ * the 1h TTL expiry (writes every run, 0 reads). All layers go 'none' for
75
+ * these roles — single-iteration calls pay the write premium with no reuse.
76
+ */
77
+ export function resolveCacheStrategy(role) {
78
+ if (isOneShotMaintenanceRole(role)) {
79
+ return { tools: 'none', system: 'none', tier3: 'none', messages: 'none' };
80
+ }
81
+ // Hidden multi-turn roles (explorer / scheduler / webhook): single-use
82
+ // session, not resumed for same-task reuse → keep the cheaper 5m tail.
83
+ if (getHiddenRole(role)) {
84
+ return { tools: '1h', system: '1h', tier3: '1h', messages: '5m' };
85
+ }
86
+ // Public bridge workers: resumable up to 1h for same-task reuse → 1h tail.
87
+ return { tools: '1h', system: '1h', tier3: '1h', messages: '1h' };
88
+ }
89
+
90
+ /**
91
+ * Build provider-specific sendOpts.
92
+ *
93
+ * @param {string} provider
94
+ * @param {string} [sessionId]
95
+ * @param {string} [role]
96
+ * @returns {object} partial sendOpts — spread into provider.send call
97
+ */
98
+
99
+ // Provider cache capability kinds:
100
+ // 'explicit-breakpoint' — explicit provider-side cache_control writes
101
+ // 'key-prefix' — provider-managed shard keyed by cache key/session
102
+ // 'implicit-observed' — cache hits are observable but not guaranteed warm
103
+ // 'none' — no API-level cache knob/metric
104
+ const PROVIDER_CACHE_CAPABILITY = Object.freeze({
105
+ 'anthropic': 'explicit-breakpoint',
106
+ 'anthropic-oauth': 'explicit-breakpoint',
107
+ 'openai': 'key-prefix',
108
+ 'openai-oauth': 'key-prefix',
109
+ 'xai': 'key-prefix',
110
+ 'grok-oauth': 'key-prefix',
111
+ 'gemini': 'implicit-observed',
112
+ 'deepseek': 'implicit-observed',
113
+ });
114
+
115
+ export function cacheCapabilityForProvider(provider) {
116
+ return PROVIDER_CACHE_CAPABILITY[provider] || 'none';
117
+ }
118
+
119
+ export function shouldMarkWarmForProvider(provider) {
120
+ const capability = cacheCapabilityForProvider(provider);
121
+ return capability === 'explicit-breakpoint' || capability === 'key-prefix';
122
+ }
123
+
124
+ export function shouldRecordObservedForProvider(provider) {
125
+ return cacheCapabilityForProvider(provider) === 'implicit-observed';
126
+ }
127
+
128
+ // Stable per-provider shared prompt-cache key. key-prefix providers MUST land on
129
+ // a cross-session shard, so the resolver below NEVER falls back to sessionId
130
+ // (which isolates each session into its own bucket and forces a cold start).
131
+ // Generalizes the xai pattern ('mixdog-xai') that already defaulted to a shared
132
+ // key. Anthropic/Gemini use content-keyed cache_control / explicit CachedContent
133
+ // and do not consult this map.
134
+ const PROVIDER_CACHE_KEY_DEFAULT = Object.freeze({
135
+ 'openai': 'mixdog-openai',
136
+ 'openai-oauth': 'mixdog-codex',
137
+ 'xai': 'mixdog-xai',
138
+ 'grok-oauth': 'mixdog-xai',
139
+ });
140
+
141
+ /**
142
+ * Resolve the server-side prompt-cache grouping key (prompt_cache_key) for a
143
+ * key-prefix provider. Precedence: explicit provider key > prompt key >
144
+ * session-scoped prompt key > stable shared default. Invariant: always returns a
145
+ * non-empty stable key, and deliberately EXCLUDES sessionId so a fresh session
146
+ * reuses the warm shard instead of cold-starting its own bucket.
147
+ *
148
+ * This is the CACHE key only. The socket poolKey stays sessionId-scoped at each
149
+ * call site to avoid cross-session socket/delta-state reuse.
150
+ */
151
+ export function resolveProviderCacheKey(opts, provider) {
152
+ return opts?.providerCacheKey
153
+ || opts?.promptCacheKey
154
+ || opts?.session?.promptCacheKey
155
+ || PROVIDER_CACHE_KEY_DEFAULT[provider]
156
+ || 'mixdog-shared';
157
+ }
158
+
159
+ export function buildProviderCacheOpts(provider, sessionId, role) {
160
+ const ttls = resolveCacheStrategy(role);
161
+ const capability = cacheCapabilityForProvider(provider);
162
+ if (capability === 'explicit-breakpoint') {
163
+ // 2026-03-06 Anthropic dropped default TTL 1h→5m. We send
164
+ // extended-cache-ttl-2025-04-11 header to retain 1h.
165
+ // Verified 2026-04-17 (ephemeral_1h_input_tokens=4722).
166
+ return { cacheStrategy: ttls };
167
+ }
168
+ if (provider === 'openai') {
169
+ // Public OpenAI API: prompt_cache_retention extends prefix retention.
170
+ // openai-oauth (Codex) rejects the header — falls through to default.
171
+ return { cacheRetention: '24h' };
172
+ }
173
+ return {};
174
+ }
175
+
176
+ /**
177
+ * Prefix content used to derive the cache hash for registry tracking.
178
+ * Excludes the volatile user message — only the stable prefix (tools,
179
+ * system) determines whether our cache is "still warm". The Pool B prefix
180
+ * is workspace-wide, so a single hash represents every Pool B caller.
181
+ *
182
+ * `systemPrompt` is an array of system-role message contents in their send
183
+ * order (BP1 / BP2 / ...), serialized deterministically as a JSON array.
184
+ * Invariant: callers must pass an array.
185
+ */
186
+ export function computePrefixContent(systemPrompt, tools) {
187
+ const systemMessages = Array.isArray(systemPrompt)
188
+ ? systemPrompt.map(s => s == null ? '' : String(s))
189
+ : [systemPrompt == null ? '' : String(systemPrompt)];
190
+ return {
191
+ systemPrompt: JSON.stringify(systemMessages),
192
+ tools: (tools || []).map(t => ({
193
+ name: t.name,
194
+ description: t.description,
195
+ inputSchema: t.inputSchema,
196
+ })),
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Longest-lived layer TTL (seconds) for registry expiry tracking.
202
+ */
203
+ export function ttlSecondsForCache(role) {
204
+ const ttls = resolveCacheStrategy(role);
205
+ if (
206
+ ttls.tools === 'none'
207
+ && ttls.system === 'none'
208
+ && ttls.tier3 === 'none'
209
+ && ttls.messages === 'none'
210
+ ) {
211
+ return 0;
212
+ }
213
+ return Math.max(
214
+ ttlToSeconds(ttls.tools),
215
+ ttlToSeconds(ttls.system),
216
+ ttlToSeconds(ttls.tier3),
217
+ ttlToSeconds(ttls.messages),
218
+ );
219
+ }
220
+
221
+ // --- Helpers ---
222
+
223
+ function ttlToSeconds(v) {
224
+ if (v === '24h') return 86400;
225
+ if (v === '1h') return 3600;
226
+ if (v === '5m') return 300;
227
+ return 0;
228
+ }
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Smart Bridge — public API
3
+ *
4
+ * Resolution flow:
5
+ * request.role → getRoleConfig(role) (user-workflow.json)
6
+ * request.preset → presets[preset] (mixdog-config.json agent.presets)
7
+ *
8
+ * Missing role → preset comes from `request.preset` →
9
+ * userRoles[request.role] → default preset.
10
+ */
11
+
12
+ import { buildVirtualProfile } from './profiles.mjs';
13
+ import { CacheRegistry } from './registry.mjs';
14
+ import {
15
+ buildProviderCacheOpts,
16
+ computePrefixContent,
17
+ shouldMarkWarmForProvider,
18
+ shouldRecordObservedForProvider,
19
+ ttlSecondsForCache,
20
+ } from './cache-strategy.mjs';
21
+ import { getHiddenRole } from '../internal-roles.mjs';
22
+
23
+ let _sharedInstance = null;
24
+
25
+ // Plugin-managed hidden roles live in internal-roles.mjs, not
26
+ // user-workflow.json. The resolver normalises them into the same RoleConfig
27
+ // shape user-defined roles produce so every caller lands in the cache
28
+ // registry with a stable profileId — no per-call branching, no fallback
29
+ // chain in downstream code.
30
+ function _hiddenRoleConfig(role) {
31
+ const hidden = getHiddenRole(role);
32
+ if (!hidden) return null;
33
+ return {
34
+ name: role,
35
+ preset: null,
36
+ desc_path: hidden.description || null,
37
+ };
38
+ }
39
+
40
+ // Unified role resolver. Defaults to the hidden-role registry so SmartBridge
41
+ // is usable standalone before agent/init() runs; setRoleResolver() layers the
42
+ // user-workflow.json lookup on top once available. One function, one shape —
43
+ // downstream code never checks for null or picks a branch.
44
+ let _resolveRole = _hiddenRoleConfig;
45
+
46
+ /**
47
+ * Install the user-workflow role lookup. Called once by agent/index.mjs after
48
+ * the user-workflow.json cache is populated. The resulting resolver returns
49
+ * user-defined roles when present and hidden-role metadata otherwise.
50
+ */
51
+ export function setRoleResolver(fn) {
52
+ const userResolver = typeof fn === 'function' ? fn : null;
53
+ _resolveRole = userResolver
54
+ ? (role) => userResolver(role) || _hiddenRoleConfig(role)
55
+ : _hiddenRoleConfig;
56
+ }
57
+
58
+ async function _lazyGetRoleConfig(role) {
59
+ // User-workflow resolver already installed — synchronous lookup is fine.
60
+ if (_resolveRole !== _hiddenRoleConfig) return _resolveRole(role);
61
+ // Pre-init: dynamic import so standalone tests / scripts still see the
62
+ // user-workflow roles without requiring agent/init() to have run.
63
+ try {
64
+ const mod = await import('../../index.mjs');
65
+ if (typeof mod.getRoleConfig === 'function') {
66
+ setRoleResolver(mod.getRoleConfig);
67
+ return _resolveRole(role);
68
+ }
69
+ } catch { /* ignore */ }
70
+ return _hiddenRoleConfig(role);
71
+ }
72
+
73
+ function _syncGetRoleConfig(role) {
74
+ return _resolveRole(role);
75
+ }
76
+
77
+ export class SmartBridge {
78
+ constructor(opts = {}) {
79
+ this.userRoles = opts.userRoles || {};
80
+ this.presets = Array.isArray(opts.presets) ? opts.presets : [];
81
+ this.llmCall = opts.llmCall || null;
82
+ this.registry = opts.registry || CacheRegistry.shared();
83
+ }
84
+
85
+ /**
86
+ * Async resolution — used by bridge-llm and any caller that can await.
87
+ * Returns the same shape as resolveSync but falls back to the default
88
+ * preset when no role config is found.
89
+ */
90
+ async resolve(request) {
91
+ const role = request?.role || request?.taskType || null;
92
+ const roleConfig = role ? await _lazyGetRoleConfig(role) : null;
93
+ return this._finalize(roleConfig, request || {});
94
+ }
95
+
96
+ /**
97
+ * Sync variant — used by createSession and the bridge tool entry point.
98
+ * Returns null only when called before agent init has populated the
99
+ * role-config cache. Callers fall back to classic preset behaviour.
100
+ */
101
+ resolveSync(request) {
102
+ if (!request) return null;
103
+ const role = request.role || request.taskType || null;
104
+ const roleConfig = role ? _syncGetRoleConfig(role) : null;
105
+ return this._finalize(roleConfig, request);
106
+ }
107
+
108
+ _finalize(roleConfig, request) {
109
+ const profile = buildVirtualProfile(roleConfig);
110
+
111
+ let presetName = request.preset
112
+ || (request.role ? this.userRoles[request.role] : null)
113
+ || (roleConfig?.preset || null)
114
+ || null;
115
+
116
+ let preset = this._findPreset(presetName);
117
+
118
+ const provider = request.provider || preset?.provider || null;
119
+ const model = request.model || preset?.model || null;
120
+ const effort = preset?.effort || null;
121
+ const fast = preset?.fast === true;
122
+
123
+ const cacheOpts = buildProviderCacheOpts(provider, request.sessionId, request.role);
124
+
125
+ return {
126
+ profile,
127
+ preset: preset || (presetName ? { name: presetName, id: presetName } : null),
128
+ presetName,
129
+ provider,
130
+ model,
131
+ effort,
132
+ fast,
133
+ source: roleConfig ? 'role-config' : 'default',
134
+ reasoning: null,
135
+ providerCacheOpts: cacheOpts,
136
+ };
137
+ }
138
+
139
+ _findPreset(name) {
140
+ if (!name || !this.presets.length) return null;
141
+ return this.presets.find(p => p.id === name || p.name === name) || null;
142
+ }
143
+
144
+ /**
145
+ * Called after a successful send to update the cache registry. Explicit
146
+ * and key-prefix providers can mark a reusable warm shard; implicit-only
147
+ * providers record observed hit/miss metrics without reporting warm=true.
148
+ * The registry keys on the profile id (which is the role name post-refactor).
149
+ */
150
+ recordCall(profile, provider, { systemPrompt, tools, usage }) {
151
+ if (!profile) return;
152
+ const prefixContent = computePrefixContent(systemPrompt, tools);
153
+ const ttlSeconds = ttlSecondsForCache(profile.id);
154
+ const cachedTokens = usage?.cachedTokens ?? 0;
155
+ const inputTokens = usage?.inputTokens ?? usage?.promptTokens ?? 0;
156
+ if (ttlSeconds > 0 && shouldMarkWarmForProvider(provider)) {
157
+ this.registry.markWarm(profile.id, provider, prefixContent, ttlSeconds);
158
+ } else if (
159
+ ttlSeconds > 0
160
+ && shouldRecordObservedForProvider(provider)
161
+ && (cachedTokens > 0 || inputTokens > 0)
162
+ ) {
163
+ this.registry.markObserved(profile.id, provider, prefixContent, ttlSeconds);
164
+ }
165
+ if (cachedTokens > 0) {
166
+ this.registry.recordHit(profile.id, provider);
167
+ } else if (inputTokens > 0) {
168
+ this.registry.recordMiss(profile.id, provider);
169
+ }
170
+ if (this.registry.dirty) this.registry.save();
171
+ }
172
+
173
+ /**
174
+ * Called when user changes preset mapping for a role.
175
+ */
176
+ updateUserRoles(userRoles) {
177
+ this.userRoles = userRoles || {};
178
+ }
179
+
180
+ /**
181
+ * Update preset catalog — call when mixdog-config.json's agent.presets change.
182
+ */
183
+ updatePresets(presets) {
184
+ this.presets = Array.isArray(presets) ? presets : [];
185
+ }
186
+
187
+ /**
188
+ * Returns a virtual profile for a role id. Used by session manager to
189
+ * rehydrate the profile object after session reload.
190
+ */
191
+ getProfile(id) {
192
+ if (!id) return null;
193
+ const roleConfig = _syncGetRoleConfig(id);
194
+ return buildVirtualProfile(roleConfig);
195
+ }
196
+
197
+ getStats() {
198
+ return this.registry.getStats();
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Singleton accessor.
204
+ */
205
+ export function initSmartBridge(opts = {}) {
206
+ _sharedInstance = new SmartBridge(opts);
207
+ return _sharedInstance;
208
+ }
209
+
210
+ export function getSmartBridge() {
211
+ if (!_sharedInstance) {
212
+ _sharedInstance = new SmartBridge();
213
+ }
214
+ return _sharedInstance;
215
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Smart Bridge — Virtual Profile Helpers
3
+ *
4
+ * Single source of truth for role metadata is `user-workflow.json`, loaded
5
+ * via `getRoleConfig(role)` in agent/index.mjs. This module keeps a small
6
+ * helper used by callers that still think in terms of "profiles":
7
+ *
8
+ * • buildVirtualProfile(roleConfig)
9
+ * Turn a user-workflow.json role into the shape older code expected
10
+ * (`{id, taskType, permission, description}`).
11
+ *
12
+ * • ROLE_TOOLS_UNIFIED
13
+ * Every bridge caller ships the same tool surface at the cached
14
+ * prefix so the tools breakpoint stays bit-identical across roles.
15
+ * Per-role narrowing happens in the role.md injected into the first
16
+ * user turn.
17
+ */
18
+
19
+ export const ROLE_TOOLS_UNIFIED = ['full'];
20
+
21
+ /**
22
+ * Build a minimal profile-shaped object from a user-workflow.json role.
23
+ * Used by the session manager + bridge-llm to keep the existing
24
+ * `session.profileId` code paths working without introducing a second
25
+ * registry.
26
+ */
27
+ export function buildVirtualProfile(roleConfig) {
28
+ if (!roleConfig || !roleConfig.name) return null;
29
+ return {
30
+ id: roleConfig.name,
31
+ taskType: roleConfig.name,
32
+ tools: ROLE_TOOLS_UNIFIED,
33
+ permission: roleConfig.permission && roleConfig.permission !== 'full' ? roleConfig.permission : null,
34
+ fallbackPreset: roleConfig.preset || null,
35
+ description: roleConfig.desc_path || null,
36
+ };
37
+ }