@vellumai/assistant 0.6.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1346) hide show
  1. package/AGENTS.md +20 -0
  2. package/ARCHITECTURE.md +45 -36
  3. package/Dockerfile +26 -6
  4. package/README.md +8 -10
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +14 -20
  6. package/bun.lock +306 -119
  7. package/docs/architecture/memory.md +1 -90
  8. package/docs/architecture/security.md +15 -30
  9. package/docs/credential-execution-service.md +7 -5
  10. package/docs/skills.md +10 -10
  11. package/docs/stt-provider-onboarding.md +17 -45
  12. package/examples/plugins/echo/bun.lock +25 -0
  13. package/knip.json +8 -22
  14. package/node_modules/@vellumai/ces-client/bun.lock +33 -0
  15. package/node_modules/@vellumai/ces-client/package.json +25 -0
  16. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +631 -0
  17. package/node_modules/@vellumai/ces-client/src/__tests__/package-boundary.test.ts +138 -0
  18. package/node_modules/@vellumai/ces-client/src/credential-rpc.ts +13 -0
  19. package/node_modules/@vellumai/ces-client/src/http-credentials.ts +296 -0
  20. package/node_modules/@vellumai/ces-client/src/http-log-export.ts +111 -0
  21. package/node_modules/@vellumai/ces-client/src/index.ts +43 -0
  22. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +445 -0
  23. package/node_modules/@vellumai/credential-storage/src/__tests__/package-boundary.test.ts +32 -6
  24. package/node_modules/@vellumai/egress-proxy/src/__tests__/package-boundary.test.ts +32 -1
  25. package/node_modules/@vellumai/gateway-client/bun.lock +39 -0
  26. package/node_modules/@vellumai/gateway-client/package.json +23 -0
  27. package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +343 -0
  28. package/node_modules/@vellumai/gateway-client/src/__tests__/package-boundary.test.ts +140 -0
  29. package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +422 -0
  30. package/node_modules/@vellumai/gateway-client/src/index.ts +35 -0
  31. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +331 -0
  32. package/node_modules/@vellumai/gateway-client/src/types.ts +131 -0
  33. package/node_modules/@vellumai/gateway-client/tsconfig.json +20 -0
  34. package/node_modules/@vellumai/{ces-contracts → service-contracts}/bun.lock +1 -1
  35. package/node_modules/@vellumai/{ces-contracts → service-contracts}/package.json +4 -2
  36. package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/contracts.test.ts +5 -1
  37. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +155 -0
  38. package/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +23 -0
  39. package/node_modules/@vellumai/service-contracts/src/index.ts +25 -0
  40. package/node_modules/@vellumai/{ces-contracts/src/index.ts → service-contracts/src/transport.ts} +6 -28
  41. package/node_modules/@vellumai/service-contracts/src/trust-rules.ts +116 -0
  42. package/node_modules/@vellumai/service-contracts/tsconfig.json +20 -0
  43. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +891 -0
  44. package/node_modules/@vellumai/skill-host-contracts/bun.lock +24 -0
  45. package/node_modules/@vellumai/skill-host-contracts/package.json +18 -0
  46. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +91 -0
  47. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +1348 -0
  48. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +6 -0
  49. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +11 -0
  50. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +32 -0
  51. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +333 -0
  52. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +444 -0
  53. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +20 -0
  54. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +12 -0
  55. package/openapi.yaml +2855 -556
  56. package/package.json +13 -7
  57. package/scripts/check-circular-deps.ts +80 -0
  58. package/scripts/generate-openapi.ts +24 -7
  59. package/{src/memory/graph/inspect.ts → scripts/memory-inspect.ts} +27 -27
  60. package/src/__tests__/access-request-decision.test.ts +2 -11
  61. package/src/__tests__/acp-session.test.ts +4 -150
  62. package/src/__tests__/actor-token-service.test.ts +17 -678
  63. package/src/__tests__/agent-loop-callsite-precedence.test.ts +2 -6
  64. package/src/__tests__/agent-loop-override-profile.test.ts +404 -0
  65. package/src/__tests__/agent-loop-thinking.test.ts +4 -4
  66. package/src/__tests__/agent-wake-override-profile.test.ts +261 -0
  67. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -1
  68. package/src/__tests__/anthropic-provider.test.ts +127 -15
  69. package/src/__tests__/app-routes-csp.test.ts +106 -55
  70. package/src/__tests__/approval-cascade.test.ts +3 -355
  71. package/src/__tests__/approval-conversation-turn.test.ts +3 -8
  72. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
  73. package/src/__tests__/approval-primitive.test.ts +2 -1
  74. package/src/__tests__/approval-routes-http.test.ts +34 -451
  75. package/src/__tests__/assistant-events-sse-hardening.test.ts +73 -80
  76. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -3
  77. package/src/__tests__/attachment-upload-trusted-source.test.ts +139 -0
  78. package/src/__tests__/attachments-store.test.ts +46 -1
  79. package/src/__tests__/audit-log-rotation.test.ts +2 -1
  80. package/src/__tests__/auto-analysis-end-to-end.test.ts +8 -20
  81. package/src/__tests__/background-shell-bash.test.ts +227 -0
  82. package/src/__tests__/background-shell-host-bash.test.ts +474 -0
  83. package/src/__tests__/background-tool-registry.test.ts +145 -0
  84. package/src/__tests__/background-tool-routes.test.ts +175 -0
  85. package/src/__tests__/btw-routes.test.ts +147 -183
  86. package/src/__tests__/call-controller.test.ts +15 -2
  87. package/src/__tests__/call-conversation-messages.test.ts +2 -1
  88. package/src/__tests__/call-domain.test.ts +2 -2
  89. package/src/__tests__/call-pointer-messages.test.ts +11 -13
  90. package/src/__tests__/call-recovery.test.ts +2 -1
  91. package/src/__tests__/call-routes-http.test.ts +3 -14
  92. package/src/__tests__/call-store.test.ts +2 -1
  93. package/src/__tests__/cancel-resolves-conversation-key.test.ts +31 -62
  94. package/src/__tests__/canonical-guardian-store.test.ts +2 -2
  95. package/src/__tests__/catalog-files.test.ts +0 -26
  96. package/src/__tests__/ces-rpc-credential-backend.test.ts +1 -1
  97. package/src/__tests__/channel-approval-routes.test.ts +79 -49
  98. package/src/__tests__/channel-approval.test.ts +9 -7
  99. package/src/__tests__/channel-approvals.test.ts +9 -180
  100. package/src/__tests__/channel-delivery-store.test.ts +11 -10
  101. package/src/__tests__/channel-guardian.test.ts +14 -25
  102. package/src/__tests__/channel-readiness-service.test.ts +8 -6
  103. package/src/__tests__/channel-reply-delivery.test.ts +3 -19
  104. package/src/__tests__/channel-retry-sweep.test.ts +2 -5
  105. package/src/__tests__/checker.test.ts +274 -3921
  106. package/src/__tests__/circuit-breaker-pipeline.test.ts +1 -1
  107. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +208 -0
  108. package/src/__tests__/cli.test.ts +1 -38
  109. package/src/__tests__/compaction-events.test.ts +0 -1
  110. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  111. package/src/__tests__/compaction-strip-metadata-clear.test.ts +2 -2
  112. package/src/__tests__/compaction-timeout-recovery.test.ts +1 -1
  113. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -7
  114. package/src/__tests__/config-model-image-provider.test.ts +0 -1
  115. package/src/__tests__/config-schema-cmd.test.ts +1 -1
  116. package/src/__tests__/config-schema.test.ts +30 -221
  117. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +4 -25
  118. package/src/__tests__/contact-store-user-file.test.ts +2 -1
  119. package/src/__tests__/contacts-tools.test.ts +56 -29
  120. package/src/__tests__/contacts-write.test.ts +6 -61
  121. package/src/__tests__/context-search-agent-protocol.test.ts +230 -0
  122. package/src/__tests__/context-search-agent-runner.test.ts +998 -0
  123. package/src/__tests__/context-search-conversations-source.test.ts +320 -0
  124. package/src/__tests__/context-search-fanout.test.ts +380 -0
  125. package/src/__tests__/context-search-memory-source.test.ts +311 -0
  126. package/src/__tests__/context-search-pkb-source.test.ts +444 -0
  127. package/src/__tests__/context-search-types.test.ts +95 -0
  128. package/src/__tests__/context-search-workspace-source.test.ts +545 -0
  129. package/src/__tests__/context-window-manager.test.ts +25 -0
  130. package/src/__tests__/conversation-abort-tool-results.test.ts +10 -1
  131. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +631 -0
  132. package/src/__tests__/conversation-agent-loop-overflow.test.ts +15 -2
  133. package/src/__tests__/conversation-agent-loop.test.ts +24 -2
  134. package/src/__tests__/conversation-analysis-routes.test.ts +60 -82
  135. package/src/__tests__/conversation-attachments.test.ts +9 -20
  136. package/src/__tests__/conversation-attention-store.test.ts +2 -1
  137. package/src/__tests__/conversation-attention-telegram.test.ts +4 -2
  138. package/src/__tests__/conversation-clear-safety.test.ts +53 -95
  139. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -39
  140. package/src/__tests__/conversation-crud-inference-profile.test.ts +54 -0
  141. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +63 -157
  142. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  143. package/src/__tests__/conversation-disk-view.test.ts +5 -4
  144. package/src/__tests__/conversation-fork-crud.test.ts +26 -55
  145. package/src/__tests__/conversation-fork-route.test.ts +5 -74
  146. package/src/__tests__/conversation-inference-profile-list.test.ts +128 -0
  147. package/src/__tests__/conversation-inference-profile-route.test.ts +216 -0
  148. package/src/__tests__/conversation-init.benchmark.test.ts +4 -81
  149. package/src/__tests__/conversation-key-store-disk-view.test.ts +2 -1
  150. package/src/__tests__/conversation-lifecycle.test.ts +0 -1
  151. package/src/__tests__/conversation-list-source.test.ts +2 -2
  152. package/src/__tests__/conversation-load-history-repair.test.ts +0 -1
  153. package/src/__tests__/conversation-pairing.test.ts +0 -1
  154. package/src/__tests__/conversation-pre-run-repair.test.ts +137 -297
  155. package/src/__tests__/conversation-process-callsite.test.ts +0 -1
  156. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -1
  157. package/src/__tests__/conversation-queue.test.ts +1 -33
  158. package/src/__tests__/conversation-routes-disk-view.test.ts +124 -97
  159. package/src/__tests__/conversation-routes-guardian-reply.test.ts +80 -55
  160. package/src/__tests__/conversation-routes-slash-commands.test.ts +83 -12
  161. package/src/__tests__/conversation-runtime-assembly.test.ts +41 -84
  162. package/src/__tests__/conversation-slash-commands.test.ts +6 -43
  163. package/src/__tests__/conversation-slash-queue.test.ts +0 -1
  164. package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
  165. package/src/__tests__/conversation-speed-override.test.ts +0 -1
  166. package/src/__tests__/conversation-starter-routes.test.ts +177 -55
  167. package/src/__tests__/conversation-starters-cadence.test.ts +2 -2
  168. package/src/__tests__/conversation-store.test.ts +2 -375
  169. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
  170. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +6 -6
  171. package/src/__tests__/conversation-unread-route.test.ts +1 -1
  172. package/src/__tests__/conversation-usage.test.ts +2 -1
  173. package/src/__tests__/conversation-wipe.test.ts +2 -103
  174. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -1
  175. package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
  176. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
  177. package/src/__tests__/conversations-defer-cli.test.ts +150 -0
  178. package/src/__tests__/credential-execution-admin-cli.test.ts +1 -1
  179. package/src/__tests__/credential-execution-api-key-propagation.test.ts +2 -2
  180. package/src/__tests__/credential-execution-approval-bridge.test.ts +22 -289
  181. package/src/__tests__/credential-execution-client.test.ts +1 -1
  182. package/src/__tests__/credential-execution-managed-contract.test.ts +1 -1
  183. package/src/__tests__/credential-security-invariants.test.ts +14 -0
  184. package/src/__tests__/credentials-cli.test.ts +45 -21
  185. package/src/__tests__/daemon-credential-client.test.ts +23 -108
  186. package/src/__tests__/db-acp-history.test.ts +284 -0
  187. package/src/__tests__/db-activation-state.test.ts +240 -0
  188. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +2 -1
  189. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +248 -0
  190. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +2 -1
  191. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +116 -0
  192. package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +132 -0
  193. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  194. package/src/__tests__/delete-propagation.test.ts +3 -2
  195. package/src/__tests__/deterministic-verification-control-plane.test.ts +39 -32
  196. package/src/__tests__/dm-backfill.test.ts +3 -2
  197. package/src/__tests__/edit-propagation.test.ts +5 -7
  198. package/src/__tests__/embedding-managed-proxy-selection.test.ts +1 -1
  199. package/src/__tests__/empty-response-pipeline.test.ts +1 -1
  200. package/src/__tests__/events-client-registration.test.ts +297 -0
  201. package/src/__tests__/file-write-tool.test.ts +2 -4
  202. package/src/__tests__/filing-service.test.ts +144 -17
  203. package/src/__tests__/followup-tools.test.ts +2 -1
  204. package/src/__tests__/gateway-client-managed-outbound.test.ts +8 -12
  205. package/src/__tests__/gateway-only-enforcement.test.ts +2 -6
  206. package/src/__tests__/gateway-only-guard.test.ts +4 -3
  207. package/src/__tests__/gemini-provider.test.ts +276 -10
  208. package/src/__tests__/graph-extraction-event-date.test.ts +30 -0
  209. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -1
  210. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -2
  211. package/src/__tests__/guardian-action-followup-store.test.ts +2 -1
  212. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +9 -9
  213. package/src/__tests__/guardian-action-late-reply.test.ts +2 -1
  214. package/src/__tests__/guardian-action-store.test.ts +2 -1
  215. package/src/__tests__/guardian-action-sweep.test.ts +9 -8
  216. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -1
  217. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +21 -118
  218. package/src/__tests__/guardian-dispatch.test.ts +14 -11
  219. package/src/__tests__/guardian-grant-minting.test.ts +9 -15
  220. package/src/__tests__/guardian-outbound-http.test.ts +71 -106
  221. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -2
  222. package/src/__tests__/guardian-routing-invariants.test.ts +34 -90
  223. package/src/__tests__/guardian-routing-state.test.ts +14 -22
  224. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -2
  225. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +253 -0
  226. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +8 -4
  227. package/src/__tests__/heartbeat-service.test.ts +39 -21
  228. package/src/__tests__/helpers/call-route-handler.ts +72 -0
  229. package/src/__tests__/helpers/channel-test-adapter.ts +161 -0
  230. package/src/__tests__/helpers/gateway-classify-mock.ts +67 -0
  231. package/src/__tests__/helpers/mock-logger.ts +36 -0
  232. package/src/__tests__/history-repair-pipeline.test.ts +1 -1
  233. package/src/__tests__/home-state-routes.test.ts +10 -31
  234. package/src/__tests__/host-browser-e2e-cloud.test.ts +2 -1
  235. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +12 -2
  236. package/src/__tests__/host-browser-routes.test.ts +36 -91
  237. package/src/__tests__/host-browser-ws-events-e2e.test.ts +10 -2
  238. package/src/__tests__/host-proxy-interface.test.ts +3 -3
  239. package/src/__tests__/host-shell-tool.test.ts +2 -4
  240. package/src/__tests__/host-transfer-pending-interactions.test.ts +160 -0
  241. package/src/__tests__/host-transfer-proxy.test.ts +733 -0
  242. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  243. package/src/__tests__/http-user-message-parity.test.ts +20 -11
  244. package/src/__tests__/inbound-invite-redemption.test.ts +3 -2
  245. package/src/__tests__/injector-chain.test.ts +16 -17
  246. package/src/__tests__/inline-skill-load-permissions.test.ts +41 -206
  247. package/src/__tests__/install-skill-routing.test.ts +1 -1
  248. package/src/__tests__/invite-redemption-service.test.ts +2 -1
  249. package/src/__tests__/invite-routes-http.test.ts +80 -12
  250. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -1
  251. package/src/__tests__/jobs-store-upsert-debounced.test.ts +2 -1
  252. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +157 -0
  253. package/src/__tests__/list-messages-attachments.test.ts +52 -55
  254. package/src/__tests__/list-messages-page-latest.test.ts +283 -0
  255. package/src/__tests__/list-messages-tool-merge.test.ts +16 -17
  256. package/src/__tests__/llm-call-pipeline.test.ts +7 -8
  257. package/src/__tests__/llm-context-normalization.test.ts +69 -4
  258. package/src/__tests__/llm-context-route-provider.test.ts +39 -113
  259. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -1
  260. package/src/__tests__/llm-resolver.test.ts +211 -0
  261. package/src/__tests__/llm-schema.test.ts +57 -1
  262. package/src/__tests__/llm-usage-store.test.ts +2 -1
  263. package/src/__tests__/log-export-workspace.test.ts +28 -17
  264. package/src/__tests__/mcp-abort-signal.test.ts +2 -3
  265. package/src/__tests__/mcp-client-auth.test.ts +2 -3
  266. package/src/__tests__/memory-admin-recall.test.ts +221 -0
  267. package/src/__tests__/memory-recall-log-store.test.ts +2 -1
  268. package/src/__tests__/memory-retrieval-pipeline.test.ts +6 -8
  269. package/src/__tests__/memory-upsert-concurrency.test.ts +2 -1
  270. package/src/__tests__/migration-cross-version-compatibility.test.ts +14 -13
  271. package/src/__tests__/migration-export-http.test.ts +17 -17
  272. package/src/__tests__/migration-export-to-gcs.test.ts +491 -0
  273. package/src/__tests__/migration-import-commit-http.test.ts +16 -16
  274. package/src/__tests__/migration-import-from-gcs.test.ts +533 -0
  275. package/src/__tests__/migration-import-from-url.test.ts +16 -23
  276. package/src/__tests__/migration-import-preflight-http.test.ts +13 -13
  277. package/src/__tests__/migration-jobs-status.test.ts +164 -0
  278. package/src/__tests__/migration-validate-http.test.ts +48 -83
  279. package/src/__tests__/mock-gateway-ipc.ts +32 -62
  280. package/src/__tests__/model-intents.test.ts +15 -2
  281. package/src/__tests__/nl-approval-parser.test.ts +13 -17
  282. package/src/__tests__/non-member-access-request.test.ts +13 -5
  283. package/src/__tests__/notification-guardian-path.test.ts +15 -8
  284. package/src/__tests__/notification-schedule-notify-dedup.test.ts +2 -1
  285. package/src/__tests__/notification-telegram-adapter.test.ts +57 -55
  286. package/src/__tests__/oauth-apps-routes.test.ts +76 -122
  287. package/src/__tests__/oauth-cli.test.ts +14 -1
  288. package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
  289. package/src/__tests__/oauth-provider-visibility.test.ts +3 -1
  290. package/src/__tests__/oauth-providers-routes.test.ts +78 -101
  291. package/src/__tests__/oauth-store.test.ts +3 -1
  292. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -3
  293. package/src/__tests__/openai-provider.test.ts +105 -6
  294. package/src/__tests__/openai-responses-provider.test.ts +146 -4
  295. package/src/__tests__/openrouter-provider-only.test.ts +22 -4
  296. package/src/__tests__/overflow-reduce-pipeline.test.ts +4 -9
  297. package/src/__tests__/permission-types.test.ts +3 -18
  298. package/src/__tests__/persistence-pipeline.test.ts +3 -2
  299. package/src/__tests__/pipeline-runner.test.ts +1 -1
  300. package/src/__tests__/platform-bash-auto-approve.test.ts +27 -20
  301. package/src/__tests__/platform.test.ts +11 -63
  302. package/src/__tests__/playbook-execution.test.ts +2 -1
  303. package/src/__tests__/playbook-tools.test.ts +2 -1
  304. package/src/__tests__/plugin-bootstrap.test.ts +51 -5
  305. package/src/__tests__/plugin-registry.test.ts +30 -0
  306. package/src/__tests__/plugin-route-contribution.test.ts +17 -11
  307. package/src/__tests__/plugin-skill-contribution.test.ts +3 -3
  308. package/src/__tests__/plugin-tool-contribution.test.ts +10 -4
  309. package/src/__tests__/plugin-types.test.ts +1 -1
  310. package/src/__tests__/pricing.test.ts +151 -2
  311. package/src/__tests__/profiler-routes.test.ts +112 -177
  312. package/src/__tests__/provider-send-message-override-profile.test.ts +223 -0
  313. package/src/__tests__/proxy-approval-callback.test.ts +6 -554
  314. package/src/__tests__/qdrant-collection-migration.test.ts +7 -7
  315. package/src/__tests__/reaction-persistence.test.ts +3 -2
  316. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  317. package/src/__tests__/recording-handler.test.ts +0 -2
  318. package/src/__tests__/registry.test.ts +1 -0
  319. package/src/__tests__/relay-server.test.ts +19 -4
  320. package/src/__tests__/require-fresh-approval.test.ts +19 -168
  321. package/src/__tests__/resolve-trust-class.test.ts +2 -1
  322. package/src/__tests__/retry-thinking-tool-choice.test.ts +19 -7
  323. package/src/__tests__/retry-verbosity-normalization.test.ts +139 -0
  324. package/src/__tests__/runtime-attachment-metadata.test.ts +26 -6
  325. package/src/__tests__/runtime-events-sse-parity.test.ts +12 -13
  326. package/src/__tests__/runtime-events-sse.test.ts +13 -21
  327. package/src/__tests__/schedule-routes.test.ts +226 -129
  328. package/src/__tests__/schedule-store.test.ts +119 -1
  329. package/src/__tests__/schedule-tools.test.ts +2 -1
  330. package/src/__tests__/scheduler-recurrence.test.ts +2 -1
  331. package/src/__tests__/scheduler-reuse-conversation.test.ts +2 -1
  332. package/src/__tests__/scheduler-wake.test.ts +356 -0
  333. package/src/__tests__/scoped-approval-grants.test.ts +2 -1
  334. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -1
  335. package/src/__tests__/secret-detection-handler.test.ts +2 -9
  336. package/src/__tests__/secret-ingress-http.test.ts +38 -21
  337. package/src/__tests__/secret-routes-managed-proxy.test.ts +46 -102
  338. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  339. package/src/__tests__/send-endpoint-busy.test.ts +38 -25
  340. package/src/__tests__/sequence-store.test.ts +2 -1
  341. package/src/__tests__/server-history-render.test.ts +2 -2
  342. package/src/__tests__/service-contracts-import-guard.test.ts +185 -0
  343. package/src/__tests__/set-permission-mode.test.ts +0 -10
  344. package/src/__tests__/settings-routes.test.ts +35 -68
  345. package/src/__tests__/skill-boundary-guard.test.ts +105 -0
  346. package/src/__tests__/skill-load-inline-command.test.ts +2 -2
  347. package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
  348. package/src/__tests__/skill-runtime-path.test.ts +64 -0
  349. package/src/__tests__/skills-file-content-endpoint.test.ts +0 -2
  350. package/src/__tests__/slack-inbound-verification.test.ts +11 -2
  351. package/src/__tests__/slack-messaging-token-resolution.test.ts +1 -3
  352. package/src/__tests__/slack-reaction-approvals.test.ts +4 -4
  353. package/src/__tests__/slack-share-routes.test.ts +37 -72
  354. package/src/__tests__/subagent-call-site-routing.test.ts +79 -0
  355. package/src/__tests__/subagent-fork-spawn.test.ts +20 -28
  356. package/src/__tests__/subagent-notify-parent.test.ts +6 -29
  357. package/src/__tests__/subagent-role-registry.test.ts +3 -3
  358. package/src/__tests__/subagent-spawn-tool-fork.test.ts +52 -104
  359. package/src/__tests__/subagent-tools.test.ts +0 -1
  360. package/src/__tests__/suggestion-routes.test.ts +55 -62
  361. package/src/__tests__/task-compiler.test.ts +2 -1
  362. package/src/__tests__/task-management-tools.test.ts +2 -1
  363. package/src/__tests__/task-memory-cleanup.test.ts +2 -1
  364. package/src/__tests__/task-scheduler.test.ts +2 -1
  365. package/src/__tests__/telegram-config.test.ts +0 -1
  366. package/src/__tests__/terminal-tools.test.ts +5 -314
  367. package/src/__tests__/test-preload.ts +0 -11
  368. package/src/__tests__/thread-backfill.test.ts +3 -2
  369. package/src/__tests__/token-estimate-pipeline.test.ts +68 -15
  370. package/src/__tests__/tool-approval-handler.test.ts +21 -63
  371. package/src/__tests__/tool-audit-listener.test.ts +3 -3
  372. package/src/__tests__/tool-domain-event-publisher.test.ts +3 -3
  373. package/src/__tests__/tool-error-pipeline.test.ts +6 -6
  374. package/src/__tests__/tool-execute-pipeline.test.ts +6 -8
  375. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +64 -1
  376. package/src/__tests__/tool-executor-lifecycle-events.test.ts +28 -56
  377. package/src/__tests__/tool-executor.test.ts +322 -1633
  378. package/src/__tests__/tool-grant-request-escalation.test.ts +90 -311
  379. package/src/__tests__/tool-result-truncate-pipeline.test.ts +1 -1
  380. package/src/__tests__/trust-context-guards.test.ts +1 -1
  381. package/src/__tests__/trusted-contact-approval-notifier.test.ts +7 -15
  382. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +178 -354
  383. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +3 -2
  384. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -2
  385. package/src/__tests__/trusted-contact-verification.test.ts +2 -1
  386. package/src/__tests__/turn-boundary-resolution.test.ts +2 -1
  387. package/src/__tests__/twilio-routes.test.ts +25 -66
  388. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -7
  389. package/src/__tests__/usage-routes.test.ts +73 -90
  390. package/src/__tests__/user-plugin-loader.test.ts +54 -12
  391. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -2
  392. package/src/__tests__/verification-control-plane-policy.test.ts +95 -14
  393. package/src/__tests__/voice-ingress-preflight.test.ts +5 -5
  394. package/src/__tests__/voice-invite-redemption.test.ts +2 -1
  395. package/src/__tests__/voice-scoped-grant-consumer.test.ts +3 -3
  396. package/src/__tests__/voice-session-bridge.test.ts +285 -106
  397. package/src/__tests__/volume-security-guard.test.ts +0 -2
  398. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -1
  399. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +3 -1
  400. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +2 -1
  401. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +1 -1
  402. package/src/__tests__/workspace-migration-052-seed-default-inference-profiles.test.ts +260 -0
  403. package/src/__tests__/workspace-migration-053-release-notes-acp-codex.test.ts +225 -0
  404. package/src/__tests__/workspace-migration-054-seed-recall-callsite.test.ts +235 -0
  405. package/src/__tests__/workspace-migration-055-release-notes-agentic-recall.test.ts +128 -0
  406. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +232 -0
  407. package/src/__tests__/workspace-migration-acp-sessions-ui.test.ts +144 -0
  408. package/src/__tests__/workspace-migration-drop-user-md.test.ts +1 -1
  409. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +274 -0
  410. package/src/acp/__tests__/client-handler.test.ts +64 -0
  411. package/src/acp/__tests__/helpers/acp-config-stub.ts +62 -0
  412. package/src/acp/__tests__/helpers/which-stub.ts +45 -0
  413. package/src/acp/__tests__/session-manager-persistence.test.ts +366 -0
  414. package/src/acp/__tests__/session-manager-startup.test.ts +159 -0
  415. package/src/acp/__tests__/session-manager.test.ts +83 -0
  416. package/src/acp/client-handler.ts +23 -139
  417. package/src/acp/resolve-agent.test.ts +291 -0
  418. package/src/acp/resolve-agent.ts +176 -0
  419. package/src/acp/session-manager.ts +166 -7
  420. package/src/acp/types.ts +2 -50
  421. package/src/agent/loop.ts +37 -14
  422. package/src/agent/message-types.ts +0 -2
  423. package/src/approvals/AGENTS.md +1 -1
  424. package/src/approvals/__tests__/guardian-feed-event.test.ts +1 -9
  425. package/src/approvals/approval-primitive.ts +3 -20
  426. package/src/approvals/guardian-decision-primitive.ts +37 -68
  427. package/src/approvals/guardian-request-resolvers.ts +29 -103
  428. package/src/avatar/character-components.ts +6 -6
  429. package/src/{config/bundled-skills/settings/tools → avatar}/identity-avatar.ts +1 -1
  430. package/src/backup/__tests__/backup-worker.test.ts +0 -2
  431. package/src/backup/__tests__/paths.test.ts +3 -2
  432. package/src/backup/backup-worker.ts +1 -10
  433. package/src/backup/paths.ts +2 -18
  434. package/src/backup/restore.ts +7 -11
  435. package/src/browser/__tests__/operations.test.ts +0 -35
  436. package/src/browser/operations.ts +1 -47
  437. package/src/bundler/package-resolver.ts +2 -6
  438. package/src/calls/active-call-lease.ts +1 -1
  439. package/src/calls/call-constants.ts +1 -1
  440. package/src/calls/call-controller.ts +1 -5
  441. package/src/calls/call-domain.ts +14 -14
  442. package/src/calls/call-pointer-messages.ts +4 -9
  443. package/src/calls/call-store.ts +2 -1
  444. package/src/calls/guardian-action-sweep.ts +9 -25
  445. package/src/calls/guardian-dispatch.ts +1 -20
  446. package/src/calls/media-stream-audio-transcode.ts +2 -41
  447. package/src/calls/media-stream-server.ts +2 -3
  448. package/src/calls/media-stream-stt-session.ts +1 -3
  449. package/src/calls/relay-access-wait.ts +5 -8
  450. package/src/calls/relay-server.ts +15 -18
  451. package/src/calls/relay-setup-router.ts +2 -2
  452. package/src/calls/relay-verification.ts +4 -4
  453. package/src/calls/twilio-rest.ts +1 -1
  454. package/src/calls/twilio-routes.ts +160 -78
  455. package/src/calls/voice-control-protocol.ts +10 -10
  456. package/src/calls/voice-ingress-preflight.ts +2 -2
  457. package/src/calls/voice-session-bridge.ts +137 -42
  458. package/src/channels/__tests__/types.test.ts +25 -3
  459. package/src/channels/permission-profiles.ts +2 -72
  460. package/src/channels/types.ts +42 -26
  461. package/src/cli/AGENTS.md +1 -0
  462. package/src/cli/__tests__/notifications.test.ts +12 -10
  463. package/src/cli/commands/__tests__/attachment.test.ts +14 -8
  464. package/src/cli/commands/__tests__/backup.test.ts +3 -14
  465. package/src/cli/commands/__tests__/browser.test.ts +36 -31
  466. package/src/cli/commands/__tests__/cache.test.ts +23 -18
  467. package/src/cli/commands/__tests__/memory-v2.test.ts +396 -0
  468. package/src/cli/commands/__tests__/task.test.ts +36 -35
  469. package/src/cli/commands/__tests__/trust.test.ts +602 -0
  470. package/src/cli/commands/__tests__/ui-confirm.test.ts +14 -14
  471. package/src/cli/commands/__tests__/ui.test.ts +17 -17
  472. package/src/cli/commands/__tests__/watchers.test.ts +29 -29
  473. package/src/cli/commands/__tests__/webhooks.test.ts +544 -0
  474. package/src/cli/commands/attachment.ts +12 -8
  475. package/src/cli/commands/auth.ts +1 -1
  476. package/src/cli/commands/avatar.ts +192 -9
  477. package/src/cli/commands/backup.ts +14 -44
  478. package/src/cli/commands/browser.ts +52 -4
  479. package/src/cli/commands/cache.ts +7 -5
  480. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  481. package/src/cli/commands/clients.ts +11 -12
  482. package/src/cli/commands/completions.ts +1 -1
  483. package/src/cli/commands/contacts.ts +10 -10
  484. package/src/cli/commands/conversations-defer.ts +364 -0
  485. package/src/cli/commands/conversations-import.ts +2 -3
  486. package/src/cli/commands/conversations.ts +63 -53
  487. package/src/cli/commands/credential-execution.ts +1 -1
  488. package/src/cli/commands/credentials.ts +139 -5
  489. package/src/cli/commands/default-action.ts +1 -1
  490. package/src/cli/commands/domain.ts +2 -2
  491. package/src/cli/commands/email.ts +7 -7
  492. package/src/cli/commands/image-generation.ts +1 -1
  493. package/src/cli/commands/keys.ts +2 -2
  494. package/src/cli/commands/mcp.ts +1 -1
  495. package/src/cli/commands/memory-v2.ts +343 -0
  496. package/src/cli/commands/memory.ts +8 -8
  497. package/src/cli/commands/notifications.ts +21 -20
  498. package/src/cli/commands/oauth/__tests__/connect.test.ts +23 -5
  499. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +1 -1
  500. package/src/cli/commands/oauth/__tests__/mode.test.ts +1 -1
  501. package/src/cli/commands/oauth/__tests__/status.test.ts +1 -1
  502. package/src/cli/commands/oauth/__tests__/token.test.ts +1 -1
  503. package/src/cli/commands/oauth/connect.ts +2 -2
  504. package/src/cli/commands/oauth/shared.ts +29 -2
  505. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -6
  506. package/src/cli/commands/platform/__tests__/connect.test.ts +23 -11
  507. package/src/cli/commands/platform/__tests__/disconnect.test.ts +22 -10
  508. package/src/cli/commands/platform/__tests__/status.test.ts +22 -10
  509. package/src/cli/commands/platform/connect.ts +3 -3
  510. package/src/cli/commands/platform/disconnect.ts +4 -6
  511. package/src/cli/commands/platform/index.ts +12 -10
  512. package/src/cli/commands/routes.ts +7 -1
  513. package/src/cli/commands/sequence.ts +7 -7
  514. package/src/cli/commands/skills.ts +188 -82
  515. package/src/cli/commands/task.ts +12 -10
  516. package/src/cli/commands/trust.ts +460 -162
  517. package/src/cli/commands/ui.ts +3 -3
  518. package/src/cli/commands/usage.ts +10 -5
  519. package/src/cli/commands/watchers.ts +8 -8
  520. package/src/cli/commands/webhooks.ts +270 -0
  521. package/src/cli/lib/daemon-avatar-client.ts +37 -0
  522. package/src/cli/lib/daemon-credential-client.ts +27 -189
  523. package/src/cli/lib/ipc-params.ts +22 -0
  524. package/src/cli/program.ts +4 -0
  525. package/src/cli.ts +1 -61
  526. package/src/config/acp-defaults.test.ts +57 -0
  527. package/src/config/acp-defaults.ts +40 -0
  528. package/src/config/acp-schema.ts +1 -1
  529. package/src/config/assistant-feature-flags.ts +18 -142
  530. package/src/config/bundled-skills/acp/SKILL.md +44 -16
  531. package/src/config/bundled-skills/acp/TOOLS.json +45 -1
  532. package/src/config/bundled-skills/acp/tools/acp-list-agents.ts +12 -0
  533. package/src/config/bundled-skills/acp/tools/acp-steer.ts +12 -0
  534. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +14 -14
  535. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -4
  536. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +11 -6
  537. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +6 -6
  538. package/src/config/bundled-skills/media-processing/services/reduce.ts +0 -13
  539. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +1 -1
  540. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
  541. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -1
  542. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +1 -1
  543. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -1
  544. package/src/config/bundled-skills/settings/SKILL.md +2 -17
  545. package/src/config/bundled-skills/settings/TOOLS.json +0 -56
  546. package/src/config/bundled-skills/subagent/SKILL.md +2 -0
  547. package/src/config/bundled-tool-registry.ts +4 -6
  548. package/src/config/env.ts +7 -8
  549. package/src/config/feature-flag-registry.json +16 -24
  550. package/src/config/llm-resolver.ts +51 -33
  551. package/src/config/loader.ts +12 -15
  552. package/src/config/schema.ts +5 -72
  553. package/src/config/schemas/__tests__/filing.test.ts +58 -0
  554. package/src/config/schemas/__tests__/memory-v2.test.ts +186 -0
  555. package/src/config/schemas/filing.ts +12 -0
  556. package/src/config/schemas/host-browser.ts +2 -2
  557. package/src/config/schemas/inference.ts +0 -2
  558. package/src/config/schemas/ingress.ts +1 -1
  559. package/src/config/schemas/llm.ts +51 -9
  560. package/src/config/schemas/memory-storage.ts +1 -1
  561. package/src/config/schemas/memory-v2.ts +176 -0
  562. package/src/config/schemas/memory.ts +2 -0
  563. package/src/config/schemas/security.ts +0 -60
  564. package/src/config/schemas/services.ts +46 -7
  565. package/src/config/skills.ts +1 -1
  566. package/src/config/types.ts +0 -41
  567. package/src/contacts/contact-store.ts +2 -2
  568. package/src/contacts/contacts-write.ts +0 -38
  569. package/src/contacts/types.ts +8 -10
  570. package/src/context/token-estimator.ts +1 -1
  571. package/src/context/tool-result-truncation.ts +1 -1
  572. package/src/context/window-manager.ts +1 -1
  573. package/src/credential-execution/approval-bridge.ts +7 -69
  574. package/src/credential-execution/client.ts +17 -422
  575. package/src/credential-execution/feature-gates.ts +1 -2
  576. package/src/credential-execution/managed-catalog.ts +1 -1
  577. package/src/credential-health/credential-health-service.ts +1 -1
  578. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -13
  579. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
  580. package/src/daemon/__tests__/daemon-skill-host.test.ts +272 -0
  581. package/src/daemon/__tests__/meet-host-supervisor.test.ts +587 -0
  582. package/src/daemon/__tests__/meet-manifest-loader.test.ts +463 -0
  583. package/src/daemon/approval-generators.ts +2 -14
  584. package/src/daemon/classifier.ts +0 -106
  585. package/src/daemon/config-watcher.ts +14 -54
  586. package/src/daemon/connection-policy.ts +0 -14
  587. package/src/daemon/conversation-agent-loop-handlers.ts +37 -6
  588. package/src/daemon/conversation-agent-loop.ts +164 -53
  589. package/src/daemon/conversation-attachments.ts +5 -81
  590. package/src/daemon/conversation-error.ts +9 -5
  591. package/src/daemon/conversation-history.ts +1 -1
  592. package/src/daemon/conversation-launch.ts +1 -1
  593. package/src/daemon/conversation-messaging.ts +1 -1
  594. package/src/daemon/conversation-notifiers.ts +1 -1
  595. package/src/daemon/conversation-process.ts +9 -13
  596. package/src/daemon/conversation-runtime-assembly.ts +26 -88
  597. package/src/daemon/conversation-slash.ts +4 -160
  598. package/src/daemon/conversation-store.ts +368 -0
  599. package/src/daemon/conversation-surfaces.ts +5 -4
  600. package/src/daemon/conversation-tool-setup.ts +23 -172
  601. package/src/daemon/conversation.ts +46 -182
  602. package/src/daemon/daemon-control.ts +3 -3
  603. package/src/daemon/daemon-skill-host.ts +262 -0
  604. package/src/daemon/external-plugins-bootstrap.ts +67 -13
  605. package/src/daemon/handlers/config-channels.ts +2 -2
  606. package/src/daemon/handlers/config-embeddings.ts +1 -1
  607. package/src/daemon/handlers/config-ingress.ts +24 -2
  608. package/src/daemon/handlers/config-model.test.ts +17 -0
  609. package/src/daemon/handlers/config-model.ts +7 -52
  610. package/src/daemon/handlers/config-telegram.ts +6 -53
  611. package/src/daemon/handlers/config-voice.ts +1 -1
  612. package/src/daemon/handlers/conversations.ts +22 -156
  613. package/src/daemon/handlers/recording.ts +1 -1
  614. package/src/daemon/handlers/shared.ts +34 -35
  615. package/src/daemon/handlers/skills.ts +15 -23
  616. package/src/daemon/host-transfer-proxy.ts +500 -0
  617. package/src/daemon/lifecycle.ts +23 -258
  618. package/src/daemon/meet-host-startup.ts +51 -0
  619. package/src/daemon/meet-host-supervisor.ts +781 -0
  620. package/src/daemon/meet-manifest-loader.ts +410 -0
  621. package/src/daemon/memory-v2-startup.ts +35 -0
  622. package/src/daemon/message-protocol.ts +4 -7
  623. package/src/daemon/message-types/acp.ts +1 -0
  624. package/src/daemon/message-types/conversations.ts +16 -2
  625. package/src/daemon/message-types/host-transfer.ts +41 -0
  626. package/src/daemon/message-types/integrations.ts +6 -0
  627. package/src/daemon/message-types/messages.ts +14 -14
  628. package/src/daemon/message-types/schedules.ts +1 -0
  629. package/src/daemon/message-types/settings.ts +0 -6
  630. package/src/daemon/message-types/shared.ts +5 -2
  631. package/src/daemon/message-types/subagents.ts +2 -1
  632. package/src/daemon/message-types/workspace.ts +0 -2
  633. package/src/daemon/pkb-reminder-builder.test.ts +13 -12
  634. package/src/daemon/pkb-reminder-builder.ts +8 -16
  635. package/src/daemon/process-message.ts +616 -0
  636. package/src/daemon/providers-setup.ts +14 -6
  637. package/src/daemon/server.ts +79 -1274
  638. package/src/daemon/shutdown-handlers.ts +1 -1
  639. package/src/daemon/startup-error.ts +1 -1
  640. package/src/daemon/trust-context.ts +32 -0
  641. package/src/daemon/wake-target-adapter.ts +223 -0
  642. package/src/email/feature-gate.ts +1 -1
  643. package/src/events/domain-events.ts +1 -8
  644. package/src/events/tool-audit-listener.ts +2 -8
  645. package/src/events/tool-metrics-listener.ts +1 -4
  646. package/src/filing/filing-service.ts +194 -54
  647. package/src/followups/followup-store.ts +3 -71
  648. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +89 -21
  649. package/src/heartbeat/heartbeat-service.ts +32 -11
  650. package/src/home/__tests__/phase5-exit-criteria.test.ts +18 -1
  651. package/src/home/__tests__/rollup-producer.test.ts +67 -2
  652. package/src/home/assistant-feed-authoring.ts +8 -1
  653. package/src/home/feed-types.ts +1 -1
  654. package/src/home/relationship-state-writer.ts +1 -1
  655. package/src/home/rewrite-feed-title.ts +58 -0
  656. package/src/home/rollup-producer.ts +16 -3
  657. package/src/inbound/platform-callback-registration.ts +1 -17
  658. package/src/ipc/__tests__/attachment-ipc.test.ts +128 -66
  659. package/src/ipc/__tests__/browser-ipc.test.ts +75 -51
  660. package/src/ipc/__tests__/cache-ipc.test.ts +52 -107
  661. package/src/ipc/__tests__/cli-ipc.test.ts +9 -6
  662. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +254 -0
  663. package/src/ipc/__tests__/skill-server.test.ts +182 -0
  664. package/src/ipc/__tests__/socket-path.test.ts +69 -23
  665. package/src/ipc/__tests__/ui-request-route.test.ts +241 -216
  666. package/src/ipc/__tests__/watcher-ipc.test.ts +33 -33
  667. package/src/ipc/assistant-server.ts +450 -0
  668. package/src/ipc/cli-client.ts +3 -3
  669. package/src/ipc/gateway-client.test.ts +131 -0
  670. package/src/ipc/gateway-client.ts +98 -123
  671. package/src/ipc/ipc-framing.ts +281 -0
  672. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +152 -0
  673. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +219 -0
  674. package/src/ipc/routes/db-proxy.ts +73 -0
  675. package/src/ipc/routes/route-adapter.ts +32 -0
  676. package/src/ipc/routes/trust-rules.test.ts +218 -0
  677. package/src/ipc/skill-ipc-types.ts +13 -0
  678. package/src/ipc/skill-routes/__tests__/config.test.ts +146 -0
  679. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +402 -0
  680. package/src/ipc/skill-routes/__tests__/identity.test.ts +81 -0
  681. package/src/ipc/skill-routes/__tests__/log.test.ts +133 -0
  682. package/src/ipc/skill-routes/__tests__/memory.test.ts +178 -0
  683. package/src/ipc/skill-routes/__tests__/platform.test.ts +111 -0
  684. package/src/ipc/skill-routes/__tests__/providers.test.ts +265 -0
  685. package/src/ipc/skill-routes/__tests__/registries.test.ts +361 -0
  686. package/src/ipc/skill-routes/config.ts +47 -0
  687. package/src/ipc/skill-routes/events.ts +131 -0
  688. package/src/ipc/skill-routes/identity.ts +34 -0
  689. package/src/ipc/skill-routes/index.ts +37 -0
  690. package/src/ipc/skill-routes/log.ts +40 -0
  691. package/src/ipc/skill-routes/memory.ts +76 -0
  692. package/src/ipc/skill-routes/platform.ts +39 -0
  693. package/src/ipc/skill-routes/providers.ts +163 -0
  694. package/src/ipc/skill-routes/registries.ts +393 -0
  695. package/src/ipc/skill-server.ts +771 -0
  696. package/src/ipc/skill-socket-path.ts +20 -0
  697. package/src/ipc/socket-cleanup.ts +92 -0
  698. package/src/ipc/socket-path.ts +63 -32
  699. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +374 -0
  700. package/src/live-voice/__tests__/live-voice-archive.test.ts +525 -0
  701. package/src/live-voice/__tests__/live-voice-events.test.ts +473 -0
  702. package/src/live-voice/__tests__/live-voice-integration.test.ts +359 -0
  703. package/src/live-voice/__tests__/live-voice-metrics.test.ts +179 -0
  704. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +349 -0
  705. package/src/live-voice/__tests__/live-voice-stt.test.ts +244 -0
  706. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +337 -0
  707. package/src/live-voice/__tests__/live-voice-tts.test.ts +337 -0
  708. package/src/live-voice/__tests__/protocol.test.ts +295 -0
  709. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +421 -0
  710. package/src/live-voice/live-voice-archive.ts +758 -0
  711. package/src/live-voice/live-voice-metrics.ts +472 -0
  712. package/src/live-voice/live-voice-session-manager.ts +222 -0
  713. package/src/live-voice/live-voice-session.ts +1144 -0
  714. package/src/live-voice/live-voice-tts.ts +260 -0
  715. package/src/live-voice/protocol.ts +524 -0
  716. package/src/mcp/client.ts +2 -2
  717. package/src/media/types.ts +4 -4
  718. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +4 -28
  719. package/src/memory/__tests__/auto-analysis-guard.test.ts +2 -2
  720. package/src/memory/__tests__/conversation-analyze-job.test.ts +7 -62
  721. package/src/memory/__tests__/conversation-group-migration.test.ts +2 -2
  722. package/src/memory/__tests__/find-analysis-conversation.test.ts +2 -1
  723. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +235 -0
  724. package/src/memory/admin.ts +65 -7
  725. package/src/memory/app-git-service.ts +0 -14
  726. package/src/memory/attachments-store.ts +14 -16
  727. package/src/memory/auto-analysis-enqueue.ts +2 -17
  728. package/src/memory/canonical-guardian-store.ts +2 -1
  729. package/src/memory/channel-verification-sessions.ts +1 -1
  730. package/src/memory/checkpoints.ts +1 -1
  731. package/src/memory/context-search/agent-protocol.ts +424 -0
  732. package/src/memory/context-search/agent-runner.ts +1295 -0
  733. package/src/memory/context-search/format.ts +160 -0
  734. package/src/memory/context-search/limits.ts +106 -0
  735. package/src/memory/context-search/search.ts +387 -0
  736. package/src/memory/context-search/sources/conversations.ts +278 -0
  737. package/src/memory/context-search/sources/memory.ts +90 -0
  738. package/src/memory/context-search/sources/pkb.ts +468 -0
  739. package/src/memory/context-search/sources/workspace.ts +1255 -0
  740. package/src/memory/context-search/types.ts +49 -0
  741. package/src/memory/conversation-analyze-job.ts +3 -24
  742. package/src/memory/conversation-attention-store.ts +1 -1
  743. package/src/memory/conversation-bootstrap.ts +1 -1
  744. package/src/memory/conversation-crud.ts +69 -127
  745. package/src/memory/conversation-directories.ts +1 -11
  746. package/src/memory/conversation-display-order-migration.ts +11 -2
  747. package/src/memory/conversation-group-migration.ts +20 -4
  748. package/src/memory/conversation-key-store.ts +3 -4
  749. package/src/memory/conversation-queries.ts +13 -26
  750. package/src/memory/conversation-starter-validation.ts +88 -0
  751. package/src/memory/conversation-starters-cadence.ts +1 -1
  752. package/src/memory/conversation-title-service.ts +2 -1
  753. package/src/memory/db-init.ts +14 -4
  754. package/src/memory/db-maintenance.ts +1 -1
  755. package/src/memory/delivery-channels.ts +1 -14
  756. package/src/memory/delivery-crud.ts +2 -32
  757. package/src/memory/delivery-status.ts +1 -1
  758. package/src/memory/embedding-gemini.test.ts +4 -4
  759. package/src/memory/external-conversation-store.ts +1 -1
  760. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +412 -0
  761. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +225 -0
  762. package/src/memory/graph/bootstrap.test.ts +2 -7
  763. package/src/memory/graph/bootstrap.ts +2 -1
  764. package/src/memory/graph/capability-seed.ts +3 -3
  765. package/src/memory/graph/compaction.ts +1 -1
  766. package/src/memory/graph/consolidation.ts +13 -10
  767. package/src/memory/graph/conversation-graph-memory.ts +151 -1
  768. package/src/memory/graph/decay.ts +1 -1
  769. package/src/memory/graph/extraction.ts +53 -21
  770. package/src/memory/graph/graph-memory-state-store.ts +1 -1
  771. package/src/memory/graph/graph-search.test.ts +94 -2
  772. package/src/memory/graph/graph-search.ts +22 -7
  773. package/src/memory/graph/image-ref-utils.ts +1 -1
  774. package/src/memory/graph/retriever.test.ts +158 -4
  775. package/src/memory/graph/retriever.ts +17 -5
  776. package/src/memory/graph/store.test.ts +2 -1
  777. package/src/memory/graph/store.ts +1 -1
  778. package/src/memory/graph/tool-handlers.ts +73 -247
  779. package/src/memory/graph/tools.ts +35 -53
  780. package/src/memory/group-crud.ts +1 -2
  781. package/src/memory/guardian-action-store.ts +2 -1
  782. package/src/memory/guardian-approvals.ts +1 -1
  783. package/src/memory/guardian-rate-limits.ts +1 -1
  784. package/src/memory/indexer.ts +43 -17
  785. package/src/memory/invite-store.ts +1 -1
  786. package/src/memory/job-handlers/backfill.ts +1 -1
  787. package/src/memory/job-handlers/cleanup.ts +2 -1
  788. package/src/memory/job-handlers/conversation-starters.ts +18 -10
  789. package/src/memory/job-handlers/embedding.test.ts +2 -1
  790. package/src/memory/job-handlers/embedding.ts +1 -1
  791. package/src/memory/job-handlers/index-maintenance.ts +1 -1
  792. package/src/memory/job-handlers/summarization.ts +3 -3
  793. package/src/memory/job-utils.ts +3 -3
  794. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +362 -0
  795. package/src/memory/jobs/embed-concept-page.ts +210 -0
  796. package/src/memory/jobs/embed-pkb-file.test.ts +2 -1
  797. package/src/memory/jobs-store.ts +10 -2
  798. package/src/memory/jobs-worker.ts +58 -5
  799. package/src/memory/lifecycle-events-store.ts +1 -1
  800. package/src/memory/llm-request-log-store.ts +1 -1
  801. package/src/memory/llm-usage-store.ts +1 -1
  802. package/src/memory/media-store.ts +1 -1
  803. package/src/memory/memory-recall-log-store.ts +1 -1
  804. package/src/memory/migrations/038-actor-token-records.ts +3 -0
  805. package/src/memory/migrations/039-actor-refresh-token-records.ts +3 -0
  806. package/src/memory/migrations/226-schedule-wake-conversation-id.ts +11 -0
  807. package/src/memory/migrations/227-add-conversation-inference-profile.ts +18 -0
  808. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +27 -0
  809. package/src/memory/migrations/229-delete-private-conversations.test.ts +1087 -0
  810. package/src/memory/migrations/229-delete-private-conversations.ts +210 -0
  811. package/src/memory/migrations/230-acp-session-history.ts +41 -0
  812. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +128 -0
  813. package/src/memory/migrations/232-activation-state.ts +38 -0
  814. package/src/memory/migrations/index.ts +10 -0
  815. package/src/memory/migrations/registry.ts +7 -0
  816. package/src/memory/pkb/pkb-index.test.ts +4 -5
  817. package/src/memory/pkb/pkb-reconcile.test.ts +4 -5
  818. package/src/memory/pkb/pkb-search.test.ts +83 -3
  819. package/src/memory/pkb/pkb-search.ts +27 -14
  820. package/src/memory/published-pages-store.ts +1 -1
  821. package/src/memory/schema/acp.ts +30 -0
  822. package/src/memory/schema/conversations.ts +1 -1
  823. package/src/memory/schema/index.ts +1 -0
  824. package/src/memory/schema/infrastructure.ts +1 -32
  825. package/src/memory/schema/memory-graph.ts +36 -14
  826. package/src/memory/scoped-approval-grants.ts +2 -1
  827. package/src/memory/search/semantic.ts +2 -2
  828. package/src/memory/shared-app-links-store.ts +2 -1
  829. package/src/memory/tool-usage-store.ts +1 -1
  830. package/src/memory/trace-event-store.ts +2 -1
  831. package/src/memory/turn-events-store.ts +1 -1
  832. package/src/memory/v2/__tests__/activation-store.test.ts +202 -0
  833. package/src/memory/v2/__tests__/activation.test.ts +956 -0
  834. package/src/memory/v2/__tests__/backfill-jobs.test.ts +610 -0
  835. package/src/memory/v2/__tests__/consolidation-job.test.ts +395 -0
  836. package/src/memory/v2/__tests__/edges.test.ts +435 -0
  837. package/src/memory/v2/__tests__/injection.test.ts +792 -0
  838. package/src/memory/v2/__tests__/migration.test.ts +812 -0
  839. package/src/memory/v2/__tests__/page-store.test.ts +334 -0
  840. package/src/memory/v2/__tests__/qdrant.test.ts +438 -0
  841. package/src/memory/v2/__tests__/sim.test.ts +549 -0
  842. package/src/memory/v2/__tests__/skill-content.test.ts +85 -0
  843. package/src/memory/v2/__tests__/skill-qdrant.test.ts +657 -0
  844. package/src/memory/v2/__tests__/skill-store.test.ts +351 -0
  845. package/src/memory/v2/__tests__/sweep-job.test.ts +441 -0
  846. package/src/memory/v2/activation-store.ts +109 -0
  847. package/src/memory/v2/activation.ts +490 -0
  848. package/src/memory/v2/backfill-jobs.ts +442 -0
  849. package/src/memory/v2/consolidation-job.ts +304 -0
  850. package/src/memory/v2/edges.ts +217 -0
  851. package/src/memory/v2/injection.ts +307 -0
  852. package/src/memory/v2/migration.ts +654 -0
  853. package/src/memory/v2/now-text.ts +38 -0
  854. package/src/memory/v2/page-store.ts +245 -0
  855. package/src/memory/v2/prompts/consolidation.ts +185 -0
  856. package/src/memory/v2/prompts/sweep.ts +56 -0
  857. package/src/memory/v2/qdrant.ts +342 -0
  858. package/src/memory/v2/sim.ts +206 -0
  859. package/src/memory/v2/skill-content.ts +42 -0
  860. package/src/memory/v2/skill-qdrant.ts +395 -0
  861. package/src/memory/v2/skill-store.ts +128 -0
  862. package/src/memory/v2/sweep-job.ts +298 -0
  863. package/src/memory/v2/types.ts +116 -0
  864. package/src/memory/validation.ts +1 -1
  865. package/src/messaging/providers/index.ts +262 -0
  866. package/src/messaging/providers/slack/api.ts +242 -0
  867. package/src/messaging/providers/slack/message-metadata.ts +1 -1
  868. package/src/messaging/providers/slack/send.ts +383 -0
  869. package/src/messaging/providers/telegram-bot/adapter.ts +4 -42
  870. package/src/messaging/providers/telegram-bot/api.ts +253 -0
  871. package/src/messaging/providers/telegram-bot/client.ts +17 -58
  872. package/src/messaging/providers/telegram-bot/send.ts +232 -0
  873. package/src/messaging/providers/whatsapp/adapter.ts +4 -36
  874. package/src/messaging/providers/whatsapp/api.ts +319 -0
  875. package/src/messaging/providers/whatsapp/client.ts +4 -48
  876. package/src/messaging/providers/whatsapp/send.ts +209 -0
  877. package/src/notifications/adapters/slack.ts +5 -23
  878. package/src/notifications/adapters/telegram.ts +8 -29
  879. package/src/notifications/conversation-candidates.ts +1 -1
  880. package/src/notifications/conversation-seed-composer.ts +12 -6
  881. package/src/notifications/copy-composer.ts +1 -1
  882. package/src/notifications/decision-engine.ts +1 -1
  883. package/src/notifications/decisions-store.ts +1 -1
  884. package/src/notifications/deliveries-store.ts +2 -1
  885. package/src/notifications/deterministic-checks.ts +1 -1
  886. package/src/notifications/events-store.ts +1 -13
  887. package/src/notifications/preferences-store.ts +1 -1
  888. package/src/notifications/signal.ts +0 -9
  889. package/src/oauth/connection-resolver.ts +11 -2
  890. package/src/oauth/oauth-store.ts +2 -1
  891. package/src/outbound-proxy/index.ts +0 -1
  892. package/src/permissions/approval-policy.test.ts +149 -132
  893. package/src/permissions/approval-policy.ts +65 -91
  894. package/src/permissions/checker.test.ts +632 -0
  895. package/src/permissions/checker.ts +266 -459
  896. package/src/permissions/gateway-threshold-reader.ts +28 -47
  897. package/src/permissions/ipc-risk-types.ts +95 -0
  898. package/src/permissions/prompter.ts +4 -9
  899. package/src/permissions/risk-types.ts +24 -210
  900. package/src/permissions/types.ts +17 -47
  901. package/src/permissions/workspace-policy.ts +2 -4
  902. package/src/playbooks/playbook-compiler.ts +1 -1
  903. package/src/plugins/defaults/index.ts +1 -1
  904. package/src/plugins/defaults/injectors.ts +18 -21
  905. package/src/plugins/defaults/llm-call.ts +6 -9
  906. package/src/plugins/defaults/memory-retrieval.ts +1 -6
  907. package/src/plugins/defaults/overflow-reduce.ts +9 -5
  908. package/src/plugins/defaults/token-estimate.ts +2 -3
  909. package/src/plugins/registry.ts +61 -1
  910. package/src/plugins/types.ts +6 -7
  911. package/src/plugins/user-loader.ts +36 -10
  912. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +197 -0
  913. package/src/prompts/persona-resolver.ts +2 -4
  914. package/src/prompts/system-prompt.ts +39 -0
  915. package/src/prompts/templates/SOUL.md +3 -1
  916. package/src/providers/__tests__/provider-env-vars.test.ts +0 -21
  917. package/src/providers/__tests__/retry-callsite.test.ts +3 -6
  918. package/src/providers/anthropic/client.ts +71 -19
  919. package/src/providers/call-site-routing.ts +7 -3
  920. package/src/providers/fireworks/client.ts +3 -0
  921. package/src/providers/gemini/client.ts +96 -22
  922. package/src/providers/managed-proxy/context.ts +0 -12
  923. package/src/providers/model-catalog.ts +83 -8
  924. package/src/providers/model-intents.ts +7 -8
  925. package/src/providers/openai/chat-completions-provider.ts +37 -7
  926. package/src/providers/openai/responses-provider.ts +39 -4
  927. package/src/providers/openrouter/client.ts +4 -5
  928. package/src/providers/provider-env-vars.ts +4 -12
  929. package/src/providers/provider-send-message.ts +16 -11
  930. package/src/providers/registry.ts +1 -1
  931. package/src/providers/retry.ts +52 -23
  932. package/src/providers/speech-to-text/openai-whisper-stream.ts +1 -1
  933. package/src/providers/speech-to-text/openai-whisper.ts +3 -6
  934. package/src/providers/speech-to-text/provider-catalog.ts +75 -0
  935. package/src/providers/speech-to-text/xai.ts +5 -5
  936. package/src/providers/thinking-config.ts +34 -0
  937. package/src/providers/types.ts +22 -10
  938. package/src/runtime/AGENTS.md +10 -9
  939. package/src/runtime/__tests__/agent-wake.test.ts +33 -9
  940. package/src/runtime/__tests__/client-registry.test.ts +5 -27
  941. package/src/runtime/__tests__/interactive-ui.test.ts +157 -246
  942. package/src/runtime/access-request-helper.ts +9 -20
  943. package/src/runtime/actor-trust-resolver.ts +2 -2
  944. package/src/runtime/agent-wake.ts +174 -68
  945. package/src/runtime/approval-conversation-turn.ts +2 -15
  946. package/src/runtime/approval-message-composer.ts +11 -60
  947. package/src/runtime/assistant-event.ts +18 -66
  948. package/src/runtime/auth/__tests__/guard-tests.test.ts +6 -30
  949. package/src/runtime/auth/__tests__/middleware.test.ts +10 -10
  950. package/src/runtime/auth/__tests__/route-policy.test.ts +0 -8
  951. package/src/runtime/auth/context.ts +9 -0
  952. package/src/runtime/auth/middleware.ts +4 -4
  953. package/src/runtime/auth/route-policy.ts +195 -4
  954. package/src/runtime/auth/token-service.ts +1 -100
  955. package/src/runtime/capability-tokens.ts +89 -313
  956. package/src/runtime/channel-approval-types.ts +1 -6
  957. package/src/runtime/channel-approvals.ts +7 -79
  958. package/src/runtime/channel-readiness-service.ts +2 -2
  959. package/src/runtime/channel-reply-delivery.ts +2 -8
  960. package/src/runtime/channel-retry-sweep.ts +20 -17
  961. package/src/runtime/client-registry.ts +21 -28
  962. package/src/runtime/confirmation-request-guardian-bridge.ts +2 -7
  963. package/src/runtime/gateway-client.ts +37 -378
  964. package/src/runtime/guardian-action-grant-minter.ts +2 -3
  965. package/src/runtime/guardian-action-message-composer.ts +11 -52
  966. package/src/runtime/guardian-action-service.ts +19 -7
  967. package/src/runtime/guardian-decision-types.ts +4 -65
  968. package/src/runtime/guardian-reply-router.ts +10 -19
  969. package/src/runtime/guardian-vellum-migration.ts +5 -64
  970. package/src/runtime/http-errors.ts +3 -0
  971. package/src/runtime/http-router.ts +50 -7
  972. package/src/runtime/http-server.ts +345 -1110
  973. package/src/runtime/http-types.ts +15 -98
  974. package/src/runtime/interactive-ui-types.ts +145 -0
  975. package/src/runtime/interactive-ui.ts +38 -196
  976. package/src/runtime/invite-redemption-service.ts +1 -1
  977. package/src/runtime/invite-redemption-templates.ts +1 -1
  978. package/src/runtime/local-actor-identity.ts +13 -43
  979. package/src/runtime/message-composer-types.ts +134 -0
  980. package/src/runtime/middleware/rate-limiter.ts +1 -1
  981. package/src/runtime/middleware/request-logger.ts +5 -2
  982. package/src/runtime/migrations/__tests__/job-registry.test.ts +346 -0
  983. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +16 -0
  984. package/src/runtime/migrations/job-registry.ts +281 -0
  985. package/src/runtime/migrations/vbundle-builder.ts +3 -4
  986. package/src/runtime/migrations/vbundle-importer.ts +1 -1
  987. package/src/runtime/migrations/vbundle-streaming-importer.ts +0 -13
  988. package/src/runtime/migrations/vbundle-tar-stream.ts +11 -3
  989. package/src/runtime/nl-approval-parser.ts +16 -21
  990. package/src/runtime/pending-interactions.ts +29 -12
  991. package/src/runtime/routes/__tests__/acp-routes.test.ts +395 -0
  992. package/src/runtime/routes/__tests__/backup-routes.test.ts +204 -320
  993. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +72 -4
  994. package/src/runtime/routes/__tests__/stt-routes.test.ts +182 -223
  995. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +230 -0
  996. package/src/{ipc/__tests__/task-ipc.test.ts → runtime/routes/__tests__/task-routes.test.ts} +116 -96
  997. package/src/runtime/routes/__tests__/tts-routes.test.ts +185 -289
  998. package/src/runtime/routes/access-request-decision.ts +25 -50
  999. package/src/runtime/routes/acp-routes.test.ts +371 -0
  1000. package/src/runtime/routes/acp-routes.ts +392 -166
  1001. package/src/runtime/routes/app-management-routes.ts +464 -660
  1002. package/src/runtime/routes/app-routes.ts +192 -177
  1003. package/src/runtime/routes/approval-routes.ts +116 -434
  1004. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +24 -84
  1005. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +3 -10
  1006. package/src/runtime/routes/attachment-routes.ts +409 -253
  1007. package/src/runtime/routes/audio-routes.ts +51 -18
  1008. package/src/runtime/routes/avatar-routes.ts +82 -75
  1009. package/src/runtime/routes/background-tool-routes.ts +94 -0
  1010. package/src/runtime/routes/backup-routes.ts +154 -336
  1011. package/src/runtime/routes/brain-graph-routes.ts +83 -110
  1012. package/src/runtime/routes/browser-routes.ts +141 -0
  1013. package/src/runtime/routes/btw-routes.ts +62 -106
  1014. package/src/runtime/routes/cache-routes.ts +96 -0
  1015. package/src/runtime/routes/call-routes.ts +208 -247
  1016. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +1 -1
  1017. package/src/runtime/routes/channel-delivery-routes.ts +25 -27
  1018. package/src/runtime/routes/channel-readiness-routes.ts +83 -120
  1019. package/src/runtime/routes/channel-route-definitions.ts +62 -0
  1020. package/src/runtime/routes/channel-route-shared.ts +14 -18
  1021. package/src/runtime/routes/channel-verification-routes.ts +207 -187
  1022. package/src/runtime/routes/client-routes.ts +48 -0
  1023. package/src/runtime/routes/contact-routes.ts +533 -407
  1024. package/src/runtime/routes/conversation-analysis-routes.ts +48 -49
  1025. package/src/runtime/routes/conversation-attention-routes.ts +55 -67
  1026. package/src/runtime/routes/conversation-list-routes.ts +265 -0
  1027. package/src/runtime/routes/conversation-management-routes.ts +626 -715
  1028. package/src/runtime/routes/conversation-query-routes.ts +510 -460
  1029. package/src/runtime/routes/conversation-routes.ts +456 -368
  1030. package/src/runtime/routes/conversation-starter-routes.ts +121 -71
  1031. package/src/runtime/routes/credential-prompt-routes.ts +124 -0
  1032. package/src/runtime/routes/debug-routes.ts +34 -39
  1033. package/src/runtime/routes/defer-routes.ts +230 -0
  1034. package/src/runtime/routes/diagnostics-routes.ts +79 -70
  1035. package/src/runtime/routes/documents-routes.ts +117 -106
  1036. package/src/runtime/routes/errors.ts +132 -0
  1037. package/src/runtime/routes/events-routes.ts +97 -58
  1038. package/src/runtime/routes/filing-routes.ts +65 -78
  1039. package/src/runtime/routes/global-search-routes.ts +51 -57
  1040. package/src/runtime/routes/group-routes.ts +199 -181
  1041. package/src/runtime/routes/guardian-action-routes.ts +103 -169
  1042. package/src/runtime/routes/guardian-approval-interception.ts +27 -58
  1043. package/src/runtime/routes/guardian-approval-prompt.ts +10 -21
  1044. package/src/runtime/routes/guardian-approval-reply-helpers.ts +2 -6
  1045. package/src/runtime/routes/guardian-expiry-sweep.ts +19 -36
  1046. package/src/runtime/routes/heartbeat-routes.ts +194 -209
  1047. package/src/runtime/routes/home-feed-routes.ts +85 -187
  1048. package/src/runtime/routes/home-state-routes.ts +27 -24
  1049. package/src/runtime/routes/host-bash-routes.ts +42 -52
  1050. package/src/runtime/routes/host-browser-routes.ts +38 -69
  1051. package/src/runtime/routes/host-cu-routes.ts +74 -70
  1052. package/src/runtime/routes/host-file-routes.ts +50 -60
  1053. package/src/runtime/routes/host-transfer-routes.ts +220 -0
  1054. package/src/runtime/routes/http-adapter.ts +172 -0
  1055. package/src/runtime/routes/identity-routes.ts +83 -79
  1056. package/src/runtime/routes/inbound-conversation.ts +11 -18
  1057. package/src/runtime/routes/inbound-message-handler.ts +74 -110
  1058. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +79 -138
  1059. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +2 -3
  1060. package/src/runtime/routes/inbound-stages/background-dispatch.ts +54 -90
  1061. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +25 -50
  1062. package/src/runtime/routes/inbound-stages/edit-intercept.ts +7 -7
  1063. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
  1064. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +5 -6
  1065. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -24
  1066. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -10
  1067. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
  1068. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +3 -3
  1069. package/src/runtime/routes/inbound-stages/verification-intercept.ts +19 -26
  1070. package/src/runtime/routes/index.ts +197 -0
  1071. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +25 -32
  1072. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +22 -31
  1073. package/src/runtime/routes/integrations/slack/channel.ts +69 -66
  1074. package/src/runtime/routes/integrations/slack/share.ts +49 -58
  1075. package/src/runtime/routes/integrations/telegram.ts +91 -74
  1076. package/src/runtime/routes/integrations/twilio.ts +163 -240
  1077. package/src/runtime/routes/integrations/vercel.ts +57 -54
  1078. package/src/runtime/routes/interface-routes.ts +43 -0
  1079. package/src/runtime/routes/internal-oauth-routes.ts +56 -0
  1080. package/src/runtime/routes/internal-twilio-routes.ts +46 -0
  1081. package/src/runtime/routes/llm-context-normalization.ts +4 -2
  1082. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  1083. package/src/runtime/routes/log-export-routes.ts +90 -100
  1084. package/src/runtime/routes/memory-item-routes.test.ts +152 -175
  1085. package/src/runtime/routes/memory-item-routes.ts +243 -323
  1086. package/src/runtime/routes/memory-v2-routes.ts +193 -0
  1087. package/src/runtime/routes/migration-rollback-routes.ts +167 -212
  1088. package/src/runtime/routes/migration-routes.ts +877 -374
  1089. package/src/runtime/routes/notification-routes.ts +199 -70
  1090. package/src/runtime/routes/oauth-apps.ts +254 -251
  1091. package/src/runtime/routes/oauth-providers.ts +66 -57
  1092. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +60 -120
  1093. package/src/runtime/routes/playground/__tests__/guard.test.ts +34 -54
  1094. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +107 -151
  1095. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +41 -117
  1096. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +95 -138
  1097. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +115 -217
  1098. package/src/runtime/routes/playground/__tests__/state.test.ts +41 -90
  1099. package/src/runtime/routes/playground/conversation-not-found.ts +9 -11
  1100. package/src/runtime/routes/playground/force-compact.ts +41 -54
  1101. package/src/runtime/routes/playground/guard.ts +18 -19
  1102. package/src/runtime/routes/playground/helpers.ts +103 -0
  1103. package/src/runtime/routes/playground/index.ts +15 -25
  1104. package/src/runtime/routes/playground/inject-failures.ts +48 -64
  1105. package/src/runtime/routes/playground/reset-circuit.ts +31 -57
  1106. package/src/runtime/routes/playground/seed-conversation.ts +66 -92
  1107. package/src/runtime/routes/playground/seeded-conversations.ts +60 -64
  1108. package/src/runtime/routes/playground/state.ts +23 -24
  1109. package/src/runtime/routes/profiler-routes.ts +132 -167
  1110. package/src/runtime/routes/ps-routes.ts +120 -0
  1111. package/src/runtime/routes/recording-routes.ts +197 -258
  1112. package/src/runtime/routes/rename-conversation-routes.ts +89 -0
  1113. package/src/runtime/routes/schedule-routes.ts +238 -242
  1114. package/src/runtime/routes/secret-routes.ts +219 -265
  1115. package/src/runtime/routes/secrets-deps.ts +24 -0
  1116. package/src/runtime/routes/settings-routes.ts +361 -441
  1117. package/src/runtime/routes/skills-routes.ts +434 -469
  1118. package/src/runtime/routes/stt-routes.ts +196 -206
  1119. package/src/runtime/routes/subagents-routes.ts +125 -141
  1120. package/src/runtime/routes/suggest-trust-rule-routes.ts +244 -0
  1121. package/src/runtime/routes/surface-action-routes.ts +135 -190
  1122. package/src/runtime/routes/surface-content-routes.ts +84 -118
  1123. package/src/runtime/routes/task-routes.ts +354 -0
  1124. package/src/runtime/routes/telemetry-routes.ts +33 -49
  1125. package/src/runtime/routes/trace-event-routes.ts +55 -74
  1126. package/src/runtime/routes/trust-rules-routes.ts +147 -239
  1127. package/src/runtime/routes/tts-routes.ts +187 -169
  1128. package/src/runtime/routes/types.ts +139 -0
  1129. package/src/{ipc/routes/ui-request.ts → runtime/routes/ui-request-routes.ts} +23 -17
  1130. package/src/runtime/routes/upgrade-broadcast-routes.ts +156 -197
  1131. package/src/runtime/routes/usage-routes.ts +143 -169
  1132. package/src/runtime/routes/user-routes.ts +102 -18
  1133. package/src/runtime/routes/wake-conversation-routes.ts +49 -0
  1134. package/src/{ipc/routes/watcher.ts → runtime/routes/watcher-routes.ts} +84 -39
  1135. package/src/runtime/routes/wipe-conversation-routes.ts +89 -0
  1136. package/src/runtime/routes/work-items-routes.test.ts +10 -20
  1137. package/src/runtime/routes/work-items-routes.ts +418 -433
  1138. package/src/runtime/routes/workspace-commit-routes.ts +30 -61
  1139. package/src/runtime/routes/workspace-routes.test.ts +254 -381
  1140. package/src/runtime/routes/workspace-routes.ts +238 -246
  1141. package/src/runtime/runtime-mode.ts +8 -1
  1142. package/src/runtime/services/__tests__/analyze-conversation.test.ts +80 -118
  1143. package/src/runtime/services/analyze-conversation.ts +14 -41
  1144. package/src/runtime/services/conversation-serializer.ts +181 -0
  1145. package/src/runtime/trust-context-resolver.ts +3 -2
  1146. package/src/runtime/verification-outbound-actions.ts +13 -49
  1147. package/src/schedule/schedule-store.ts +64 -2
  1148. package/src/schedule/scheduler.ts +101 -0
  1149. package/src/security/ces-credential-client.ts +32 -169
  1150. package/src/security/ces-rpc-credential-backend.ts +1 -1
  1151. package/src/security/credential-backend.ts +6 -6
  1152. package/src/security/oauth-completion-page.ts +1 -1
  1153. package/src/security/oauth2.ts +3 -6
  1154. package/src/sequence/analytics.ts +1 -1
  1155. package/src/sequence/guardrails.ts +3 -3
  1156. package/src/sequence/store.ts +2 -1
  1157. package/src/signals/bash.ts +1 -1
  1158. package/src/signals/event-stream.ts +1 -1
  1159. package/src/skills/catalog-cache.ts +7 -0
  1160. package/src/skills/catalog-files.ts +0 -5
  1161. package/src/skills/catalog-install.ts +28 -18
  1162. package/src/skills/category-inference.ts +0 -11
  1163. package/src/skills/clawhub.ts +2 -2
  1164. package/src/skills/managed-store.ts +2 -2
  1165. package/src/skills/remote-skill-policy.ts +6 -7
  1166. package/src/subagent/index.ts +2 -6
  1167. package/src/subagent/manager.ts +27 -23
  1168. package/src/subagent/types.ts +9 -0
  1169. package/src/tasks/SPEC.md +2 -2
  1170. package/src/tasks/task-compiler.ts +1 -1
  1171. package/src/tasks/task-runner.ts +2 -22
  1172. package/src/tasks/task-store.ts +1 -1
  1173. package/src/tools/acp/list-agents.test.ts +115 -0
  1174. package/src/tools/acp/list-agents.ts +31 -0
  1175. package/src/tools/acp/spawn.test.ts +379 -0
  1176. package/src/tools/acp/spawn.ts +142 -62
  1177. package/src/tools/acp/steer.test.ts +101 -0
  1178. package/src/tools/acp/steer.ts +38 -0
  1179. package/src/tools/background-tool-registry.ts +98 -0
  1180. package/src/tools/browser/browser-execution.ts +34 -7
  1181. package/src/tools/browser/browser-manager.ts +1 -8
  1182. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +1 -1
  1183. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +3 -1
  1184. package/src/tools/browser/cdp-client/types.ts +4 -1
  1185. package/src/tools/computer-use/definitions.ts +1 -1
  1186. package/src/tools/credential-execution/make-authenticated-request.ts +2 -2
  1187. package/src/tools/credential-execution/manage-secure-command-tool.ts +1 -1
  1188. package/src/tools/credential-execution/run-authenticated-command.ts +2 -2
  1189. package/src/tools/credentials/broker-types.ts +2 -1
  1190. package/src/tools/document/editor-template.ts +1 -1
  1191. package/src/tools/execution-timeout.ts +1 -1
  1192. package/src/tools/executor.ts +10 -15
  1193. package/src/tools/host-filesystem/transfer.test.ts +268 -0
  1194. package/src/tools/host-filesystem/transfer.ts +234 -0
  1195. package/src/tools/host-terminal/host-shell.ts +189 -11
  1196. package/src/tools/mcp/mcp-tool-factory.ts +1 -1
  1197. package/src/tools/memory/register.test.ts +161 -1
  1198. package/src/tools/memory/register.ts +19 -34
  1199. package/src/tools/permission-checker.ts +18 -219
  1200. package/src/tools/policy-context.ts +1 -8
  1201. package/src/tools/registry.ts +16 -1
  1202. package/src/tools/secret-detection-handler.ts +13 -103
  1203. package/src/tools/shared/shell-output.ts +4 -1
  1204. package/src/tools/side-effects.ts +2 -2
  1205. package/src/tools/skills/execute.ts +1 -1
  1206. package/src/tools/subagent/spawn.ts +35 -11
  1207. package/src/tools/terminal/safe-env.ts +9 -1
  1208. package/src/tools/terminal/shell.ts +161 -31
  1209. package/src/tools/tool-approval-handler.ts +4 -70
  1210. package/src/tools/tool-input-summary.ts +10 -0
  1211. package/src/tools/types.ts +143 -163
  1212. package/src/tools/ui-surface/definitions.ts +2 -2
  1213. package/src/util/debounce.ts +0 -21
  1214. package/src/util/errors.ts +0 -8
  1215. package/src/util/log-redact.ts +0 -1
  1216. package/src/util/platform.ts +85 -124
  1217. package/src/util/pricing.ts +109 -6
  1218. package/src/watcher/engine.ts +42 -20
  1219. package/src/watcher/watcher-store.ts +2 -1
  1220. package/src/work-items/work-item-store.ts +1 -1
  1221. package/src/workspace/git-service.ts +1 -6
  1222. package/src/workspace/migrations/006-services-config.ts +10 -1
  1223. package/src/workspace/migrations/017-seed-persona-dirs.ts +1 -1
  1224. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +1 -1
  1225. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +1 -1
  1226. package/src/workspace/migrations/031-drop-user-md.ts +1 -1
  1227. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +3 -4
  1228. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +150 -0
  1229. package/src/workspace/migrations/053-release-notes-acp-codex.ts +107 -0
  1230. package/src/workspace/migrations/054-seed-recall-callsite.ts +102 -0
  1231. package/src/workspace/migrations/055-release-notes-agentic-recall.ts +63 -0
  1232. package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +65 -0
  1233. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +98 -0
  1234. package/src/workspace/migrations/058-release-notes-acp-sessions-ui.ts +71 -0
  1235. package/src/workspace/migrations/059-move-pid-to-workspace.ts +53 -0
  1236. package/src/workspace/migrations/060-memory-v2-init.ts +53 -0
  1237. package/src/workspace/migrations/rebuild-conversation-disk-view.ts +1 -1
  1238. package/src/workspace/migrations/registry.ts +18 -0
  1239. package/src/workspace/migrations/runner.ts +2 -2
  1240. package/src/workspace/provider-commit-message-generator.ts +1 -1
  1241. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +0 -471
  1242. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +0 -436
  1243. package/src/__tests__/cli-command-risk-guard.test.ts +0 -368
  1244. package/src/__tests__/config-watcher-feature-flags.test.ts +0 -211
  1245. package/src/__tests__/conversation-approval-overrides.test.ts +0 -207
  1246. package/src/__tests__/conversation-host-access-routes.test.ts +0 -229
  1247. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +0 -226
  1248. package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +0 -167
  1249. package/src/__tests__/ephemeral-permissions.test.ts +0 -474
  1250. package/src/__tests__/extension-id-sync-guard.test.ts +0 -241
  1251. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +0 -374
  1252. package/src/__tests__/native-host-marker-sync-guard.test.ts +0 -157
  1253. package/src/__tests__/pairing-concurrent.test.ts +0 -84
  1254. package/src/__tests__/pairing-routes.test.ts +0 -181
  1255. package/src/__tests__/parser.test.ts +0 -595
  1256. package/src/__tests__/permission-checker-host-gate.test.ts +0 -488
  1257. package/src/__tests__/permission-controls-v2-flag.test.ts +0 -55
  1258. package/src/__tests__/permission-mode.test.ts +0 -89
  1259. package/src/__tests__/provider-env-vars-scope.test.ts +0 -52
  1260. package/src/__tests__/risk-classifier-parity.test.ts +0 -230
  1261. package/src/__tests__/shell-identity.test.ts +0 -236
  1262. package/src/__tests__/shell-parser-fuzz.test.ts +0 -629
  1263. package/src/__tests__/shell-parser-property.test.ts +0 -936
  1264. package/src/__tests__/starter-bundle.test.ts +0 -173
  1265. package/src/__tests__/stt-catalog-parity.test.ts +0 -282
  1266. package/src/__tests__/task-runner.test.ts +0 -224
  1267. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -354
  1268. package/src/__tests__/trust-store-pattern-matches.test.ts +0 -29
  1269. package/src/__tests__/trust-store.test.ts +0 -2013
  1270. package/src/__tests__/v2-consent-policy.test.ts +0 -103
  1271. package/src/browser/identifiers.ts +0 -51
  1272. package/src/cli/db.ts +0 -1
  1273. package/src/config/bundled-skills/settings/tools/avatar-get.ts +0 -40
  1274. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +0 -64
  1275. package/src/config/bundled-skills/settings/tools/avatar-update.ts +0 -88
  1276. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +0 -127
  1277. package/src/daemon/approved-devices-store.ts +0 -110
  1278. package/src/daemon/external-skills-bootstrap.ts +0 -41
  1279. package/src/daemon/message-types/trust.ts +0 -71
  1280. package/src/daemon/pairing-store.ts +0 -229
  1281. package/src/ipc/cli-server.ts +0 -252
  1282. package/src/ipc/routes/attachment.ts +0 -114
  1283. package/src/ipc/routes/browser-context.ts +0 -63
  1284. package/src/ipc/routes/browser.ts +0 -97
  1285. package/src/ipc/routes/cache.ts +0 -96
  1286. package/src/ipc/routes/get-contact.ts +0 -16
  1287. package/src/ipc/routes/index.ts +0 -35
  1288. package/src/ipc/routes/list-clients.ts +0 -31
  1289. package/src/ipc/routes/merge-contacts.ts +0 -17
  1290. package/src/ipc/routes/notification.ts +0 -133
  1291. package/src/ipc/routes/rename-conversation.ts +0 -59
  1292. package/src/ipc/routes/search-contacts.ts +0 -19
  1293. package/src/ipc/routes/task-queue.ts +0 -226
  1294. package/src/ipc/routes/task.ts +0 -173
  1295. package/src/ipc/routes/upsert-contact.ts +0 -25
  1296. package/src/ipc/routes/wake-conversation.ts +0 -19
  1297. package/src/memory/db.ts +0 -23
  1298. package/src/permissions/arg-parser.test.ts +0 -161
  1299. package/src/permissions/arg-parser.ts +0 -141
  1300. package/src/permissions/bash-risk-classifier.test.ts +0 -1620
  1301. package/src/permissions/bash-risk-classifier.ts +0 -950
  1302. package/src/permissions/command-registry.test.ts +0 -774
  1303. package/src/permissions/command-registry.ts +0 -1005
  1304. package/src/permissions/defaults.ts +0 -314
  1305. package/src/permissions/file-risk-classifier.test.ts +0 -535
  1306. package/src/permissions/file-risk-classifier.ts +0 -274
  1307. package/src/permissions/permission-mode.ts +0 -24
  1308. package/src/permissions/schedule-risk-classifier.test.ts +0 -129
  1309. package/src/permissions/schedule-risk-classifier.ts +0 -85
  1310. package/src/permissions/shell-identity.ts +0 -297
  1311. package/src/permissions/skill-risk-classifier.test.ts +0 -311
  1312. package/src/permissions/skill-risk-classifier.ts +0 -214
  1313. package/src/permissions/trust-client.ts +0 -359
  1314. package/src/permissions/trust-store-interface.ts +0 -100
  1315. package/src/permissions/trust-store.ts +0 -1330
  1316. package/src/permissions/v2-consent-policy.ts +0 -87
  1317. package/src/permissions/web-risk-classifier.test.ts +0 -170
  1318. package/src/permissions/web-risk-classifier.ts +0 -89
  1319. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +0 -715
  1320. package/src/runtime/__tests__/capability-tokens.test.ts +0 -258
  1321. package/src/runtime/actor-refresh-token-store.ts +0 -156
  1322. package/src/runtime/actor-token-store.ts +0 -207
  1323. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -264
  1324. package/src/runtime/auth/credential-service.ts +0 -352
  1325. package/src/runtime/conversation-approval-overrides.ts +0 -86
  1326. package/src/runtime/routes/browser-extension-pair-routes.ts +0 -575
  1327. package/src/runtime/routes/channel-routes.ts +0 -112
  1328. package/src/runtime/routes/contact-routes.test.ts +0 -298
  1329. package/src/runtime/routes/guardian-bootstrap-routes.ts +0 -175
  1330. package/src/runtime/routes/guardian-refresh-routes.ts +0 -79
  1331. package/src/runtime/routes/invite-routes.ts +0 -280
  1332. package/src/runtime/routes/pairing-routes.ts +0 -431
  1333. package/src/runtime/routes/playground/deps.ts +0 -56
  1334. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +0 -67
  1335. package/src/runtime/services/analyze-deps-singleton.ts +0 -32
  1336. package/src/tasks/ephemeral-permissions.ts +0 -55
  1337. package/src/tools/terminal/parser.ts +0 -623
  1338. package/src/types/qrcode.d.ts +0 -13
  1339. package/src/util/network-info.ts +0 -55
  1340. /package/node_modules/@vellumai/{ces-contracts → ces-client}/tsconfig.json +0 -0
  1341. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/grants.test.ts +0 -0
  1342. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/error.ts +0 -0
  1343. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/grants.ts +0 -0
  1344. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/handles.ts +0 -0
  1345. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rendering.ts +0 -0
  1346. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rpc.ts +0 -0
@@ -1,1330 +0,0 @@
1
- import {
2
- chmodSync,
3
- existsSync,
4
- mkdirSync,
5
- readFileSync,
6
- renameSync,
7
- writeFileSync,
8
- } from "node:fs";
9
- import { dirname, join } from "node:path";
10
-
11
- import {
12
- parseTrustFileData,
13
- parseTrustRule,
14
- ruleScope,
15
- SCOPED_TOOLS,
16
- } from "@vellumai/ces-contracts";
17
- import { Minimatch } from "minimatch";
18
- import { v4 as uuid } from "uuid";
19
-
20
- import { getIsContainerized } from "../config/env-registry.js";
21
- import { getLogger } from "../util/logger.js";
22
- import { getProtectedDir } from "../util/platform.js";
23
- import { getDefaultRuleTemplates } from "./defaults.js";
24
- import * as trustClient from "./trust-client.js";
25
- import type {
26
- AcceptStarterBundleResult,
27
- StarterBundleRule,
28
- TrustStoreBackend,
29
- } from "./trust-store-interface.js";
30
- import type { PolicyContext, TrustRule } from "./types.js";
31
-
32
- export type {
33
- AcceptStarterBundleResult,
34
- StarterBundleRule,
35
- } from "./trust-store-interface.js";
36
- export type { TrustStoreBackend } from "./trust-store-interface.js";
37
-
38
- const log = getLogger("trust-store");
39
-
40
- /** O(1) lookup set for scoped tool names. */
41
- const SCOPED_TOOLS_SET: ReadonlySet<string> = new Set(SCOPED_TOOLS);
42
-
43
- const TRUST_FILE_VERSION = 3;
44
-
45
- interface TrustFile {
46
- version: number;
47
- rules: TrustRule[];
48
- /** Set to true when the user explicitly accepts the starter approval bundle. */
49
- starterBundleAccepted?: boolean;
50
- }
51
-
52
- let cachedRules: TrustRule[] | null = null;
53
- let cachedStarterBundleAccepted: boolean | null = null;
54
-
55
- // Callbacks invoked when trust rules change (add/update/remove/clear).
56
- // Used by the permission checker to invalidate dependent caches.
57
- const rulesChangedListeners: Array<() => void> = [];
58
-
59
- /** Register a callback to be invoked whenever trust rules change (file backend). */
60
- function fileOnRulesChanged(listener: () => void): void {
61
- rulesChangedListeners.push(listener);
62
- }
63
-
64
- function notifyRulesChanged(): void {
65
- for (const listener of rulesChangedListeners) {
66
- listener();
67
- }
68
- }
69
-
70
- /**
71
- * Cache of pre-compiled Minimatch objects keyed by pattern string.
72
- * Rebuilt whenever cachedRules changes. Avoids re-parsing glob patterns
73
- * on every tool-call permission check.
74
- */
75
- const compiledPatterns = new Map<string, Minimatch>();
76
- /** Patterns that failed compilation — cached to avoid repeated attempts and log spam. */
77
- const invalidPatterns = new Set<string>();
78
-
79
- /** Get or compile a Minimatch object for the given pattern. Returns null if the pattern is invalid. */
80
- function getCompiledPattern(pattern: string): Minimatch | null {
81
- if (invalidPatterns.has(pattern)) return null;
82
- let compiled = compiledPatterns.get(pattern);
83
- if (!compiled) {
84
- if (typeof pattern !== "string") {
85
- log.warn({ pattern }, "Cannot compile non-string pattern");
86
- invalidPatterns.add(pattern as string);
87
- return null;
88
- }
89
- try {
90
- compiled = new Minimatch(pattern);
91
- compiledPatterns.set(pattern, compiled);
92
- } catch (err) {
93
- log.warn({ pattern, err }, "Failed to compile pattern");
94
- invalidPatterns.add(pattern);
95
- return null;
96
- }
97
- }
98
- return compiled;
99
- }
100
-
101
- /**
102
- * Check whether a minimatch pattern matches a candidate string (file backend).
103
- * Reuses the compiled pattern cache from trust rule evaluation.
104
- */
105
- function filePatternMatchesCandidate(
106
- pattern: string,
107
- candidate: string,
108
- ): boolean {
109
- const compiled = getCompiledPattern(pattern);
110
- if (!compiled) return false;
111
- return compiled.match(candidate);
112
- }
113
-
114
- /** Rebuild the compiled pattern cache from the current rule set. */
115
- function rebuildPatternCache(rules: TrustRule[]): void {
116
- compiledPatterns.clear();
117
- invalidPatterns.clear();
118
- for (const rule of rules) {
119
- if (typeof rule.pattern !== "string") {
120
- log.warn(
121
- { ruleId: rule.id, pattern: rule.pattern },
122
- "Skipping rule with non-string pattern during cache rebuild",
123
- );
124
- continue;
125
- }
126
- if (!compiledPatterns.has(rule.pattern)) {
127
- try {
128
- compiledPatterns.set(rule.pattern, new Minimatch(rule.pattern));
129
- } catch (err) {
130
- log.warn(
131
- { ruleId: rule.id, pattern: rule.pattern, err },
132
- "Skipping rule with invalid pattern during cache rebuild",
133
- );
134
- }
135
- }
136
- }
137
- }
138
-
139
- function getTrustPath(): string {
140
- return join(getGatewaySecurityDir(), "trust.json");
141
- }
142
-
143
- /**
144
- * Resolve the gateway security directory.
145
- *
146
- * Docker: `GATEWAY_SECURITY_DIR` env var.
147
- * Local: the per-instance protected directory resolved by `getProtectedDir()`.
148
- */
149
- function getGatewaySecurityDir(): string {
150
- const securityDir = process.env.GATEWAY_SECURITY_DIR;
151
- if (securityDir) return securityDir;
152
- return getProtectedDir();
153
- }
154
-
155
- /**
156
- * Sort comparator: highest priority first. At the same priority, deny rules
157
- * come before allow rules for safety (deny wins ties).
158
- */
159
- function ruleOrder(a: TrustRule, b: TrustRule): number {
160
- if (b.priority !== a.priority) return b.priority - a.priority;
161
- if (a.decision !== b.decision) {
162
- // deny > ask > allow
163
- const order: Record<string, number> = { deny: 0, ask: 1, allow: 2 };
164
- return (order[a.decision] ?? 2) - (order[b.decision] ?? 2);
165
- }
166
- return 0;
167
- }
168
-
169
- /**
170
- * Ensure default rules are always present in the rule set.
171
- * Mutates the provided array and returns whether any rules were added.
172
- */
173
- function backfillDefaults(rules: TrustRule[]): boolean {
174
- let changed = false;
175
- const existingIds = new Set(rules.map((r) => r.id));
176
-
177
- // Migrate old default:deny-*-protected rules → default:ask-*-protected
178
- const oldDefaultPrefix = "default:deny-";
179
- const newDefaultPrefix = "default:ask-";
180
- for (let i = rules.length - 1; i >= 0; i--) {
181
- const rule = rules[i];
182
- if (
183
- rule.id.startsWith(oldDefaultPrefix) &&
184
- rule.id.endsWith("-protected")
185
- ) {
186
- const newId = newDefaultPrefix + rule.id.slice(oldDefaultPrefix.length);
187
- rules.splice(i, 1);
188
- existingIds.delete(rule.id);
189
- // Don't add newId to existingIds — let the backfill loop re-add it
190
- changed = true;
191
- log.info({ oldId: rule.id, newId }, "Migrated default deny rule to ask");
192
- }
193
- }
194
-
195
- // Remove default rules that are no longer in the template set (e.g.
196
- // computer_use_done/computer_use_respond were removed from the ask-rule list
197
- // because they are terminal signal tools that don't need approval).
198
- const templateIds = new Set(getDefaultRuleTemplates().map((t) => t.id));
199
- for (let i = rules.length - 1; i >= 0; i--) {
200
- const rule = rules[i];
201
- if (rule.id.startsWith("default:") && !templateIds.has(rule.id)) {
202
- rules.splice(i, 1);
203
- existingIds.delete(rule.id);
204
- changed = true;
205
- log.info({ ruleId: rule.id }, "Removed stale default trust rule");
206
- }
207
- }
208
-
209
- // Migrate existing default rules whose priority, pattern, scope, or decision
210
- // has changed in the template (e.g. host_bash pattern changed from '*' to
211
- // '**', host tool priorities changed from 1000 to 50, workspace scope
212
- // changed from getRootDir()+workspace to getWorkspaceDir()).
213
- //
214
- // Also strip any leftover allowHighRisk fields from persisted default rules
215
- // since the field has been replaced by runtime determination.
216
- //
217
- // Rules with `userModifiedAt` set are skipped — the user explicitly
218
- // customized them and their override should be preserved across upgrades.
219
- for (const template of getDefaultRuleTemplates()) {
220
- if (existingIds.has(template.id)) {
221
- const rule = rules.find((r) => r.id === template.id);
222
- if (!rule) continue;
223
- // Strip legacy allowHighRisk from persisted default rules.
224
- const ruleRecord = rule as unknown as Record<string, unknown>;
225
- if ("allowHighRisk" in ruleRecord) {
226
- delete ruleRecord.allowHighRisk;
227
- changed = true;
228
- }
229
- if (
230
- rule.priority !== template.priority ||
231
- rule.pattern !== template.pattern ||
232
- ruleScope(rule) !== (template.scope ?? "everywhere") ||
233
- rule.decision !== template.decision
234
- ) {
235
- if (rule.userModifiedAt != null) {
236
- log.info(
237
- { ruleId: rule.id, userModifiedAt: rule.userModifiedAt },
238
- "Skipping migration of user-modified default rule",
239
- );
240
- continue;
241
- }
242
- log.info(
243
- {
244
- ruleId: rule.id,
245
- oldPriority: rule.priority,
246
- newPriority: template.priority,
247
- oldPattern: rule.pattern,
248
- newPattern: template.pattern,
249
- oldScope: ruleScope(rule),
250
- newScope: template.scope ?? "everywhere",
251
- },
252
- "Migrated default rule to updated template values",
253
- );
254
- rule.priority = template.priority;
255
- rule.pattern = template.pattern;
256
- if (template.scope != null) {
257
- rule.scope = template.scope;
258
- }
259
- rule.decision = template.decision;
260
- changed = true;
261
- }
262
- }
263
- }
264
-
265
- for (const template of getDefaultRuleTemplates()) {
266
- if (!existingIds.has(template.id)) {
267
- // Canonicalize through parseTrustRule so family-specific field
268
- // validation is applied (consistent with fileAddRule/fileUpdateRule).
269
- const { rule } = parseTrustRule({
270
- ...template,
271
- createdAt: Date.now(),
272
- });
273
- rules.push(rule as TrustRule);
274
- changed = true;
275
- log.info({ ruleId: template.id }, "Backfilled default trust rule");
276
- }
277
- }
278
- return changed;
279
- }
280
-
281
- function loadFromDisk(): TrustRule[] {
282
- const path = getTrustPath();
283
- let rules: TrustRule[] = [];
284
- let needsSave = false;
285
-
286
- if (existsSync(path)) {
287
- try {
288
- const raw = readFileSync(path, "utf-8");
289
- const data = JSON.parse(raw) as TrustFile;
290
-
291
- // Guard: ensure rules is an array (protects against hand-edited files)
292
- const rawRules = Array.isArray(data.rules) ? data.rules : [];
293
-
294
- // Restore persisted starter bundle flag
295
- cachedStarterBundleAccepted = data.starterBundleAccepted === true;
296
-
297
- // Defense-in-depth: strip any __internal: prefixed rules that may have
298
- // been hand-edited into trust.json.
299
- const sanitizedRules = rawRules.filter((r) => {
300
- if (typeof r.tool === "string" && r.tool.startsWith("__internal:")) {
301
- log.warn(
302
- { ruleId: r.id, tool: r.tool },
303
- "Stripping __internal: rule from trust file on load",
304
- );
305
- return false;
306
- }
307
- return true;
308
- });
309
-
310
- if (
311
- data.version === TRUST_FILE_VERSION ||
312
- data.version === 1 ||
313
- data.version === 2
314
- ) {
315
- if (sanitizedRules.length < rawRules.length) {
316
- needsSave = true;
317
- }
318
- if (data.version !== TRUST_FILE_VERSION) {
319
- needsSave = true;
320
- log.info(
321
- { version: data.version, targetVersion: TRUST_FILE_VERSION },
322
- "Migrating legacy trust file version",
323
- );
324
- }
325
-
326
- // Apply canonical parser for family-aware normalization.
327
- // The parser strips fields that are invalid for a rule's tool family
328
- // (e.g. executionTarget on URL rules) and coerces malformed values.
329
- const { data: parsedData, normalized } = parseTrustFileData({
330
- ...data,
331
- rules: sanitizedRules,
332
- });
333
- // The contracts parser returns the union TrustRule type; our local
334
- // TrustRule flattens the union with optional fields for backward
335
- // compatibility. The structural overlap is safe to cast here.
336
- rules = parsedData.rules as TrustRule[];
337
- if (normalized) {
338
- needsSave = true;
339
- }
340
-
341
- // Strip legacy principal-scoped fields from persisted v3 rules.
342
- // Before the principal concept was removed, rules could carry
343
- // principalKind/principalId/principalVersion which acted as scope
344
- // constraints. Now that matching ignores those fields, leaving them
345
- // on loaded rules would silently widen their scope to global
346
- // wildcards. Stripping them and re-saving prevents scope escalation.
347
- for (const rule of rules) {
348
- // Legacy v3 rules may carry principal-scoped fields that no longer
349
- // exist in the TrustRule interface — cast to strip them at runtime.
350
- const r = rule as unknown as Record<string, unknown>;
351
- if (
352
- "principalKind" in r ||
353
- "principalId" in r ||
354
- "principalVersion" in r
355
- ) {
356
- delete r.principalKind;
357
- delete r.principalId;
358
- delete r.principalVersion;
359
- needsSave = true;
360
- }
361
- }
362
- } else {
363
- log.warn(
364
- { version: data.version },
365
- "Unknown trust file version, applying defaults in-memory only",
366
- );
367
- // Apply default deny rules in-memory so the assistant is still
368
- // protected, but do NOT persist — we must not overwrite a newer
369
- // trust file format we don't understand.
370
- const memRules: TrustRule[] = [];
371
- backfillDefaults(memRules);
372
- memRules.sort(ruleOrder);
373
- return memRules;
374
- }
375
- } catch (err) {
376
- log.error({ err }, "Failed to load trust file");
377
- // Fall through to backfill defaults even on parse errors
378
- }
379
- }
380
-
381
- // Backfill default rules at their declared priority
382
- if (backfillDefaults(rules)) {
383
- needsSave = true;
384
- }
385
-
386
- rules.sort(ruleOrder);
387
-
388
- if (needsSave) {
389
- try {
390
- saveToDisk(rules);
391
- } catch (err) {
392
- log.warn(
393
- { err },
394
- "Failed to persist migrated trust rules (continuing with in-memory rules)",
395
- );
396
- }
397
- }
398
-
399
- return rules;
400
- }
401
-
402
- function saveToDisk(rules: TrustRule[]): void {
403
- const path = getTrustPath();
404
- const dir = dirname(path);
405
- if (!existsSync(dir)) {
406
- mkdirSync(dir, { recursive: true });
407
- }
408
- const data: TrustFile = { version: TRUST_FILE_VERSION, rules };
409
- if (cachedStarterBundleAccepted) {
410
- data.starterBundleAccepted = true;
411
- }
412
- const tmpPath = path + ".tmp." + process.pid;
413
- writeFileSync(tmpPath, JSON.stringify(data, null, 2), { mode: 0o600 });
414
- renameSync(tmpPath, path);
415
- // Enforce owner-only permissions even if the file already existed with
416
- // wider permissions. Matches the pattern used in encrypted-store.ts.
417
- chmodSync(path, 0o600);
418
- }
419
-
420
- function getRules(): TrustRule[] {
421
- if (cachedRules == null) {
422
- cachedRules = loadFromDisk();
423
- rebuildPatternCache(cachedRules);
424
- }
425
- return cachedRules;
426
- }
427
-
428
- function fileAddRule(
429
- tool: string,
430
- pattern: string,
431
- scope: string,
432
- decision: "allow" | "deny" | "ask" = "allow",
433
- priority: number = 100,
434
- options?: {
435
- executionTarget?: string;
436
- },
437
- ): TrustRule {
438
- if (tool.startsWith("__internal:"))
439
- throw new Error(`Cannot create internal pseudo-rule via addRule: ${tool}`);
440
-
441
- // Canonicalize through the shared parser so fields invalid for the tool's
442
- // family are stripped before persistence, regardless of which callsite
443
- // invoked addRule. Only include scope for scoped tools — non-scoped tools
444
- // don't carry a scope field.
445
- const rawRule: Record<string, unknown> = {
446
- id: uuid(),
447
- tool,
448
- pattern,
449
- decision,
450
- priority,
451
- createdAt: Date.now(),
452
- };
453
- if (SCOPED_TOOLS_SET.has(tool)) {
454
- rawRule.scope = scope;
455
- }
456
- if (options?.executionTarget != null) {
457
- rawRule.executionTarget = options.executionTarget;
458
- }
459
- const { rule: canonical } = parseTrustRule(rawRule);
460
- const rule = canonical as TrustRule;
461
-
462
- // Re-read from disk to avoid lost updates if another call modified rules
463
- // between our last read and now (e.g. two rapid trust rule additions).
464
- cachedRules = null;
465
- const rules = [...getRules()];
466
- rules.push(rule);
467
- rules.sort(ruleOrder);
468
- cachedRules = rules;
469
- rebuildPatternCache(rules);
470
- saveToDisk(rules);
471
- notifyRulesChanged();
472
- log.info({ rule }, "Added trust rule");
473
- return rule;
474
- }
475
-
476
- function fileUpdateRule(
477
- id: string,
478
- updates: {
479
- tool?: string;
480
- pattern?: string;
481
- scope?: string;
482
- decision?: "allow" | "deny" | "ask";
483
- priority?: number;
484
- },
485
- ): TrustRule {
486
- if (updates.tool?.startsWith("__internal:"))
487
- throw new Error(
488
- `Cannot update tool to internal pseudo-rule: ${updates.tool}`,
489
- );
490
-
491
- // Re-read from disk to avoid lost updates from concurrent modifications.
492
- cachedRules = null;
493
- const rules = [...getRules()];
494
- const index = rules.findIndex((r) => r.id === id);
495
- if (index === -1) throw new Error(`Trust rule not found: ${id}`);
496
- const merged = { ...rules[index] };
497
- if (updates.tool != null) merged.tool = updates.tool;
498
- if (updates.pattern != null) merged.pattern = updates.pattern;
499
- // Only apply scope updates for scoped tools — non-scoped tools ignore scope.
500
- const effectiveTool = updates.tool ?? merged.tool;
501
- if (updates.scope != null && SCOPED_TOOLS_SET.has(effectiveTool)) {
502
- merged.scope = updates.scope;
503
- }
504
- if (updates.decision != null) merged.decision = updates.decision;
505
- if (updates.priority != null) merged.priority = updates.priority;
506
-
507
- // Mark default rules with userModifiedAt so backfillDefaults() preserves
508
- // the user's customization across upgrades instead of overwriting it.
509
- // Only set the timestamp when the merged result actually diverges from the
510
- // template — a no-op PATCH (same values) should not permanently opt a rule
511
- // out of future template migrations.
512
- const templates = getDefaultRuleTemplates();
513
- const template = templates.find((t) => t.id === id);
514
- if (template) {
515
- const diverges =
516
- merged.tool !== template.tool ||
517
- merged.pattern !== template.pattern ||
518
- ruleScope(merged) !== (template.scope ?? "everywhere") ||
519
- merged.decision !== template.decision ||
520
- merged.priority !== template.priority;
521
- if (diverges) {
522
- merged.userModifiedAt = Date.now();
523
- } else {
524
- // Rule matches the template again — clear the override marker so
525
- // future template changes are applied normally.
526
- delete merged.userModifiedAt;
527
- }
528
- }
529
-
530
- // Canonicalize through parseTrustRule so that fields invalid for the
531
- // (potentially changed) tool family are stripped. For example, if a rule's
532
- // tool is changed from "bash" to "web_fetch", executionTarget is dropped
533
- // because URL-family tools don't support target scoping.
534
- const { rule } = parseTrustRule(merged as unknown as Record<string, unknown>);
535
- rules[index] = rule;
536
- rules.sort(ruleOrder);
537
- cachedRules = rules;
538
- rebuildPatternCache(rules);
539
- saveToDisk(rules);
540
- notifyRulesChanged();
541
- log.info({ rule }, "Updated trust rule");
542
- return rule;
543
- }
544
-
545
- function fileRemoveRule(id: string): boolean {
546
- const defaultIds = new Set(getDefaultRuleTemplates().map((t) => t.id));
547
- if (defaultIds.has(id))
548
- throw new Error(`Cannot remove default trust rule: ${id}`);
549
-
550
- // Re-read from disk to avoid lost updates from concurrent modifications.
551
- cachedRules = null;
552
- const rules = [...getRules()];
553
- const index = rules.findIndex((r) => r.id === id);
554
- if (index === -1) return false;
555
- rules.splice(index, 1);
556
- cachedRules = rules;
557
- rebuildPatternCache(rules);
558
- saveToDisk(rules);
559
- notifyRulesChanged();
560
- log.info({ id }, "Removed trust rule");
561
- return true;
562
- }
563
-
564
- function matchesScope(ruleScope: string, workingDir: string): boolean {
565
- if (ruleScope === "everywhere") return true;
566
- // Strip optional trailing wildcard, then enforce a directory-boundary match
567
- // so that a rule for "/path/project" does NOT match "/path/project-evil".
568
- const prefix = ruleScope.replace(/\*$/, "").replace(/\/+$/, "");
569
- const dir = workingDir.replace(/\/+$/, "");
570
- return dir === prefix || dir.startsWith(prefix + "/");
571
- }
572
-
573
- function findRuleByDecision(
574
- tool: string,
575
- command: string,
576
- scope: string,
577
- decision: "allow" | "deny" | "ask",
578
- ): TrustRule | null {
579
- const rules = getRules();
580
- for (const rule of rules) {
581
- if (rule.tool !== tool) continue;
582
- if (rule.decision !== decision) continue;
583
- const compiled = getCompiledPattern(rule.pattern);
584
- if (!compiled || !compiled.match(command)) continue;
585
- if (!matchesScope(ruleScope(rule), scope)) continue;
586
- return rule;
587
- }
588
- return null;
589
- }
590
-
591
- /**
592
- * Check whether a rule's executionTarget constraint matches the context.
593
- *
594
- * If the rule does not specify an executionTarget it matches any target
595
- * (wildcard). If specified, it must match exactly.
596
- *
597
- * Not all trust rule families carry `executionTarget` — URL, managed-skill,
598
- * and skill-load rules never have it. For those families the check is a
599
- * no-op (wildcard match).
600
- */
601
- function matchesExecutionTarget(rule: TrustRule, ctx?: PolicyContext): boolean {
602
- if (rule.executionTarget == null) return true;
603
- return ctx?.executionTarget === rule.executionTarget;
604
- }
605
-
606
- /**
607
- * Find the highest-priority rule that matches any of the command candidates (file backend).
608
- * Rules are pre-sorted by priority descending, so the first match wins.
609
- *
610
- * When a `PolicyContext` is provided, rules that specify executionTarget
611
- * constraints are filtered accordingly. Rules without those constraints
612
- * act as wildcards and match any context.
613
- */
614
- function fileFindHighestPriorityRule(
615
- tool: string,
616
- commands: string[],
617
- scope: string,
618
- ctx?: PolicyContext,
619
- ): TrustRule | null {
620
- // Check ephemeral (task-scoped) rules first — they take precedence over
621
- // file-based rules at the same priority because they are evaluated earlier.
622
- // The ruleOrder sort (highest priority first, deny wins ties) still applies
623
- // across the combined set because ephemeral rules use a lower default
624
- // priority (50) than user rules (100), so user deny rules still win.
625
- const ephemeral = ctx?.ephemeralRules ?? [];
626
- const fileRules = getRules();
627
-
628
- // Concatenate and re-sort so priority ordering is respected across both sets.
629
- const allRules =
630
- ephemeral.length > 0
631
- ? [...ephemeral, ...fileRules].sort(ruleOrder)
632
- : fileRules;
633
-
634
- for (const rule of allRules) {
635
- if (rule.tool !== tool) continue;
636
- if (!matchesScope(ruleScope(rule), scope)) continue;
637
- if (!matchesExecutionTarget(rule, ctx)) continue;
638
- const compiled = getCompiledPattern(rule.pattern);
639
- if (!compiled) continue;
640
- for (const command of commands) {
641
- if (compiled.match(command)) {
642
- return rule;
643
- }
644
- }
645
- }
646
- return null;
647
- }
648
-
649
- function fileFindMatchingRule(
650
- tool: string,
651
- command: string,
652
- scope: string,
653
- ): TrustRule | null {
654
- return findRuleByDecision(tool, command, scope, "allow");
655
- }
656
-
657
- function fileFindDenyRule(
658
- tool: string,
659
- command: string,
660
- scope: string,
661
- ): TrustRule | null {
662
- return findRuleByDecision(tool, command, scope, "deny");
663
- }
664
-
665
- function fileGetAllRules(): TrustRule[] {
666
- return [...getRules()];
667
- }
668
-
669
- function fileClearAllRules(): void {
670
- // Reset the starter bundle flag so the bundle can be re-accepted after clear.
671
- cachedStarterBundleAccepted = false;
672
- // Re-backfill default rules so protected directory stays guarded.
673
- const rules: TrustRule[] = [];
674
- backfillDefaults(rules);
675
- rules.sort(ruleOrder);
676
- cachedRules = rules;
677
- rebuildPatternCache(rules);
678
- saveToDisk(rules);
679
- notifyRulesChanged();
680
- log.info("Cleared all user trust rules (default rules preserved)");
681
- }
682
-
683
- function fileClearCache(): void {
684
- cachedRules = null;
685
- cachedStarterBundleAccepted = null;
686
- compiledPatterns.clear();
687
- invalidPatterns.clear();
688
- }
689
-
690
- // ─── Starter approval bundle ────────────────────────────────────────────────
691
- //
692
- // A curated set of low-risk tool rules that most users would approve
693
- // individually during normal use. Accepting the bundle seeds them all at
694
- // once, reducing prompt noise in strict mode while keeping the action
695
- // explicitly opt-in.
696
-
697
- /**
698
- * Returns the starter bundle rule definitions (file backend). These cover read-only and
699
- * information-gathering tools that never mutate the filesystem or execute
700
- * arbitrary code.
701
- */
702
- function fileGetStarterBundleRules(): StarterBundleRule[] {
703
- return [
704
- // Use standalone "**" globstar — minimatch only treats ** as globstar when
705
- // it is its own path segment, so a "tool:**" prefix would collapse to
706
- // single-star behavior and fail to match candidates containing "/".
707
- // The tool field is already filtered by findHighestPriorityRule.
708
- {
709
- id: "starter:allow-file_read",
710
- tool: "file_read",
711
- pattern: "**",
712
- scope: "everywhere",
713
- decision: "allow",
714
- priority: 90,
715
- },
716
- {
717
- id: "starter:allow-glob",
718
- tool: "glob",
719
- pattern: "**",
720
- scope: "everywhere",
721
- decision: "allow",
722
- priority: 90,
723
- },
724
- {
725
- id: "starter:allow-grep",
726
- tool: "grep",
727
- pattern: "**",
728
- scope: "everywhere",
729
- decision: "allow",
730
- priority: 90,
731
- },
732
- {
733
- id: "starter:allow-list_directory",
734
- tool: "list_directory",
735
- pattern: "**",
736
- scope: "everywhere",
737
- decision: "allow",
738
- priority: 90,
739
- },
740
- {
741
- id: "starter:allow-web_search",
742
- tool: "web_search",
743
- pattern: "**",
744
- scope: "everywhere",
745
- decision: "allow",
746
- priority: 90,
747
- },
748
- {
749
- id: "starter:allow-web_fetch",
750
- tool: "web_fetch",
751
- pattern: "**",
752
- scope: "everywhere",
753
- decision: "allow",
754
- priority: 90,
755
- },
756
- ];
757
- }
758
-
759
- /** Whether the user has previously accepted the starter bundle (file backend). */
760
- function fileIsStarterBundleAccepted(): boolean {
761
- // Ensure rules are loaded (which also loads the flag from disk)
762
- getRules();
763
- return cachedStarterBundleAccepted === true;
764
- }
765
-
766
- /**
767
- * Seed the trust store with the starter bundle rules (file backend).
768
- *
769
- * Idempotent: if the bundle was already accepted, no rules are added and
770
- * `alreadyAccepted` is returned as true. Rules whose IDs already exist
771
- * (e.g. from a previous partial acceptance) are skipped individually.
772
- */
773
- function fileAcceptStarterBundle(): AcceptStarterBundleResult {
774
- // Re-read from disk to avoid lost updates.
775
- cachedRules = null;
776
- cachedStarterBundleAccepted = null;
777
- const rules = [...getRules()];
778
-
779
- if (cachedStarterBundleAccepted === true) {
780
- return { accepted: true, rulesAdded: 0, alreadyAccepted: true };
781
- }
782
-
783
- const existingIds = new Set(rules.map((r) => r.id));
784
- let added = 0;
785
-
786
- for (const template of fileGetStarterBundleRules()) {
787
- if (existingIds.has(template.id)) continue;
788
- rules.push({
789
- id: template.id,
790
- tool: template.tool,
791
- pattern: template.pattern,
792
- scope: template.scope,
793
- decision: template.decision,
794
- priority: template.priority,
795
- createdAt: Date.now(),
796
- });
797
- added++;
798
- }
799
-
800
- cachedStarterBundleAccepted = true;
801
- rules.sort(ruleOrder);
802
- cachedRules = rules;
803
- rebuildPatternCache(rules);
804
- saveToDisk(rules);
805
- notifyRulesChanged();
806
- log.info({ rulesAdded: added }, "Starter approval bundle accepted");
807
-
808
- return { accepted: true, rulesAdded: added, alreadyAccepted: false };
809
- }
810
-
811
- // ─── Backend interface ──────────────────────────────────────────────────────
812
-
813
- /**
814
- * File-based trust store backend. Wraps the module-level functions into a
815
- * `TrustStoreBackend` so callers can program against the interface.
816
- */
817
- const fileTrustStoreBackend: TrustStoreBackend = {
818
- getAllRules: fileGetAllRules,
819
- findHighestPriorityRule: fileFindHighestPriorityRule,
820
- findMatchingRule: fileFindMatchingRule,
821
- findDenyRule: fileFindDenyRule,
822
- addRule: fileAddRule,
823
- updateRule: fileUpdateRule,
824
- removeRule: fileRemoveRule,
825
- clearAllRules: fileClearAllRules,
826
- acceptStarterBundle: fileAcceptStarterBundle,
827
- isStarterBundleAccepted: fileIsStarterBundleAccepted,
828
- onRulesChanged: fileOnRulesChanged,
829
- clearCache: fileClearCache,
830
- patternMatchesCandidate: filePatternMatchesCandidate,
831
- getStarterBundleRules: fileGetStarterBundleRules,
832
- };
833
-
834
- // ─── Gateway-backed trust store adapter ─────────────────────────────────────
835
- //
836
- // When the daemon runs in a container (IS_CONTAINERIZED=true), trust rules
837
- // are stored in the gateway — not on the local filesystem. This adapter
838
- // wraps the async gateway HTTP client into the synchronous TrustStoreBackend
839
- // interface using an in-memory cache.
840
- //
841
- // Read operations serve from the cache. Write operations call the gateway
842
- // synchronously (via curl), then update the cache from the response.
843
- // A background timer refreshes the cache every CACHE_TTL_MS.
844
-
845
- const CACHE_TTL_MS = 5_000;
846
-
847
- /**
848
- * Gateway-backed trust store that caches rules in memory and refreshes
849
- * on a TTL. Satisfies the synchronous TrustStoreBackend interface by
850
- * reading from cache and writing via synchronous HTTP calls.
851
- */
852
- class GatewayTrustStoreAdapter implements TrustStoreBackend {
853
- private rules: TrustRule[] = [];
854
- private starterBundleAccepted = false;
855
- private initialized = false;
856
- private refreshTimer: ReturnType<typeof setInterval> | null = null;
857
- private readonly listeners: Array<() => void> = [];
858
-
859
- /** Pattern cache — mirrors the file-based store's approach. */
860
- private readonly gwCompiledPatterns = new Map<string, Minimatch>();
861
- private readonly gwInvalidPatterns = new Set<string>();
862
-
863
- // ── Initialization ──────────────────────────────────────────────────────
864
-
865
- /**
866
- * Ensure the cache is populated. Blocks synchronously on the first call
867
- * by fetching rules from the gateway via the sync client. Subsequent
868
- * calls are no-ops because the background refresh timer keeps the cache
869
- * current.
870
- */
871
- private ensureInitialized(): void {
872
- if (this.initialized) return;
873
- try {
874
- this.rules = trustClient.getAllRulesSync();
875
- this.rules.sort(ruleOrder);
876
- this.rebuildPatternCache();
877
- // Infer starterBundleAccepted from the fetched rules — if any starter
878
- // rule IDs are present, the bundle was accepted.
879
- const starterIds = new Set(fileGetStarterBundleRules().map((r) => r.id));
880
- this.starterBundleAccepted = this.rules.some((r) => starterIds.has(r.id));
881
- } catch (err) {
882
- log.error(
883
- { err },
884
- "Failed to load trust rules from gateway; using empty rule set",
885
- );
886
- this.rules = [];
887
- }
888
- this.initialized = true;
889
- this.startRefreshTimer();
890
- }
891
-
892
- private startRefreshTimer(): void {
893
- if (this.refreshTimer != null) return;
894
- this.refreshTimer = setInterval(() => {
895
- this.refreshCache();
896
- }, CACHE_TTL_MS);
897
- // Unref so the timer doesn't prevent the process from exiting.
898
- if (
899
- this.refreshTimer &&
900
- typeof this.refreshTimer === "object" &&
901
- "unref" in this.refreshTimer
902
- ) {
903
- (this.refreshTimer as NodeJS.Timeout).unref();
904
- }
905
- }
906
-
907
- private refreshCache(): void {
908
- try {
909
- const fresh = trustClient.getAllRulesSync();
910
- fresh.sort(ruleOrder);
911
- const oldJson = JSON.stringify(this.rules);
912
- this.rules = fresh;
913
- this.rebuildPatternCache();
914
- // Detect starter bundle acceptance
915
- const starterIds = new Set(fileGetStarterBundleRules().map((r) => r.id));
916
- this.starterBundleAccepted = this.rules.some((r) => starterIds.has(r.id));
917
- if (JSON.stringify(fresh) !== oldJson) {
918
- this.notifyListeners();
919
- }
920
- } catch (err) {
921
- log.warn(
922
- { err },
923
- "Failed to refresh trust rules from gateway; using stale cache",
924
- );
925
- }
926
- }
927
-
928
- private rebuildPatternCache(): void {
929
- this.gwCompiledPatterns.clear();
930
- this.gwInvalidPatterns.clear();
931
- for (const rule of this.rules) {
932
- if (typeof rule.pattern !== "string") continue;
933
- if (!this.gwCompiledPatterns.has(rule.pattern)) {
934
- try {
935
- this.gwCompiledPatterns.set(
936
- rule.pattern,
937
- new Minimatch(rule.pattern),
938
- );
939
- } catch {
940
- // skip invalid patterns
941
- }
942
- }
943
- }
944
- }
945
-
946
- private getCompiledPattern(pattern: string): Minimatch | null {
947
- if (this.gwInvalidPatterns.has(pattern)) return null;
948
- let compiled = this.gwCompiledPatterns.get(pattern);
949
- if (!compiled) {
950
- try {
951
- compiled = new Minimatch(pattern);
952
- this.gwCompiledPatterns.set(pattern, compiled);
953
- } catch {
954
- this.gwInvalidPatterns.add(pattern);
955
- return null;
956
- }
957
- }
958
- return compiled;
959
- }
960
-
961
- private notifyListeners(): void {
962
- for (const listener of this.listeners) {
963
- listener();
964
- }
965
- }
966
-
967
- // ── TrustStoreBackend implementation ────────────────────────────────────
968
-
969
- getAllRules(): TrustRule[] {
970
- this.ensureInitialized();
971
- return [...this.rules];
972
- }
973
-
974
- findHighestPriorityRule(
975
- tool: string,
976
- commands: string[],
977
- scope: string,
978
- ctx?: PolicyContext,
979
- ): TrustRule | null {
980
- this.ensureInitialized();
981
- const ephemeral = ctx?.ephemeralRules ?? [];
982
- const allRules =
983
- ephemeral.length > 0
984
- ? [...ephemeral, ...this.rules].sort(ruleOrder)
985
- : this.rules;
986
-
987
- for (const rule of allRules) {
988
- if (rule.tool !== tool) continue;
989
- if (!matchesScope(ruleScope(rule), scope)) continue;
990
- if (!matchesExecutionTarget(rule, ctx)) continue;
991
- const compiled = this.getCompiledPattern(rule.pattern);
992
- if (!compiled) continue;
993
- for (const command of commands) {
994
- if (compiled.match(command)) {
995
- return rule;
996
- }
997
- }
998
- }
999
- return null;
1000
- }
1001
-
1002
- findMatchingRule(
1003
- tool: string,
1004
- command: string,
1005
- scope: string,
1006
- ): TrustRule | null {
1007
- this.ensureInitialized();
1008
- for (const rule of this.rules) {
1009
- if (rule.tool !== tool) continue;
1010
- if (rule.decision !== "allow") continue;
1011
- const compiled = this.getCompiledPattern(rule.pattern);
1012
- if (!compiled || !compiled.match(command)) continue;
1013
- if (!matchesScope(ruleScope(rule), scope)) continue;
1014
- return rule;
1015
- }
1016
- return null;
1017
- }
1018
-
1019
- findDenyRule(tool: string, command: string, scope: string): TrustRule | null {
1020
- this.ensureInitialized();
1021
- for (const rule of this.rules) {
1022
- if (rule.tool !== tool) continue;
1023
- if (rule.decision !== "deny") continue;
1024
- const compiled = this.getCompiledPattern(rule.pattern);
1025
- if (!compiled || !compiled.match(command)) continue;
1026
- if (!matchesScope(ruleScope(rule), scope)) continue;
1027
- return rule;
1028
- }
1029
- return null;
1030
- }
1031
-
1032
- addRule(
1033
- tool: string,
1034
- pattern: string,
1035
- scope: string,
1036
- decision: "allow" | "deny" | "ask" = "allow",
1037
- priority: number = 100,
1038
- options?: {
1039
- executionTarget?: string;
1040
- },
1041
- ): TrustRule {
1042
- if (tool.startsWith("__internal:"))
1043
- throw new Error(
1044
- `Cannot create internal pseudo-rule via addRule: ${tool}`,
1045
- );
1046
-
1047
- // Canonicalize through the shared parser so fields invalid for the tool's
1048
- // family are stripped before sending to the gateway.
1049
- const { rule: canonical } = parseTrustRule({
1050
- id: "",
1051
- tool,
1052
- pattern,
1053
- scope,
1054
- decision,
1055
- priority,
1056
- createdAt: 0,
1057
- ...(options?.executionTarget != null
1058
- ? { executionTarget: options.executionTarget }
1059
- : {}),
1060
- });
1061
- const canonicalOpts: { executionTarget?: string } = {};
1062
- if ("executionTarget" in canonical) {
1063
- canonicalOpts.executionTarget = (
1064
- canonical as { executionTarget?: string }
1065
- ).executionTarget;
1066
- }
1067
-
1068
- this.ensureInitialized();
1069
- const rule = trustClient.addRuleSync({
1070
- tool: canonical.tool,
1071
- pattern: canonical.pattern,
1072
- // Only send scope for scoped tools — non-scoped tools omit it.
1073
- ...(SCOPED_TOOLS_SET.has(canonical.tool)
1074
- ? { scope: ruleScope(canonical) }
1075
- : {}),
1076
- decision: canonical.decision,
1077
- priority: canonical.priority,
1078
- executionTarget: canonicalOpts.executionTarget,
1079
- });
1080
- // Update local cache
1081
- this.rules = [...this.rules, rule].sort(ruleOrder);
1082
- this.rebuildPatternCache();
1083
- this.notifyListeners();
1084
- log.info({ rule }, "Added trust rule via gateway");
1085
- return rule;
1086
- }
1087
-
1088
- updateRule(
1089
- id: string,
1090
- updates: {
1091
- tool?: string;
1092
- pattern?: string;
1093
- scope?: string;
1094
- decision?: "allow" | "deny" | "ask";
1095
- priority?: number;
1096
- },
1097
- ): TrustRule {
1098
- if (updates.tool?.startsWith("__internal:"))
1099
- throw new Error(
1100
- `Cannot update tool to internal pseudo-rule: ${updates.tool}`,
1101
- );
1102
- this.ensureInitialized();
1103
-
1104
- // Send only the caller's partial updates to the gateway. The gateway's
1105
- // own updateRule merges and canonicalizes via parseTrustRule, so doing a
1106
- // full-rule merge here against the local cache would risk overwriting
1107
- // concurrent edits with stale cached values.
1108
- const rule = trustClient.updateRuleSync(id, updates);
1109
- // Update local cache
1110
- const idx = this.rules.findIndex((r) => r.id === id);
1111
- if (idx >= 0) {
1112
- this.rules[idx] = rule;
1113
- } else {
1114
- this.rules.push(rule);
1115
- }
1116
- this.rules = [...this.rules].sort(ruleOrder);
1117
- this.rebuildPatternCache();
1118
- this.notifyListeners();
1119
- log.info({ rule }, "Updated trust rule via gateway");
1120
- return rule;
1121
- }
1122
-
1123
- removeRule(id: string): boolean {
1124
- this.ensureInitialized();
1125
- const success = trustClient.removeRuleSync(id);
1126
- if (success) {
1127
- this.rules = this.rules.filter((r) => r.id !== id);
1128
- this.rebuildPatternCache();
1129
- this.notifyListeners();
1130
- log.info({ id }, "Removed trust rule via gateway");
1131
- }
1132
- return success;
1133
- }
1134
-
1135
- clearAllRules(): void {
1136
- this.ensureInitialized();
1137
- trustClient.clearRulesSync();
1138
- this.starterBundleAccepted = false;
1139
- // Re-fetch to get the default rules the gateway preserves
1140
- try {
1141
- this.rules = trustClient.getAllRulesSync();
1142
- this.rules.sort(ruleOrder);
1143
- } catch {
1144
- this.rules = [];
1145
- }
1146
- this.rebuildPatternCache();
1147
- this.notifyListeners();
1148
- log.info("Cleared all user trust rules via gateway");
1149
- }
1150
-
1151
- acceptStarterBundle(): AcceptStarterBundleResult {
1152
- this.ensureInitialized();
1153
- const result = trustClient.acceptStarterBundleSync();
1154
- this.starterBundleAccepted = true;
1155
- // Refresh cache to include the newly added starter rules
1156
- try {
1157
- this.rules = trustClient.getAllRulesSync();
1158
- this.rules.sort(ruleOrder);
1159
- } catch {
1160
- // Keep stale cache
1161
- }
1162
- this.rebuildPatternCache();
1163
- this.notifyListeners();
1164
- log.info(
1165
- { rulesAdded: result.rulesAdded },
1166
- "Starter approval bundle accepted via gateway",
1167
- );
1168
- return { ...result, alreadyAccepted: result.rulesAdded === 0 };
1169
- }
1170
-
1171
- isStarterBundleAccepted(): boolean {
1172
- this.ensureInitialized();
1173
- return this.starterBundleAccepted;
1174
- }
1175
-
1176
- onRulesChanged(listener: () => void): void {
1177
- this.listeners.push(listener);
1178
- }
1179
-
1180
- clearCache(): void {
1181
- this.initialized = false;
1182
- this.rules = [];
1183
- this.starterBundleAccepted = false;
1184
- this.gwCompiledPatterns.clear();
1185
- this.gwInvalidPatterns.clear();
1186
- if (this.refreshTimer != null) {
1187
- clearInterval(this.refreshTimer);
1188
- this.refreshTimer = null;
1189
- }
1190
- }
1191
-
1192
- patternMatchesCandidate(pattern: string, candidate: string): boolean {
1193
- const compiled = this.getCompiledPattern(pattern);
1194
- if (!compiled) return false;
1195
- return compiled.match(candidate);
1196
- }
1197
-
1198
- getStarterBundleRules(): StarterBundleRule[] {
1199
- // Starter bundle definitions are static — same regardless of backend.
1200
- return fileGetStarterBundleRules();
1201
- }
1202
- }
1203
-
1204
- /** Singleton gateway adapter instance (lazily created). */
1205
- let gatewayTrustStoreBackend: GatewayTrustStoreAdapter | null = null;
1206
-
1207
- function getGatewayTrustStore(): GatewayTrustStoreAdapter {
1208
- if (!gatewayTrustStoreBackend) {
1209
- gatewayTrustStoreBackend = new GatewayTrustStoreAdapter();
1210
- }
1211
- return gatewayTrustStoreBackend;
1212
- }
1213
-
1214
- /**
1215
- * Returns the active trust store backend.
1216
- *
1217
- * When `IS_CONTAINERIZED=true`, returns a gateway-backed adapter that
1218
- * proxies all trust operations through the gateway HTTP API.
1219
- *
1220
- * When `IS_CONTAINERIZED=false`, returns the file-based implementation.
1221
- */
1222
- export function getTrustStore(): TrustStoreBackend {
1223
- if (getIsContainerized()) {
1224
- return getGatewayTrustStore();
1225
- }
1226
- return fileTrustStoreBackend;
1227
- }
1228
-
1229
- // ─── Module-level exports that delegate through getTrustStore() ─────────────
1230
- //
1231
- // All existing callers import these functions directly. By delegating through
1232
- // getTrustStore(), they automatically get the right backend (file-based or
1233
- // gateway-backed) without changing their imports.
1234
-
1235
- export function addRule(
1236
- tool: string,
1237
- pattern: string,
1238
- scope: string,
1239
- decision: "allow" | "deny" | "ask" = "allow",
1240
- priority: number = 100,
1241
- options?: {
1242
- executionTarget?: string;
1243
- },
1244
- ): TrustRule {
1245
- return getTrustStore().addRule(
1246
- tool,
1247
- pattern,
1248
- scope,
1249
- decision,
1250
- priority,
1251
- options,
1252
- );
1253
- }
1254
-
1255
- export function updateRule(
1256
- id: string,
1257
- updates: {
1258
- tool?: string;
1259
- pattern?: string;
1260
- scope?: string;
1261
- decision?: "allow" | "deny" | "ask";
1262
- priority?: number;
1263
- },
1264
- ): TrustRule {
1265
- return getTrustStore().updateRule(id, updates);
1266
- }
1267
-
1268
- export function removeRule(id: string): boolean {
1269
- return getTrustStore().removeRule(id);
1270
- }
1271
-
1272
- export function clearAllRules(): void {
1273
- getTrustStore().clearAllRules();
1274
- }
1275
-
1276
- export function getAllRules(): TrustRule[] {
1277
- return getTrustStore().getAllRules();
1278
- }
1279
-
1280
- export function findHighestPriorityRule(
1281
- tool: string,
1282
- commands: string[],
1283
- scope: string,
1284
- ctx?: PolicyContext,
1285
- ): TrustRule | null {
1286
- return getTrustStore().findHighestPriorityRule(tool, commands, scope, ctx);
1287
- }
1288
-
1289
- export function findMatchingRule(
1290
- tool: string,
1291
- command: string,
1292
- scope: string,
1293
- ): TrustRule | null {
1294
- return getTrustStore().findMatchingRule(tool, command, scope);
1295
- }
1296
-
1297
- export function findDenyRule(
1298
- tool: string,
1299
- command: string,
1300
- scope: string,
1301
- ): TrustRule | null {
1302
- return getTrustStore().findDenyRule(tool, command, scope);
1303
- }
1304
-
1305
- export function acceptStarterBundle(): AcceptStarterBundleResult {
1306
- return getTrustStore().acceptStarterBundle();
1307
- }
1308
-
1309
- export function isStarterBundleAccepted(): boolean {
1310
- return getTrustStore().isStarterBundleAccepted();
1311
- }
1312
-
1313
- export function getStarterBundleRules(): StarterBundleRule[] {
1314
- return getTrustStore().getStarterBundleRules();
1315
- }
1316
-
1317
- export function onRulesChanged(listener: () => void): void {
1318
- getTrustStore().onRulesChanged(listener);
1319
- }
1320
-
1321
- export function clearCache(): void {
1322
- getTrustStore().clearCache();
1323
- }
1324
-
1325
- export function patternMatchesCandidate(
1326
- pattern: string,
1327
- candidate: string,
1328
- ): boolean {
1329
- return getTrustStore().patternMatchesCandidate(pattern, candidate);
1330
- }