@vellumai/assistant 0.4.26 → 0.4.30

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 (1360) hide show
  1. package/.env.example +2 -2
  2. package/AGENTS.md +5 -0
  3. package/ARCHITECTURE.md +207 -105
  4. package/Dockerfile +1 -1
  5. package/README.md +111 -113
  6. package/bun.lock +0 -3
  7. package/docs/architecture/integrations.md +0 -1
  8. package/docs/architecture/memory.md +100 -63
  9. package/docs/error-handling.md +71 -0
  10. package/docs/runbook-trusted-contacts.md +89 -52
  11. package/docs/trusted-contact-access.md +48 -46
  12. package/package.json +3 -3
  13. package/scripts/compare-benchmarks.sh +12 -5
  14. package/scripts/ipc/check-swift-decoder-drift.ts +5 -3
  15. package/scripts/test.sh +89 -5
  16. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +50 -37
  17. package/src/__tests__/access-request-decision.test.ts +0 -1
  18. package/src/__tests__/account-registry.test.ts +1 -1
  19. package/src/__tests__/actor-token-service.test.ts +40 -26
  20. package/src/__tests__/agent-loop-thinking.test.ts +29 -13
  21. package/src/__tests__/agent-loop.test.ts +2 -1
  22. package/src/__tests__/app-builder-tool-scripts.test.ts +1 -1
  23. package/src/__tests__/app-executors.test.ts +7 -17
  24. package/src/__tests__/approval-routes-http.test.ts +2 -2
  25. package/src/__tests__/asset-materialize-tool.test.ts +7 -7
  26. package/src/__tests__/asset-search-tool.test.ts +7 -7
  27. package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -10
  28. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  29. package/src/__tests__/browser-skill-endstate.test.ts +10 -1
  30. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +218 -0
  31. package/src/__tests__/call-controller.test.ts +99 -69
  32. package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +157 -114
  34. package/src/__tests__/channel-approval.test.ts +8 -0
  35. package/src/__tests__/channel-approvals.test.ts +39 -1
  36. package/src/__tests__/channel-guardian.test.ts +176 -275
  37. package/src/__tests__/channel-readiness-service.test.ts +6 -2
  38. package/src/__tests__/channel-reply-delivery.test.ts +33 -2
  39. package/src/__tests__/channel-retry-sweep.test.ts +14 -14
  40. package/src/__tests__/checker.test.ts +12 -31
  41. package/src/__tests__/claude-code-tool-profiles.test.ts +1 -1
  42. package/src/__tests__/commit-message-enrichment-service.test.ts +71 -59
  43. package/src/__tests__/compaction.benchmark.test.ts +6 -2
  44. package/src/__tests__/computer-use-tools.test.ts +1 -1
  45. package/src/__tests__/config-schema.test.ts +66 -7
  46. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -29
  47. package/src/__tests__/contacts-tools.test.ts +63 -2
  48. package/src/__tests__/context-overflow-approval.test.ts +141 -0
  49. package/src/__tests__/context-overflow-policy.test.ts +171 -0
  50. package/src/__tests__/context-overflow-reducer.test.ts +533 -0
  51. package/src/__tests__/context-window-manager.test.ts +97 -0
  52. package/src/__tests__/conversation-attention-telegram.test.ts +38 -46
  53. package/src/__tests__/conversation-pairing.test.ts +2 -2
  54. package/src/__tests__/conversation-routes-guardian-reply.test.ts +214 -10
  55. package/src/__tests__/conversation-routes.test.ts +4 -7
  56. package/src/__tests__/credential-broker-browser-fill.test.ts +13 -2
  57. package/src/__tests__/credential-security-e2e.test.ts +1 -1
  58. package/src/__tests__/credential-security-invariants.test.ts +1 -1
  59. package/src/__tests__/credential-vault-unit.test.ts +1 -1
  60. package/src/__tests__/credential-vault.test.ts +11 -8
  61. package/src/__tests__/daemon-lifecycle.test.ts +2 -2
  62. package/src/__tests__/daemon-server-session-init.test.ts +6 -6
  63. package/src/__tests__/delete-managed-skill-tool.test.ts +1 -1
  64. package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -2
  65. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +9 -0
  66. package/src/__tests__/emit-signal-routing-intent.test.ts +4 -0
  67. package/src/__tests__/encrypted-store.test.ts +10 -7
  68. package/src/__tests__/ephemeral-permissions.test.ts +3 -3
  69. package/src/__tests__/file-edit-tool.test.ts +1 -1
  70. package/src/__tests__/file-read-tool.test.ts +1 -1
  71. package/src/__tests__/file-write-tool.test.ts +1 -1
  72. package/src/__tests__/fixtures/credential-security-fixtures.ts +87 -64
  73. package/src/__tests__/fixtures/media-reuse-fixtures.ts +37 -31
  74. package/src/__tests__/fixtures/mock-signup-server.ts +171 -115
  75. package/src/__tests__/fixtures/proxy-fixtures.ts +39 -39
  76. package/src/__tests__/followup-tools.test.ts +1 -1
  77. package/src/__tests__/gateway-only-guard.test.ts +4 -0
  78. package/src/__tests__/gemini-image-service.test.ts +2 -2
  79. package/src/__tests__/guardian-actions-endpoint.test.ts +543 -1
  80. package/src/__tests__/guardian-control-plane-policy.test.ts +15 -15
  81. package/src/__tests__/guardian-dispatch.test.ts +79 -1
  82. package/src/__tests__/guardian-grant-minting.test.ts +20 -20
  83. package/src/__tests__/guardian-outbound-http.test.ts +1 -2
  84. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -41
  85. package/src/__tests__/guardian-routing-invariants.test.ts +36 -16
  86. package/src/__tests__/guardian-routing-state.test.ts +36 -52
  87. package/src/__tests__/guardian-verification-intent-routing.test.ts +4 -6
  88. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +6 -8
  89. package/src/__tests__/handle-user-message-secret-resume.test.ts +39 -1
  90. package/src/__tests__/handlers-cu-observation-blob.test.ts +21 -10
  91. package/src/__tests__/handlers-telegram-config.test.ts +14 -14
  92. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +23 -2
  93. package/src/__tests__/headless-browser-interactions.test.ts +1 -1
  94. package/src/__tests__/headless-browser-navigate.test.ts +1 -1
  95. package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
  96. package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
  97. package/src/__tests__/heartbeat-service.test.ts +45 -2
  98. package/src/__tests__/host-file-edit-tool.test.ts +1 -1
  99. package/src/__tests__/host-file-read-tool.test.ts +1 -1
  100. package/src/__tests__/host-file-write-tool.test.ts +1 -1
  101. package/src/__tests__/host-shell-tool.test.ts +1 -1
  102. package/src/__tests__/inbound-invite-redemption.test.ts +17 -19
  103. package/src/__tests__/ingress-reconcile.test.ts +2 -2
  104. package/src/__tests__/integrations-cli.test.ts +232 -0
  105. package/src/__tests__/intent-routing.test.ts +7 -5
  106. package/src/__tests__/invite-redemption-service.test.ts +5 -4
  107. package/src/__tests__/{ingress-routes-http.test.ts → invite-routes-http.test.ts} +42 -321
  108. package/src/__tests__/ipc-snapshot.test.ts +32 -31
  109. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -1
  110. package/src/__tests__/mcp-cli.test.ts +136 -57
  111. package/src/__tests__/mcp-client-auth.test.ts +95 -0
  112. package/src/__tests__/media-generate-image.test.ts +2 -2
  113. package/src/__tests__/media-reuse-story.e2e.test.ts +8 -8
  114. package/src/__tests__/memory-regressions.test.ts +6 -6
  115. package/src/__tests__/messaging-send-tool.test.ts +1 -1
  116. package/src/__tests__/migration-cross-version-compatibility.test.ts +1855 -0
  117. package/src/__tests__/migration-export-http.test.ts +540 -0
  118. package/src/__tests__/migration-import-commit-http.test.ts +823 -0
  119. package/src/__tests__/migration-import-preflight-http.test.ts +755 -0
  120. package/src/__tests__/migration-parity-persistence.test.ts +1854 -0
  121. package/src/__tests__/migration-transport.test.ts +904 -0
  122. package/src/__tests__/migration-validate-http.test.ts +698 -0
  123. package/src/__tests__/migration-wizard.test.ts +1289 -0
  124. package/src/__tests__/nl-approval-parser.test.ts +305 -0
  125. package/src/__tests__/non-member-access-request.test.ts +17 -17
  126. package/src/__tests__/notification-decision-strategy.test.ts +110 -2
  127. package/src/__tests__/notification-deep-link.test.ts +18 -0
  128. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  129. package/src/__tests__/oauth-provider-profiles.test.ts +34 -0
  130. package/src/__tests__/oauth2-gateway-transport.test.ts +1 -1
  131. package/src/__tests__/playbook-execution.test.ts +1 -1
  132. package/src/__tests__/playbook-tools.test.ts +1 -1
  133. package/src/__tests__/provider-error-scenarios.test.ts +68 -0
  134. package/src/__tests__/provider-streaming.benchmark.test.ts +3 -1
  135. package/src/__tests__/proxy-approval-callback.test.ts +1 -1
  136. package/src/__tests__/qdrant-manager.test.ts +40 -11
  137. package/src/__tests__/rebind-secrets-screen.test.ts +839 -0
  138. package/src/__tests__/recording-handler.test.ts +2 -2
  139. package/src/__tests__/recording-intent-handler.test.ts +3 -3
  140. package/src/__tests__/recording-state-machine.test.ts +2 -2
  141. package/src/__tests__/relay-server.test.ts +507 -228
  142. package/src/__tests__/reminder-store.test.ts +8 -0
  143. package/src/__tests__/reminder.test.ts +8 -0
  144. package/src/__tests__/{resolve-guardian-trust-class.test.ts → resolve-trust-class.test.ts} +11 -17
  145. package/src/__tests__/retry-after-extraction.test.ts +111 -0
  146. package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -1
  147. package/src/__tests__/schedule-tools.test.ts +1 -1
  148. package/src/__tests__/script-proxy-certs.test.ts +1 -1
  149. package/src/__tests__/script-proxy-connect-tunnel.test.ts +2 -3
  150. package/src/__tests__/script-proxy-decision-trace.test.ts +2 -2
  151. package/src/__tests__/script-proxy-http-forwarder.test.ts +1 -1
  152. package/src/__tests__/script-proxy-injection-runtime.test.ts +5 -5
  153. package/src/__tests__/script-proxy-mitm-handler.test.ts +4 -4
  154. package/src/__tests__/script-proxy-policy-runtime.test.ts +2 -2
  155. package/src/__tests__/script-proxy-policy.test.ts +2 -2
  156. package/src/__tests__/script-proxy-profile-template-fallback.test.ts +127 -0
  157. package/src/__tests__/script-proxy-session-manager.test.ts +4 -7
  158. package/src/__tests__/script-proxy-session-runtime.test.ts +1 -6
  159. package/src/__tests__/secret-onetime-send.test.ts +4 -4
  160. package/src/__tests__/secret-scanner-executor.test.ts +2 -2
  161. package/src/__tests__/send-endpoint-busy.test.ts +11 -9
  162. package/src/__tests__/send-notification-tool.test.ts +2 -2
  163. package/src/__tests__/session-abort-tool-results.test.ts +17 -2
  164. package/src/__tests__/session-agent-loop.test.ts +456 -35
  165. package/src/__tests__/session-confirmation-signals.test.ts +3 -2
  166. package/src/__tests__/session-conflict-gate.test.ts +20 -3
  167. package/src/__tests__/session-init.benchmark.test.ts +2 -2
  168. package/src/__tests__/session-load-history-repair.test.ts +7 -7
  169. package/src/__tests__/session-media-retry.test.ts +147 -0
  170. package/src/__tests__/session-pre-run-repair.test.ts +17 -2
  171. package/src/__tests__/session-profile-injection.test.ts +20 -3
  172. package/src/__tests__/session-provider-retry-repair.test.ts +86 -6
  173. package/src/__tests__/session-queue.test.ts +33 -18
  174. package/src/__tests__/session-runtime-assembly.test.ts +147 -1
  175. package/src/__tests__/session-runtime-workspace.test.ts +40 -0
  176. package/src/__tests__/session-slash-known.test.ts +21 -3
  177. package/src/__tests__/session-slash-queue.test.ts +17 -2
  178. package/src/__tests__/session-slash-unknown.test.ts +17 -2
  179. package/src/__tests__/session-surfaces-deselection.test.ts +208 -0
  180. package/src/__tests__/session-workspace-cache-state.test.ts +2 -2
  181. package/src/__tests__/session-workspace-injection.test.ts +17 -2
  182. package/src/__tests__/session-workspace-tool-tracking.test.ts +17 -2
  183. package/src/__tests__/shell-credential-ref.test.ts +1 -1
  184. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  185. package/src/__tests__/skill-feature-flags-integration.test.ts +9 -5
  186. package/src/__tests__/skill-feature-flags.test.ts +18 -12
  187. package/src/__tests__/skill-load-feature-flag.test.ts +5 -4
  188. package/src/__tests__/skill-load-tool.test.ts +1 -1
  189. package/src/__tests__/skill-script-runner-host.test.ts +1 -1
  190. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -1
  191. package/src/__tests__/skill-script-runner.test.ts +1 -1
  192. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  193. package/src/__tests__/slack-block-formatting.test.ts +100 -0
  194. package/src/__tests__/slack-inbound-verification.test.ts +346 -0
  195. package/src/__tests__/slack-reaction-approvals.test.ts +77 -0
  196. package/src/__tests__/slack-skill.test.ts +4 -2
  197. package/src/__tests__/starter-task-flow.test.ts +0 -1
  198. package/src/__tests__/subagent-tools.test.ts +3 -3
  199. package/src/__tests__/swarm-recursion.test.ts +1 -1
  200. package/src/__tests__/swarm-session-integration.test.ts +1 -1
  201. package/src/__tests__/swarm-tool.test.ts +1 -1
  202. package/src/__tests__/task-management-tools.test.ts +1 -1
  203. package/src/__tests__/task-tools.test.ts +1 -1
  204. package/src/__tests__/terminal-tools.test.ts +1 -1
  205. package/src/__tests__/test-support/browser-skill-harness.ts +39 -27
  206. package/src/__tests__/test-support/computer-use-skill-harness.ts +14 -14
  207. package/src/__tests__/tool-approval-handler.test.ts +15 -15
  208. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -1
  209. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
  210. package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
  211. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  212. package/src/__tests__/tool-executor.test.ts +23 -182
  213. package/src/__tests__/tool-grant-request-escalation.test.ts +11 -11
  214. package/src/__tests__/tool-permission-simulate-handler.test.ts +4 -4
  215. package/src/__tests__/transfer-progress-screen.test.ts +1180 -0
  216. package/src/__tests__/trust-context-guards.test.ts +25 -29
  217. package/src/__tests__/trusted-contact-approval-notifier.test.ts +23 -21
  218. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +37 -40
  219. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +29 -25
  220. package/src/__tests__/trusted-contact-multichannel.test.ts +25 -24
  221. package/src/__tests__/trusted-contact-verification.test.ts +64 -76
  222. package/src/__tests__/turn-commit.test.ts +18 -18
  223. package/src/__tests__/twilio-provider.test.ts +7 -7
  224. package/src/__tests__/validation-results-screen.test.ts +1107 -0
  225. package/src/__tests__/view-image-tool.test.ts +1 -1
  226. package/src/__tests__/voice-invite-redemption.test.ts +4 -3
  227. package/src/__tests__/voice-scoped-grant-consumer.test.ts +12 -12
  228. package/src/__tests__/voice-session-bridge.test.ts +24 -24
  229. package/src/agent/attachments.ts +3 -1
  230. package/src/agent/loop.ts +13 -13
  231. package/src/agent/message-types.ts +13 -7
  232. package/src/amazon/cart.ts +59 -32
  233. package/src/amazon/checkout.ts +25 -14
  234. package/src/amazon/client.ts +61 -58
  235. package/src/amazon/product-details.ts +3 -3
  236. package/src/amazon/request-extractor.ts +46 -31
  237. package/src/amazon/search.ts +6 -4
  238. package/src/amazon/session.ts +33 -24
  239. package/src/approvals/AGENTS.md +26 -0
  240. package/src/approvals/approval-primitive.ts +87 -64
  241. package/src/approvals/guardian-decision-primitive.ts +172 -81
  242. package/src/approvals/guardian-request-resolvers.ts +262 -155
  243. package/src/autonomy/autonomy-resolver.ts +7 -5
  244. package/src/autonomy/autonomy-store.ts +34 -19
  245. package/src/autonomy/disposition-mapper.ts +5 -5
  246. package/src/autonomy/index.ts +6 -6
  247. package/src/autonomy/types.ts +7 -3
  248. package/src/browser-extension-relay/client.ts +50 -19
  249. package/src/browser-extension-relay/protocol.ts +11 -11
  250. package/src/browser-extension-relay/server.ts +45 -20
  251. package/src/bundler/app-bundler.ts +75 -50
  252. package/src/bundler/bundle-scanner.ts +145 -41
  253. package/src/bundler/bundle-signer.ts +16 -14
  254. package/src/bundler/signature-verifier.ts +36 -33
  255. package/src/calls/call-constants.ts +10 -3
  256. package/src/calls/call-controller.ts +473 -214
  257. package/src/calls/call-conversation-messages.ts +25 -15
  258. package/src/calls/call-domain.ts +401 -148
  259. package/src/calls/call-pointer-message-composer.ts +26 -21
  260. package/src/calls/call-pointer-messages.ts +52 -28
  261. package/src/calls/call-recovery.ts +53 -37
  262. package/src/calls/call-state-machine.ts +37 -7
  263. package/src/calls/call-state.ts +35 -13
  264. package/src/calls/call-store.ts +165 -77
  265. package/src/calls/elevenlabs-client.ts +39 -20
  266. package/src/calls/guardian-action-sweep.ts +42 -24
  267. package/src/calls/guardian-dispatch.ts +79 -56
  268. package/src/calls/guardian-question-copy.ts +28 -23
  269. package/src/calls/relay-server.ts +1149 -532
  270. package/src/calls/speaker-identification.ts +21 -15
  271. package/src/calls/twilio-config.ts +34 -17
  272. package/src/calls/twilio-provider.ts +108 -55
  273. package/src/calls/twilio-rest.ts +212 -100
  274. package/src/calls/twilio-routes.ts +165 -92
  275. package/src/calls/types.ts +55 -7
  276. package/src/calls/voice-quality.ts +6 -4
  277. package/src/calls/voice-session-bridge.ts +181 -133
  278. package/src/channels/config.ts +18 -14
  279. package/src/channels/types.ts +38 -10
  280. package/src/cli/amazon.ts +333 -227
  281. package/src/cli/config-commands.ts +236 -146
  282. package/src/cli/core-commands.ts +403 -329
  283. package/src/cli/email-guardrails.ts +38 -19
  284. package/src/cli/email.ts +207 -153
  285. package/src/cli/influencer.ts +58 -56
  286. package/src/cli/integrations.ts +306 -0
  287. package/src/cli/ipc-client.ts +24 -19
  288. package/src/cli/map.ts +176 -129
  289. package/src/cli/mcp.ts +260 -152
  290. package/src/cli/sequence.ts +165 -107
  291. package/src/cli/twitter.ts +302 -218
  292. package/src/cli.ts +418 -279
  293. package/src/commands/cc-command-registry.ts +52 -27
  294. package/src/config/agent-schema.ts +217 -134
  295. package/src/config/assistant-feature-flags.ts +23 -18
  296. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +19 -0
  297. package/src/config/bundled-skills/app-builder/SKILL.md +193 -1500
  298. package/src/config/bundled-skills/app-builder/TOOLS.json +70 -18
  299. package/src/config/bundled-skills/app-builder/tools/app-create.ts +7 -4
  300. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +6 -3
  301. package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +7 -4
  302. package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +6 -3
  303. package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +6 -3
  304. package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +7 -4
  305. package/src/config/bundled-skills/app-builder/tools/app-list.ts +6 -3
  306. package/src/config/bundled-skills/app-builder/tools/app-query.ts +6 -3
  307. package/src/config/bundled-skills/app-builder/tools/app-update.ts +6 -3
  308. package/src/config/bundled-skills/browser/TOOLS.json +59 -2
  309. package/src/config/bundled-skills/browser/tools/browser-click.ts +5 -2
  310. package/src/config/bundled-skills/browser/tools/browser-close.ts +5 -2
  311. package/src/config/bundled-skills/browser/tools/browser-extract.ts +5 -2
  312. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +5 -2
  313. package/src/config/bundled-skills/browser/tools/browser-hover.ts +5 -2
  314. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +5 -2
  315. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +5 -2
  316. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +5 -2
  317. package/src/config/bundled-skills/browser/tools/browser-scroll.ts +5 -2
  318. package/src/config/bundled-skills/browser/tools/browser-select-option.ts +5 -2
  319. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +5 -2
  320. package/src/config/bundled-skills/browser/tools/browser-type.ts +5 -2
  321. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +13 -6
  322. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +5 -2
  323. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +4 -0
  324. package/src/config/bundled-skills/claude-code/TOOLS.json +4 -0
  325. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +5 -2
  326. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  327. package/src/config/bundled-skills/computer-use/TOOLS.json +50 -2
  328. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +6 -3
  329. package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +6 -3
  330. package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +10 -3
  331. package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +6 -3
  332. package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +6 -3
  333. package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +6 -3
  334. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +10 -3
  335. package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +6 -3
  336. package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +10 -3
  337. package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +10 -3
  338. package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +6 -3
  339. package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +6 -3
  340. package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +6 -3
  341. package/src/config/bundled-skills/configure-settings/SKILL.md +28 -14
  342. package/src/config/bundled-skills/contacts/SKILL.md +453 -15
  343. package/src/config/bundled-skills/contacts/TOOLS.json +22 -2
  344. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +79 -20
  345. package/src/config/bundled-skills/contacts/tools/contact-search.ts +55 -18
  346. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +64 -19
  347. package/src/config/bundled-skills/document/TOOLS.json +8 -0
  348. package/src/config/bundled-skills/document/tools/document-create.ts +5 -2
  349. package/src/config/bundled-skills/document/tools/document-update.ts +5 -2
  350. package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -7
  351. package/src/config/bundled-skills/email-setup/SKILL.md +12 -9
  352. package/src/config/bundled-skills/followups/TOOLS.json +12 -0
  353. package/src/config/bundled-skills/followups/tools/followup-create.ts +5 -2
  354. package/src/config/bundled-skills/followups/tools/followup-list.ts +5 -2
  355. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +5 -2
  356. package/src/config/bundled-skills/google-calendar/TOOLS.json +124 -26
  357. package/src/config/bundled-skills/google-calendar/calendar-client.ts +44 -32
  358. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +11 -5
  359. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +13 -7
  360. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +11 -5
  361. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +13 -7
  362. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +28 -12
  363. package/src/config/bundled-skills/google-calendar/tools/shared.ts +6 -4
  364. package/src/config/bundled-skills/google-calendar/types.ts +3 -3
  365. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +88 -33
  366. package/src/config/bundled-skills/image-studio/TOOLS.json +12 -2
  367. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +48 -25
  368. package/src/config/bundled-skills/knowledge-graph/TOOLS.json +13 -3
  369. package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +60 -35
  370. package/src/config/bundled-skills/mcp-setup/SKILL.md +75 -0
  371. package/src/config/bundled-skills/media-processing/SKILL.md +55 -15
  372. package/src/config/bundled-skills/media-processing/TOOLS.json +48 -2
  373. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +12 -10
  374. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +34 -19
  375. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +82 -66
  376. package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +148 -0
  377. package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +1 -1
  378. package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +8 -3
  379. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +117 -53
  380. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +273 -0
  381. package/src/config/bundled-skills/media-processing/services/preprocess.ts +185 -97
  382. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +32 -27
  383. package/src/config/bundled-skills/media-processing/services/reduce.ts +101 -24
  384. package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +121 -55
  385. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +58 -24
  386. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +198 -92
  387. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +98 -70
  388. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +59 -19
  389. package/src/config/bundled-skills/media-processing/tools/media-status.ts +26 -10
  390. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +29 -14
  391. package/src/config/bundled-skills/messaging/SKILL.md +7 -5
  392. package/src/config/bundled-skills/messaging/TOOLS.json +232 -186
  393. package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +31 -13
  394. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +16 -10
  395. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +18 -9
  396. package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +23 -16
  397. package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +28 -12
  398. package/src/config/bundled-skills/messaging/tools/gmail-filters.ts +41 -21
  399. package/src/config/bundled-skills/messaging/tools/gmail-follow-up.ts +44 -23
  400. package/src/config/bundled-skills/messaging/tools/gmail-forward.ts +73 -33
  401. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +15 -9
  402. package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +22 -14
  403. package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +99 -50
  404. package/src/config/bundled-skills/messaging/tools/gmail-send-draft.ts +14 -8
  405. package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +63 -44
  406. package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +90 -46
  407. package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +43 -22
  408. package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +15 -9
  409. package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +51 -22
  410. package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +62 -26
  411. package/src/config/bundled-skills/messaging/tools/gmail-vacation.ts +34 -19
  412. package/src/config/bundled-skills/messaging/tools/google-contacts.ts +32 -16
  413. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +10 -4
  414. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +91 -47
  415. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +21 -9
  416. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +9 -3
  417. package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +30 -17
  418. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +10 -4
  419. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +14 -6
  420. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +16 -5
  421. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +63 -36
  422. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +10 -4
  423. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +30 -12
  424. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +48 -29
  425. package/src/config/bundled-skills/messaging/tools/scan-result-store.ts +20 -6
  426. package/src/config/bundled-skills/messaging/tools/send-notification.ts +1 -1
  427. package/src/config/bundled-skills/messaging/tools/sequence-analytics.ts +59 -22
  428. package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +13 -7
  429. package/src/config/bundled-skills/messaging/tools/sequence-create.ts +27 -12
  430. package/src/config/bundled-skills/messaging/tools/sequence-delete.ts +14 -6
  431. package/src/config/bundled-skills/messaging/tools/sequence-enroll.ts +30 -11
  432. package/src/config/bundled-skills/messaging/tools/sequence-enrollment-list.ts +16 -8
  433. package/src/config/bundled-skills/messaging/tools/sequence-get.ts +31 -13
  434. package/src/config/bundled-skills/messaging/tools/sequence-import.ts +38 -22
  435. package/src/config/bundled-skills/messaging/tools/sequence-list.ts +16 -7
  436. package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +29 -10
  437. package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +16 -8
  438. package/src/config/bundled-skills/messaging/tools/sequence-update.ts +35 -16
  439. package/src/config/bundled-skills/messaging/tools/shared.ts +26 -12
  440. package/src/config/bundled-skills/notifications/SKILL.md +3 -2
  441. package/src/config/bundled-skills/notifications/TOOLS.json +7 -13
  442. package/src/config/bundled-skills/notifications/tools/send-notification.ts +69 -34
  443. package/src/config/bundled-skills/notifications/tools/shared.ts +1 -1
  444. package/src/config/bundled-skills/phone-calls/SKILL.md +46 -48
  445. package/src/config/bundled-skills/phone-calls/TOOLS.json +13 -1
  446. package/src/config/bundled-skills/phone-calls/tools/call-end.ts +1 -1
  447. package/src/config/bundled-skills/phone-calls/tools/call-start.ts +1 -1
  448. package/src/config/bundled-skills/phone-calls/tools/call-status.ts +1 -1
  449. package/src/config/bundled-skills/playbooks/TOOLS.json +16 -0
  450. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +91 -51
  451. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +30 -16
  452. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +66 -27
  453. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +89 -42
  454. package/src/config/bundled-skills/public-ingress/SKILL.md +26 -19
  455. package/src/config/bundled-skills/reminder/TOOLS.json +15 -2
  456. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +5 -2
  457. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +5 -2
  458. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +5 -2
  459. package/src/config/bundled-skills/schedule/SKILL.md +33 -15
  460. package/src/config/bundled-skills/schedule/TOOLS.json +17 -1
  461. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +5 -2
  462. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +5 -2
  463. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +5 -2
  464. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +5 -2
  465. package/src/config/bundled-skills/screen-recording/SKILL.md +11 -3
  466. package/src/config/bundled-skills/self-upgrade/SKILL.md +9 -8
  467. package/src/config/bundled-skills/slack/SKILL.md +30 -1
  468. package/src/config/bundled-skills/slack/TOOLS.json +122 -17
  469. package/src/config/bundled-skills/slack/tools/shared.ts +7 -5
  470. package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +11 -5
  471. package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +11 -5
  472. package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +146 -0
  473. package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +46 -16
  474. package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +11 -5
  475. package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +28 -0
  476. package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +12 -6
  477. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +120 -0
  478. package/src/config/bundled-skills/slack-app-setup/SKILL.md +200 -0
  479. package/src/config/bundled-skills/sms-setup/SKILL.md +5 -8
  480. package/src/config/bundled-skills/subagent/TOOLS.json +22 -2
  481. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +5 -2
  482. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +5 -2
  483. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +5 -2
  484. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +5 -2
  485. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +5 -2
  486. package/src/config/bundled-skills/tasks/TOOLS.json +86 -14
  487. package/src/config/bundled-skills/tasks/tools/task-delete.ts +5 -2
  488. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +5 -2
  489. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +5 -2
  490. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +5 -2
  491. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +5 -2
  492. package/src/config/bundled-skills/tasks/tools/task-list.ts +5 -2
  493. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +5 -2
  494. package/src/config/bundled-skills/tasks/tools/task-run.ts +5 -2
  495. package/src/config/bundled-skills/tasks/tools/task-save.ts +5 -2
  496. package/src/config/bundled-skills/telegram-setup/SKILL.md +7 -8
  497. package/src/config/bundled-skills/transcribe/TOOLS.json +4 -0
  498. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +232 -127
  499. package/src/config/bundled-skills/twilio-setup/SKILL.md +7 -12
  500. package/src/config/bundled-skills/twitter/SKILL.md +19 -2
  501. package/src/config/bundled-skills/voice-setup/SKILL.md +5 -5
  502. package/src/config/bundled-skills/watcher/TOOLS.json +20 -0
  503. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +5 -2
  504. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +5 -2
  505. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +5 -2
  506. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +5 -2
  507. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +5 -2
  508. package/src/config/bundled-skills/weather/TOOLS.json +4 -0
  509. package/src/config/bundled-skills/weather/tools/get-weather.ts +5 -2
  510. package/src/config/bundled-tool-registry.ts +2 -0
  511. package/src/config/calls-schema.ts +108 -63
  512. package/src/config/channel-permission-profiles.ts +155 -0
  513. package/src/config/computer-use-prompt.ts +7 -7
  514. package/src/config/core-schema.ts +239 -155
  515. package/src/config/defaults.ts +2 -2
  516. package/src/config/elevenlabs-schema.ts +15 -15
  517. package/src/config/env-registry.ts +33 -33
  518. package/src/config/env.ts +4 -1
  519. package/src/config/feature-flag-registry.json +31 -7
  520. package/src/config/loader.ts +118 -58
  521. package/src/config/mcp-schema.ts +29 -15
  522. package/src/config/memory-schema.ts +434 -229
  523. package/src/config/notifications-schema.ts +4 -4
  524. package/src/config/sandbox-schema.ts +2 -2
  525. package/src/config/schema.ts +12 -2
  526. package/src/config/skill-state.ts +27 -15
  527. package/src/config/skills-schema.ts +72 -23
  528. package/src/config/skills.ts +303 -143
  529. package/src/config/system-prompt.ts +25 -6
  530. package/src/config/types.ts +1 -1
  531. package/src/config/update-bulletin-format.ts +3 -3
  532. package/src/config/update-bulletin-state.ts +15 -6
  533. package/src/config/update-bulletin-template-path.ts +8 -4
  534. package/src/config/update-bulletin.ts +33 -14
  535. package/src/config/user-reference.ts +8 -8
  536. package/src/contacts/contact-events.ts +21 -0
  537. package/src/contacts/contact-store.ts +813 -100
  538. package/src/contacts/contacts-write.ts +287 -0
  539. package/src/contacts/index.ts +13 -4
  540. package/src/contacts/startup-migration.ts +21 -0
  541. package/src/contacts/types.ts +73 -2
  542. package/src/context/token-estimator.ts +54 -31
  543. package/src/context/tool-result-truncation.ts +41 -7
  544. package/src/context/window-manager.ts +225 -120
  545. package/src/daemon/approval-generators.ts +83 -55
  546. package/src/daemon/approved-devices-store.ts +33 -20
  547. package/src/daemon/assistant-attachments.ts +157 -101
  548. package/src/daemon/auth-manager.ts +17 -15
  549. package/src/daemon/classifier.ts +117 -46
  550. package/src/daemon/computer-use-session.ts +316 -187
  551. package/src/daemon/config-watcher.ts +91 -44
  552. package/src/daemon/connection-policy.ts +18 -10
  553. package/src/daemon/context-overflow-approval.ts +48 -0
  554. package/src/daemon/context-overflow-policy.ts +50 -0
  555. package/src/daemon/context-overflow-reducer.ts +300 -0
  556. package/src/daemon/daemon-control.ts +79 -51
  557. package/src/daemon/date-context.ts +119 -69
  558. package/src/daemon/dictation-profile-store.ts +94 -48
  559. package/src/daemon/dictation-text-processing.ts +33 -12
  560. package/src/daemon/doordash-steps.ts +92 -49
  561. package/src/daemon/guardian-action-generators.ts +62 -46
  562. package/src/daemon/guardian-verification-intent.ts +35 -19
  563. package/src/daemon/handlers/apps.ts +258 -113
  564. package/src/daemon/handlers/avatar.ts +20 -15
  565. package/src/daemon/handlers/computer-use.ts +82 -39
  566. package/src/daemon/handlers/config-channels.ts +146 -69
  567. package/src/daemon/handlers/config-heartbeat.ts +114 -59
  568. package/src/daemon/handlers/config-inbox.ts +213 -160
  569. package/src/daemon/handlers/config-ingress.ts +127 -55
  570. package/src/daemon/handlers/config-integrations.ts +145 -88
  571. package/src/daemon/handlers/config-model.ts +58 -22
  572. package/src/daemon/handlers/config-platform.ts +40 -16
  573. package/src/daemon/handlers/config-scheduling.ts +109 -48
  574. package/src/daemon/handlers/config-slack-channel.ts +67 -35
  575. package/src/daemon/handlers/config-slack.ts +21 -20
  576. package/src/daemon/handlers/config-telegram.ts +100 -70
  577. package/src/daemon/handlers/config-tools.ts +103 -55
  578. package/src/daemon/handlers/config-trust.ts +50 -20
  579. package/src/daemon/handlers/config.ts +72 -24
  580. package/src/daemon/handlers/contacts.ts +163 -0
  581. package/src/daemon/handlers/diagnostics.ts +90 -48
  582. package/src/daemon/handlers/documents.ts +74 -46
  583. package/src/daemon/handlers/guardian-actions.ts +57 -77
  584. package/src/daemon/handlers/home-base.ts +19 -16
  585. package/src/daemon/handlers/identity.ts +65 -45
  586. package/src/daemon/handlers/index.ts +78 -54
  587. package/src/daemon/handlers/misc.ts +664 -234
  588. package/src/daemon/handlers/navigate-settings.ts +14 -11
  589. package/src/daemon/handlers/oauth-connect.ts +48 -35
  590. package/src/daemon/handlers/open-bundle-handler.ts +31 -24
  591. package/src/daemon/handlers/pairing.ts +51 -25
  592. package/src/daemon/handlers/publish.ts +55 -33
  593. package/src/daemon/handlers/recording.ts +378 -162
  594. package/src/daemon/handlers/sessions.ts +922 -423
  595. package/src/daemon/handlers/shared.ts +202 -117
  596. package/src/daemon/handlers/signing.ts +25 -6
  597. package/src/daemon/handlers/subagents.ts +117 -56
  598. package/src/daemon/handlers/twitter-auth.ts +70 -49
  599. package/src/daemon/handlers/work-items.ts +264 -112
  600. package/src/daemon/handlers/workspace-files.ts +27 -20
  601. package/src/daemon/handlers.ts +2 -2
  602. package/src/daemon/history-repair.ts +16 -15
  603. package/src/daemon/identity-helpers.ts +4 -4
  604. package/src/daemon/install-cli-launchers.ts +33 -22
  605. package/src/daemon/ipc-blob-store.ts +38 -24
  606. package/src/daemon/ipc-contract/apps.ts +61 -50
  607. package/src/daemon/ipc-contract/computer-use.ts +47 -37
  608. package/src/daemon/ipc-contract/contacts.ts +69 -0
  609. package/src/daemon/ipc-contract/diagnostics.ts +14 -14
  610. package/src/daemon/ipc-contract/documents.ts +8 -8
  611. package/src/daemon/ipc-contract/guardian-actions.ts +4 -4
  612. package/src/daemon/ipc-contract/inbox.ts +12 -71
  613. package/src/daemon/ipc-contract/integrations.ts +57 -44
  614. package/src/daemon/ipc-contract/memory.ts +3 -5
  615. package/src/daemon/ipc-contract/messages.ts +95 -69
  616. package/src/daemon/ipc-contract/notifications.ts +10 -6
  617. package/src/daemon/ipc-contract/pairing.ts +8 -8
  618. package/src/daemon/ipc-contract/schedules.ts +20 -20
  619. package/src/daemon/ipc-contract/sessions.ts +89 -57
  620. package/src/daemon/ipc-contract/settings.ts +12 -7
  621. package/src/daemon/ipc-contract/shared.ts +9 -7
  622. package/src/daemon/ipc-contract/skills.ts +46 -26
  623. package/src/daemon/ipc-contract/subagents.ts +9 -9
  624. package/src/daemon/ipc-contract/surfaces.ts +0 -1
  625. package/src/daemon/ipc-contract/trust.ts +11 -11
  626. package/src/daemon/ipc-contract/work-items.ts +33 -28
  627. package/src/daemon/ipc-contract/workspace.ts +28 -21
  628. package/src/daemon/ipc-contract-inventory.json +10 -4
  629. package/src/daemon/ipc-contract-inventory.ts +29 -26
  630. package/src/daemon/ipc-contract.ts +111 -44
  631. package/src/daemon/ipc-handler.ts +27 -19
  632. package/src/daemon/ipc-protocol.ts +22 -12
  633. package/src/daemon/ipc-validate.ts +91 -46
  634. package/src/daemon/lifecycle.ts +39 -3
  635. package/src/daemon/main.ts +10 -8
  636. package/src/daemon/media-visibility-policy.ts +3 -1
  637. package/src/daemon/pairing-store.ts +72 -40
  638. package/src/daemon/providers-setup.ts +35 -25
  639. package/src/daemon/recording-executor.ts +37 -30
  640. package/src/daemon/recording-intent-fallback.ts +58 -28
  641. package/src/daemon/recording-intent.ts +71 -61
  642. package/src/daemon/ride-shotgun-handler.ts +201 -121
  643. package/src/daemon/seed-files.ts +28 -17
  644. package/src/daemon/server.ts +23 -14
  645. package/src/daemon/session-agent-loop-handlers.ts +270 -135
  646. package/src/daemon/session-agent-loop.ts +796 -253
  647. package/src/daemon/session-attachments.ts +109 -40
  648. package/src/daemon/session-conflict-gate.ts +72 -28
  649. package/src/daemon/session-dynamic-profile.ts +36 -22
  650. package/src/daemon/session-error.ts +68 -45
  651. package/src/daemon/session-evictor.ts +17 -10
  652. package/src/daemon/session-history.ts +201 -89
  653. package/src/daemon/session-lifecycle.ts +80 -44
  654. package/src/daemon/session-media-retry.ts +104 -42
  655. package/src/daemon/session-memory.ts +77 -55
  656. package/src/daemon/session-messaging.ts +261 -111
  657. package/src/daemon/session-notifiers.ts +57 -45
  658. package/src/daemon/session-process.ts +370 -154
  659. package/src/daemon/session-queue-manager.ts +30 -13
  660. package/src/daemon/session-runtime-assembly.ts +61 -15
  661. package/src/daemon/session-skill-tools.ts +84 -36
  662. package/src/daemon/session-slash.ts +178 -113
  663. package/src/daemon/session-surfaces.ts +498 -212
  664. package/src/daemon/session-tool-setup.ts +24 -16
  665. package/src/daemon/session-usage.ts +26 -13
  666. package/src/daemon/session-workspace.ts +7 -4
  667. package/src/daemon/session.ts +18 -19
  668. package/src/daemon/shutdown-handlers.ts +36 -33
  669. package/src/daemon/tls-certs.ts +90 -57
  670. package/src/daemon/tool-side-effects.ts +97 -65
  671. package/src/daemon/trace-emitter.ts +8 -7
  672. package/src/daemon/video-thumbnail.ts +55 -25
  673. package/src/daemon/watch-handler.ts +164 -86
  674. package/src/email/provider.ts +1 -1
  675. package/src/email/providers/agentmail.ts +87 -45
  676. package/src/email/providers/index.ts +19 -14
  677. package/src/email/service.ts +52 -24
  678. package/src/email/types.ts +2 -2
  679. package/src/errors.ts +1 -1
  680. package/src/events/bus.ts +30 -10
  681. package/src/events/domain-events.ts +20 -13
  682. package/src/events/index.ts +6 -6
  683. package/src/events/tool-audit-listener.ts +34 -20
  684. package/src/events/tool-domain-event-publisher.ts +22 -20
  685. package/src/events/tool-metrics-listener.ts +26 -21
  686. package/src/events/tool-notification-listener.ts +5 -5
  687. package/src/events/tool-profiling-listener.ts +33 -23
  688. package/src/events/tool-trace-listener.ts +70 -46
  689. package/src/export/formatter.ts +38 -32
  690. package/src/followups/followup-store.ts +43 -36
  691. package/src/followups/index.ts +2 -2
  692. package/src/followups/types.ts +1 -1
  693. package/src/gallery/default-gallery.ts +37 -34
  694. package/src/gallery/gallery-manifest.ts +9 -9
  695. package/src/heartbeat/heartbeat-service.ts +59 -37
  696. package/src/home-base/app-link-store.ts +14 -12
  697. package/src/home-base/bootstrap.ts +14 -8
  698. package/src/home-base/prebuilt/seed.ts +34 -26
  699. package/src/home-base/prebuilt-home-base-updater.ts +14 -8
  700. package/src/hooks/cli.ts +56 -43
  701. package/src/hooks/config.ts +27 -14
  702. package/src/hooks/discovery.ts +53 -33
  703. package/src/hooks/manager.ts +50 -26
  704. package/src/hooks/runner.ts +35 -29
  705. package/src/hooks/templates.ts +38 -15
  706. package/src/hooks/types.ts +13 -13
  707. package/src/inbound/platform-callback-registration.ts +21 -15
  708. package/src/inbound/public-ingress-urls.ts +9 -6
  709. package/src/index.ts +20 -19
  710. package/src/influencer/client.ts +261 -117
  711. package/src/instrument.ts +3 -1
  712. package/src/logfire.ts +64 -39
  713. package/src/mcp/client.ts +107 -55
  714. package/src/mcp/manager.ts +45 -18
  715. package/src/mcp/mcp-oauth-provider.ts +114 -62
  716. package/src/media/gemini-image-service.ts +75 -23
  717. package/src/memory/account-store.ts +16 -9
  718. package/src/memory/admin.ts +87 -57
  719. package/src/memory/app-git-service.ts +77 -47
  720. package/src/memory/app-store.ts +148 -78
  721. package/src/memory/attachments-store.ts +123 -53
  722. package/src/memory/canonical-guardian-store.ts +190 -48
  723. package/src/memory/channel-delivery-store.ts +5 -5
  724. package/src/memory/channel-guardian-store.ts +31 -16
  725. package/src/memory/checkpoints.ts +14 -7
  726. package/src/memory/clarification-resolver.ts +219 -104
  727. package/src/memory/conflict-intent.ts +74 -23
  728. package/src/memory/conflict-policy.ts +20 -7
  729. package/src/memory/conflict-store.ts +144 -94
  730. package/src/memory/contradiction-checker.ts +257 -132
  731. package/src/memory/conversation-attention-store.ts +74 -32
  732. package/src/memory/conversation-bootstrap.ts +28 -0
  733. package/src/memory/conversation-crud.ts +12 -5
  734. package/src/memory/conversation-display-order-migration.ts +7 -7
  735. package/src/memory/conversation-key-store.ts +18 -13
  736. package/src/memory/conversation-queries.ts +130 -52
  737. package/src/memory/conversation-store.ts +43 -26
  738. package/src/memory/conversation-title-service.ts +89 -66
  739. package/src/memory/db-init.ts +94 -2
  740. package/src/memory/db.ts +10 -3
  741. package/src/memory/delivery-channels.ts +12 -6
  742. package/src/memory/delivery-crud.ts +26 -12
  743. package/src/memory/delivery-status.ts +19 -16
  744. package/src/memory/embedding-backend.ts +205 -77
  745. package/src/memory/embedding-gemini.ts +23 -10
  746. package/src/memory/embedding-local.ts +89 -44
  747. package/src/memory/embedding-ollama.ts +25 -13
  748. package/src/memory/embedding-openai.ts +20 -11
  749. package/src/memory/embedding-runtime-manager.ts +163 -90
  750. package/src/memory/entity-extractor.ts +185 -123
  751. package/src/memory/external-conversation-store.ts +30 -12
  752. package/src/memory/fingerprint.ts +2 -2
  753. package/src/memory/fts-reconciler.ts +57 -28
  754. package/src/memory/guardian-action-store.ts +162 -100
  755. package/src/memory/guardian-approvals.ts +63 -129
  756. package/src/memory/guardian-rate-limits.ts +20 -9
  757. package/src/memory/guardian-verification.ts +82 -35
  758. package/src/memory/indexer.ts +96 -55
  759. package/src/memory/{ingress-invite-store.ts → invite-store.ts} +28 -169
  760. package/src/memory/items-extractor.ts +313 -157
  761. package/src/memory/job-handlers/backfill.ts +116 -63
  762. package/src/memory/job-handlers/cleanup.ts +64 -41
  763. package/src/memory/job-handlers/conflict.ts +90 -49
  764. package/src/memory/job-handlers/embedding.ts +32 -17
  765. package/src/memory/job-handlers/extraction.ts +58 -33
  766. package/src/memory/job-handlers/index-maintenance.ts +31 -17
  767. package/src/memory/job-handlers/media-processing.ts +65 -24
  768. package/src/memory/job-handlers/summarization.ts +186 -128
  769. package/src/memory/job-utils.ts +100 -57
  770. package/src/memory/jobs-store.ts +235 -142
  771. package/src/memory/jobs-worker.ts +167 -83
  772. package/src/memory/llm-request-log-store.ts +13 -11
  773. package/src/memory/llm-usage-store.ts +35 -26
  774. package/src/memory/media-store.ts +151 -44
  775. package/src/memory/message-content.ts +28 -18
  776. package/src/memory/migrations/001-job-deferrals.ts +11 -5
  777. package/src/memory/migrations/002-tool-invocations-fk.ts +14 -6
  778. package/src/memory/migrations/003-memory-fts-backfill.ts +11 -5
  779. package/src/memory/migrations/004-entity-relation-dedup.ts +17 -11
  780. package/src/memory/migrations/005-fingerprint-scope-unique.ts +36 -21
  781. package/src/memory/migrations/006-scope-salted-fingerprints.ts +35 -20
  782. package/src/memory/migrations/007-assistant-id-to-self.ts +40 -27
  783. package/src/memory/migrations/008-remove-assistant-id-columns.ts +58 -36
  784. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +36 -22
  785. package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +21 -11
  786. package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +30 -15
  787. package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +4 -2
  788. package/src/memory/migrations/013-guardian-action-tables.ts +29 -11
  789. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +35 -21
  790. package/src/memory/migrations/015-drop-active-search-index.ts +17 -11
  791. package/src/memory/migrations/016-memory-segments-indexes.ts +7 -3
  792. package/src/memory/migrations/017-memory-items-indexes.ts +4 -2
  793. package/src/memory/migrations/018-remaining-table-indexes.ts +13 -5
  794. package/src/memory/migrations/019-notification-tables-schema-migration.ts +34 -20
  795. package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +87 -53
  796. package/src/memory/migrations/021-conversation-status-indexes.ts +7 -3
  797. package/src/memory/migrations/022-add-origin-interface.ts +4 -2
  798. package/src/memory/migrations/023-memory-item-sources-indexes.ts +4 -2
  799. package/src/memory/migrations/024-embedding-vector-blob.ts +34 -18
  800. package/src/memory/migrations/025-messages-fts-backfill.ts +11 -5
  801. package/src/memory/migrations/026-guardian-verification-sessions.ts +80 -14
  802. package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +42 -26
  803. package/src/memory/migrations/027-notification-delivery-pairing-columns.ts +22 -8
  804. package/src/memory/migrations/027a-guardian-bootstrap-token.ts +11 -3
  805. package/src/memory/migrations/028-call-session-mode.ts +13 -3
  806. package/src/memory/migrations/028-notification-delivery-client-ack.ts +22 -8
  807. package/src/memory/migrations/029-channel-inbound-delivered-segments.ts +7 -3
  808. package/src/memory/migrations/030-guardian-action-followup.ts +46 -8
  809. package/src/memory/migrations/030-guardian-verification-purpose.ts +4 -2
  810. package/src/memory/migrations/031-conversations-thread-type-index.ts +4 -2
  811. package/src/memory/migrations/032-guardian-delivery-conversation-index.ts +4 -2
  812. package/src/memory/migrations/032-notification-delivery-thread-decision.ts +22 -8
  813. package/src/memory/migrations/033-scoped-approval-grants.ts +1 -1
  814. package/src/memory/migrations/034-guardian-action-tool-metadata.ts +15 -3
  815. package/src/memory/migrations/035-guardian-action-supersession.ts +15 -3
  816. package/src/memory/migrations/036-normalize-phone-identities.ts +101 -87
  817. package/src/memory/migrations/037-voice-invite-columns.ts +22 -4
  818. package/src/memory/migrations/038-actor-token-records.ts +5 -9
  819. package/src/memory/migrations/039-actor-refresh-token-records.ts +7 -13
  820. package/src/memory/migrations/100-core-tables.ts +1 -1
  821. package/src/memory/migrations/101-watchers-and-logs.ts +1 -1
  822. package/src/memory/migrations/103-complex-migrations.ts +9 -9
  823. package/src/memory/migrations/104-core-indexes.ts +188 -64
  824. package/src/memory/migrations/105-contacts-and-triage.ts +28 -10
  825. package/src/memory/migrations/106-call-sessions.ts +58 -16
  826. package/src/memory/migrations/107-followups.ts +16 -6
  827. package/src/memory/migrations/108-tasks-and-work-items.ts +43 -11
  828. package/src/memory/migrations/109-external-conversation-bindings.ts +11 -5
  829. package/src/memory/migrations/110-channel-guardian.ts +48 -10
  830. package/src/memory/migrations/111-media-assets.ts +52 -18
  831. package/src/memory/migrations/112-assistant-inbox.ts +32 -12
  832. package/src/memory/migrations/113-late-migrations.ts +12 -12
  833. package/src/memory/migrations/114-notifications.ts +28 -12
  834. package/src/memory/migrations/115-sequences.ts +10 -4
  835. package/src/memory/migrations/116-messages-fts.ts +1 -1
  836. package/src/memory/migrations/117-conversation-attention.ts +16 -6
  837. package/src/memory/migrations/118-reminder-routing-intent.ts +7 -3
  838. package/src/memory/migrations/119-schema-indexes-and-columns.ts +35 -15
  839. package/src/memory/migrations/120-fk-cascade-rebuilds.ts +36 -17
  840. package/src/memory/migrations/121-canonical-guardian-requests.ts +25 -9
  841. package/src/memory/migrations/122-canonical-guardian-requester-chat-id.ts +11 -3
  842. package/src/memory/migrations/123-canonical-guardian-deliveries-destination-index.ts +4 -2
  843. package/src/memory/migrations/124-voice-invite-display-metadata.ts +15 -3
  844. package/src/memory/migrations/125-guardian-principal-id-columns.ts +22 -4
  845. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +174 -126
  846. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +58 -42
  847. package/src/memory/migrations/128-contacts-role-principal.ts +26 -0
  848. package/src/memory/migrations/129-contact-channels-access-fields.ts +105 -0
  849. package/src/memory/migrations/130-contact-channels-type-ext-chat-id-index.ts +15 -0
  850. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +134 -0
  851. package/src/memory/migrations/132-contacts-assistant-id.ts +21 -0
  852. package/src/memory/migrations/133-assistant-contact-metadata.ts +21 -0
  853. package/src/memory/migrations/index.ts +83 -73
  854. package/src/memory/migrations/registry.ts +53 -37
  855. package/src/memory/migrations/validate-migration-state.ts +73 -46
  856. package/src/memory/profile-compiler.ts +58 -24
  857. package/src/memory/published-pages-store.ts +12 -16
  858. package/src/memory/qdrant-circuit-breaker.ts +28 -20
  859. package/src/memory/qdrant-client.ts +99 -63
  860. package/src/memory/qdrant-manager.ts +89 -57
  861. package/src/memory/query-builder.ts +9 -7
  862. package/src/memory/raw-query.ts +63 -14
  863. package/src/memory/recall-cache.ts +15 -8
  864. package/src/memory/retrieval-budget.ts +0 -1
  865. package/src/memory/retriever.ts +385 -192
  866. package/src/memory/schema-migration.ts +1 -1
  867. package/src/memory/schema.ts +56 -56
  868. package/src/memory/scoped-approval-grants.ts +99 -45
  869. package/src/memory/search/entity.ts +102 -40
  870. package/src/memory/search/formatting.ts +70 -52
  871. package/src/memory/search/lexical.ts +82 -43
  872. package/src/memory/search/ranking.ts +103 -39
  873. package/src/memory/search/semantic.ts +59 -35
  874. package/src/memory/search/types.ts +8 -8
  875. package/src/memory/segmenter.ts +20 -12
  876. package/src/memory/shared-app-links-store.ts +21 -16
  877. package/src/memory/slack-thread-store.ts +187 -0
  878. package/src/memory/task-memory-cleanup.ts +18 -8
  879. package/src/memory/tool-usage-store.ts +27 -19
  880. package/src/memory/validation.ts +4 -2
  881. package/src/messaging/activity-analyzer.ts +7 -7
  882. package/src/messaging/draft-store.ts +13 -10
  883. package/src/messaging/email-classifier.ts +73 -37
  884. package/src/messaging/index.ts +3 -3
  885. package/src/messaging/outreach-classifier.ts +76 -38
  886. package/src/messaging/provider-types.ts +2 -4
  887. package/src/messaging/provider.ts +37 -8
  888. package/src/messaging/providers/gmail/adapter.ts +183 -66
  889. package/src/messaging/providers/gmail/client.ts +3 -1
  890. package/src/messaging/providers/gmail/mime-builder.ts +21 -19
  891. package/src/messaging/providers/gmail/people-client.ts +22 -9
  892. package/src/messaging/providers/gmail/types.ts +6 -6
  893. package/src/messaging/providers/slack/adapter.ts +93 -43
  894. package/src/messaging/providers/slack/client.ts +165 -48
  895. package/src/messaging/providers/slack/types.ts +10 -0
  896. package/src/messaging/providers/sms/adapter.ts +76 -40
  897. package/src/messaging/providers/sms/client.ts +4 -4
  898. package/src/messaging/providers/telegram-bot/adapter.ts +52 -30
  899. package/src/messaging/providers/telegram-bot/client.ts +7 -7
  900. package/src/messaging/providers/whatsapp/adapter.ts +58 -31
  901. package/src/messaging/providers/whatsapp/client.ts +4 -4
  902. package/src/messaging/registry.ts +9 -5
  903. package/src/messaging/style-analyzer.ts +69 -39
  904. package/src/messaging/thread-summarizer.ts +101 -53
  905. package/src/messaging/triage-engine.ts +111 -82
  906. package/src/messaging/types.ts +10 -10
  907. package/src/migrations/config-merge.ts +18 -10
  908. package/src/migrations/data-layout.ts +35 -22
  909. package/src/migrations/data-merge.ts +17 -7
  910. package/src/migrations/hooks-merge.ts +43 -16
  911. package/src/migrations/index.ts +6 -6
  912. package/src/migrations/log.ts +9 -5
  913. package/src/migrations/skills-merge.ts +17 -7
  914. package/src/migrations/workspace-layout.ts +39 -25
  915. package/src/notifications/AGENTS.md +5 -0
  916. package/src/notifications/adapters/macos.ts +21 -14
  917. package/src/notifications/adapters/slack.ts +90 -0
  918. package/src/notifications/adapters/sms.ts +28 -15
  919. package/src/notifications/adapters/telegram.ts +24 -15
  920. package/src/notifications/broadcaster.ts +108 -52
  921. package/src/notifications/conversation-pairing.ts +64 -29
  922. package/src/notifications/copy-composer.ts +165 -95
  923. package/src/notifications/decision-engine.ts +353 -147
  924. package/src/notifications/decisions-store.ts +26 -10
  925. package/src/notifications/deliveries-store.ts +23 -13
  926. package/src/notifications/destination-resolver.ts +83 -24
  927. package/src/notifications/deterministic-checks.ts +78 -27
  928. package/src/notifications/emit-signal.ts +95 -41
  929. package/src/notifications/events-store.ts +13 -7
  930. package/src/notifications/guardian-question-mode.ts +125 -75
  931. package/src/notifications/preference-extractor.ts +85 -53
  932. package/src/notifications/preference-summary.ts +31 -18
  933. package/src/notifications/preferences-store.ts +29 -18
  934. package/src/notifications/runtime-dispatch.ts +22 -12
  935. package/src/notifications/signal.ts +4 -4
  936. package/src/notifications/thread-candidates.ts +59 -23
  937. package/src/notifications/thread-seed-composer.ts +45 -27
  938. package/src/notifications/types.ts +19 -10
  939. package/src/oauth/connect-orchestrator.ts +105 -54
  940. package/src/oauth/connect-types.ts +3 -3
  941. package/src/oauth/provider-profiles.ts +102 -59
  942. package/src/oauth/scope-policy.ts +5 -2
  943. package/src/oauth/token-persistence.ts +58 -24
  944. package/src/outbound-proxy/certs.ts +284 -0
  945. package/src/outbound-proxy/config.ts +94 -0
  946. package/src/outbound-proxy/connect-tunnel.ts +84 -0
  947. package/src/outbound-proxy/health.ts +62 -0
  948. package/src/outbound-proxy/host-pattern-match.ts +67 -0
  949. package/src/outbound-proxy/http-forwarder.ts +162 -0
  950. package/src/outbound-proxy/index.ts +80 -0
  951. package/src/outbound-proxy/logging.ts +193 -0
  952. package/src/outbound-proxy/mitm-handler.ts +292 -0
  953. package/src/outbound-proxy/policy.ts +172 -0
  954. package/src/outbound-proxy/router.ts +64 -0
  955. package/src/outbound-proxy/server.ts +145 -0
  956. package/src/outbound-proxy/types.ts +150 -0
  957. package/src/permissions/checker.ts +481 -189
  958. package/src/permissions/defaults.ts +135 -108
  959. package/src/permissions/prompter.ts +53 -27
  960. package/src/permissions/secret-prompter.ts +21 -15
  961. package/src/permissions/shell-identity.ts +47 -16
  962. package/src/permissions/trust-store.ts +185 -73
  963. package/src/permissions/types.ts +22 -12
  964. package/src/permissions/workspace-policy.ts +47 -38
  965. package/src/playbooks/index.ts +10 -2
  966. package/src/playbooks/playbook-compiler.ts +30 -24
  967. package/src/playbooks/types.ts +11 -8
  968. package/src/providers/anthropic/client.ts +328 -168
  969. package/src/providers/failover.ts +57 -22
  970. package/src/providers/fireworks/client.ts +9 -5
  971. package/src/providers/gemini/client.ts +61 -39
  972. package/src/providers/model-intents.ts +40 -33
  973. package/src/providers/ollama/client.ts +7 -7
  974. package/src/providers/openai/client.ts +109 -68
  975. package/src/providers/openrouter/client.ts +9 -5
  976. package/src/providers/provider-send-message.ts +59 -27
  977. package/src/providers/ratelimit.ts +25 -8
  978. package/src/providers/registry.ts +86 -38
  979. package/src/providers/retry.ts +93 -37
  980. package/src/providers/stream-timeout.ts +5 -3
  981. package/src/providers/types.ts +7 -6
  982. package/src/runtime/AGENTS.md +42 -0
  983. package/src/runtime/access-request-helper.ts +118 -68
  984. package/src/runtime/actor-refresh-token-store.ts +21 -16
  985. package/src/runtime/actor-token-store.ts +25 -18
  986. package/src/runtime/actor-trust-resolver.ts +191 -80
  987. package/src/runtime/approval-conversation-turn.ts +39 -26
  988. package/src/runtime/approval-message-composer.ts +116 -84
  989. package/src/runtime/assistant-event-hub.ts +25 -6
  990. package/src/runtime/assistant-event.ts +4 -4
  991. package/src/runtime/assistant-scope.ts +1 -1
  992. package/src/runtime/auth/__tests__/guard-tests.test.ts +36 -14
  993. package/src/runtime/auth/context.ts +8 -7
  994. package/src/runtime/auth/credential-service.ts +60 -38
  995. package/src/runtime/auth/external-assistant-id.ts +16 -8
  996. package/src/runtime/auth/index.ts +23 -16
  997. package/src/runtime/auth/require-bound-guardian.ts +44 -0
  998. package/src/runtime/auth/route-policy.ts +166 -104
  999. package/src/runtime/auth/scopes.ts +22 -29
  1000. package/src/runtime/auth/subject.ts +19 -13
  1001. package/src/runtime/auth/token-service.ts +3 -3
  1002. package/src/runtime/auth/types.ts +23 -23
  1003. package/src/runtime/channel-approval-parser.ts +37 -14
  1004. package/src/runtime/channel-approval-types.ts +30 -4
  1005. package/src/runtime/channel-approvals.ts +49 -23
  1006. package/src/runtime/channel-guardian-service.ts +144 -103
  1007. package/src/runtime/channel-invite-transport.ts +5 -3
  1008. package/src/runtime/channel-invite-transports/telegram.ts +16 -10
  1009. package/src/runtime/channel-invite-transports/voice.ts +7 -7
  1010. package/src/runtime/channel-readiness-service.ts +139 -90
  1011. package/src/runtime/channel-readiness-types.ts +4 -2
  1012. package/src/runtime/channel-reply-delivery.ts +83 -14
  1013. package/src/runtime/channel-retry-sweep.ts +111 -62
  1014. package/src/runtime/confirmation-request-guardian-bridge.ts +73 -54
  1015. package/src/runtime/gateway-client.ts +122 -55
  1016. package/src/runtime/gateway-internal-client.ts +86 -0
  1017. package/src/runtime/guardian-action-conversation-turn.ts +34 -18
  1018. package/src/runtime/guardian-action-followup-executor.ts +115 -45
  1019. package/src/runtime/guardian-action-grant-minter.ts +40 -24
  1020. package/src/runtime/guardian-action-message-composer.ts +105 -84
  1021. package/src/runtime/guardian-action-service.ts +127 -0
  1022. package/src/runtime/guardian-decision-types.ts +28 -13
  1023. package/src/runtime/guardian-outbound-actions.ts +9 -0
  1024. package/src/runtime/guardian-reply-router.ts +274 -145
  1025. package/src/runtime/guardian-vellum-migration.ts +38 -24
  1026. package/src/runtime/guardian-verification-templates.ts +24 -12
  1027. package/src/runtime/http-router.ts +175 -0
  1028. package/src/runtime/http-server.ts +913 -680
  1029. package/src/runtime/http-types.ts +2 -2
  1030. package/src/runtime/invite-redemption-service.ts +211 -134
  1031. package/src/runtime/invite-redemption-templates.ts +18 -11
  1032. package/src/runtime/{ingress-service.ts → invite-service.ts} +92 -151
  1033. package/src/runtime/local-actor-identity.ts +73 -55
  1034. package/src/runtime/middleware/auth.ts +25 -14
  1035. package/src/runtime/middleware/error-handler.ts +15 -11
  1036. package/src/runtime/middleware/rate-limiter.ts +23 -17
  1037. package/src/runtime/middleware/request-logger.ts +4 -4
  1038. package/src/runtime/middleware/twilio-validation.ts +29 -20
  1039. package/src/runtime/migrations/migration-transport.ts +575 -0
  1040. package/src/runtime/migrations/migration-wizard.ts +715 -0
  1041. package/src/runtime/migrations/rebind-secrets-screen.ts +351 -0
  1042. package/src/runtime/migrations/transfer-progress-screen.ts +321 -0
  1043. package/src/runtime/migrations/validation-results-screen.ts +467 -0
  1044. package/src/runtime/migrations/vbundle-builder.ts +295 -0
  1045. package/src/runtime/migrations/vbundle-import-analyzer.ts +212 -0
  1046. package/src/runtime/migrations/vbundle-importer.ts +339 -0
  1047. package/src/runtime/migrations/vbundle-validator.ts +356 -0
  1048. package/src/runtime/nl-approval-parser.ts +138 -0
  1049. package/src/runtime/pending-interactions.ts +16 -7
  1050. package/src/runtime/routes/access-request-decision.ts +73 -52
  1051. package/src/runtime/routes/app-routes.ts +56 -38
  1052. package/src/runtime/routes/approval-routes.ts +144 -92
  1053. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +930 -0
  1054. package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +82 -0
  1055. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +151 -0
  1056. package/src/runtime/routes/attachment-routes.ts +59 -48
  1057. package/src/runtime/routes/brain-graph-routes.ts +85 -69
  1058. package/src/runtime/routes/call-routes.ts +79 -38
  1059. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +10 -10
  1060. package/src/runtime/routes/channel-delivery-routes.ts +19 -14
  1061. package/src/runtime/routes/channel-guardian-routes.ts +3 -3
  1062. package/src/runtime/routes/channel-inbound-routes.ts +2 -2
  1063. package/src/runtime/routes/channel-readiness-routes.ts +12 -6
  1064. package/src/runtime/routes/channel-route-shared.ts +67 -25
  1065. package/src/runtime/routes/channel-routes.ts +4 -6
  1066. package/src/runtime/routes/contact-routes.ts +374 -17
  1067. package/src/runtime/routes/conversation-attention-routes.ts +57 -28
  1068. package/src/runtime/routes/conversation-routes.ts +321 -174
  1069. package/src/runtime/routes/debug-routes.ts +14 -10
  1070. package/src/runtime/routes/events-routes.ts +90 -57
  1071. package/src/runtime/routes/global-search-routes.ts +266 -0
  1072. package/src/runtime/routes/guardian-action-routes.ts +112 -113
  1073. package/src/runtime/routes/guardian-approval-interception.ts +325 -874
  1074. package/src/runtime/routes/guardian-approval-prompt.ts +40 -24
  1075. package/src/runtime/routes/guardian-approval-reply-helpers.ts +135 -0
  1076. package/src/runtime/routes/guardian-bootstrap-routes.ts +55 -36
  1077. package/src/runtime/routes/guardian-expiry-sweep.ts +63 -37
  1078. package/src/runtime/routes/guardian-refresh-routes.ts +40 -19
  1079. package/src/runtime/routes/identity-routes.ts +71 -42
  1080. package/src/runtime/routes/inbound-conversation.ts +17 -11
  1081. package/src/runtime/routes/inbound-message-handler.ts +305 -1459
  1082. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +880 -0
  1083. package/src/runtime/routes/inbound-stages/background-dispatch.ts +600 -0
  1084. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +214 -0
  1085. package/src/runtime/routes/inbound-stages/edit-intercept.ts +116 -0
  1086. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +167 -0
  1087. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +185 -0
  1088. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +132 -0
  1089. package/src/runtime/routes/inbound-stages/verification-intercept.ts +340 -0
  1090. package/src/runtime/routes/integration-routes.ts +60 -21
  1091. package/src/runtime/routes/invite-routes.ts +140 -0
  1092. package/src/runtime/routes/migration-routes.ts +434 -0
  1093. package/src/runtime/routes/pairing-routes.ts +157 -79
  1094. package/src/runtime/routes/secret-routes.ts +6 -2
  1095. package/src/runtime/routes/twilio-routes.ts +443 -249
  1096. package/src/runtime/slack-block-formatting.ts +176 -0
  1097. package/src/runtime/tool-grant-request-helper.ts +36 -27
  1098. package/src/runtime/{guardian-context-resolver.ts → trust-context-resolver.ts} +29 -41
  1099. package/src/schedule/integration-status.ts +44 -9
  1100. package/src/schedule/recurrence-engine.ts +47 -24
  1101. package/src/schedule/recurrence-types.ts +12 -7
  1102. package/src/schedule/schedule-store.ts +166 -83
  1103. package/src/schedule/scheduler.ts +37 -24
  1104. package/src/security/encrypted-store.ts +68 -38
  1105. package/src/security/keychain.ts +183 -120
  1106. package/src/security/oauth-callback-registry.ts +3 -3
  1107. package/src/security/oauth2.ts +226 -138
  1108. package/src/security/redaction.ts +24 -24
  1109. package/src/security/secret-allowlist.ts +46 -21
  1110. package/src/security/secret-ingress.ts +15 -7
  1111. package/src/security/secret-scanner.ts +193 -104
  1112. package/src/security/secure-keys.ts +9 -3
  1113. package/src/security/token-manager.ts +99 -40
  1114. package/src/security/tool-approval-digest.ts +3 -3
  1115. package/src/sequence/analytics.ts +52 -27
  1116. package/src/sequence/engine.ts +135 -72
  1117. package/src/sequence/guardrails.ts +32 -20
  1118. package/src/sequence/importer.ts +75 -37
  1119. package/src/sequence/reply-matcher.ts +36 -18
  1120. package/src/sequence/store.ts +137 -75
  1121. package/src/sequence/types.ts +30 -16
  1122. package/src/services/published-app-updater.ts +26 -16
  1123. package/src/services/vercel-deploy.ts +19 -15
  1124. package/src/skills/active-skill-tools.ts +3 -3
  1125. package/src/skills/clawhub.ts +178 -90
  1126. package/src/skills/include-graph.ts +24 -17
  1127. package/src/skills/managed-store.ts +89 -42
  1128. package/src/skills/path-classifier.ts +10 -10
  1129. package/src/skills/remote-skill-policy.ts +31 -22
  1130. package/src/skills/slash-commands.ts +36 -30
  1131. package/src/skills/tool-manifest.ts +60 -31
  1132. package/src/skills/version-hash.ts +25 -15
  1133. package/src/slack/slack-webhook.ts +19 -15
  1134. package/src/subagent/index.ts +4 -8
  1135. package/src/subagent/manager.ts +119 -69
  1136. package/src/subagent/types.ts +9 -12
  1137. package/src/swarm/backend-claude-code.ts +124 -45
  1138. package/src/swarm/checkpoint.ts +36 -16
  1139. package/src/swarm/graph-utils.ts +1 -3
  1140. package/src/swarm/index.ts +38 -19
  1141. package/src/swarm/limits.ts +13 -4
  1142. package/src/swarm/orchestrator.ts +108 -57
  1143. package/src/swarm/plan-validator.ts +23 -17
  1144. package/src/swarm/router-planner.ts +51 -22
  1145. package/src/swarm/router-prompts.ts +4 -1
  1146. package/src/swarm/synthesizer.ts +26 -18
  1147. package/src/swarm/types.ts +14 -4
  1148. package/src/swarm/worker-backend.ts +36 -26
  1149. package/src/swarm/worker-prompts.ts +13 -9
  1150. package/src/swarm/worker-runner.ts +40 -34
  1151. package/src/tasks/candidate-store.ts +14 -6
  1152. package/src/tasks/ephemeral-permissions.ts +9 -5
  1153. package/src/tasks/task-compiler.ts +41 -38
  1154. package/src/tasks/task-runner.ts +54 -26
  1155. package/src/tasks/task-scheduler.ts +1 -1
  1156. package/src/tasks/task-store.ts +20 -7
  1157. package/src/tasks/tool-sanitizer.ts +3 -3
  1158. package/src/tools/apps/definitions.ts +23 -15
  1159. package/src/tools/apps/executors.ts +122 -40
  1160. package/src/tools/apps/open-proxy.ts +5 -5
  1161. package/src/tools/apps/registry.ts +2 -2
  1162. package/src/tools/assets/materialize.ts +59 -41
  1163. package/src/tools/assets/search.ts +86 -48
  1164. package/src/tools/browser/api-map.ts +52 -36
  1165. package/src/tools/browser/auth-cache.ts +21 -18
  1166. package/src/tools/browser/auth-detector.ts +43 -28
  1167. package/src/tools/browser/auto-navigate.ts +149 -68
  1168. package/src/tools/browser/browser-execution.ts +9 -3
  1169. package/src/tools/browser/headless-browser.ts +287 -150
  1170. package/src/tools/browser/jit-auth.ts +37 -21
  1171. package/src/tools/browser/network-recorder.ts +138 -56
  1172. package/src/tools/browser/recording-store.ts +22 -15
  1173. package/src/tools/browser/runtime-check.ts +8 -5
  1174. package/src/tools/browser/x-auto-navigate.ts +88 -47
  1175. package/src/tools/calls/call-end.ts +10 -7
  1176. package/src/tools/calls/call-start.ts +30 -20
  1177. package/src/tools/calls/call-status.ts +8 -5
  1178. package/src/tools/claude-code/claude-code.ts +301 -165
  1179. package/src/tools/computer-use/definitions.ts +175 -130
  1180. package/src/tools/computer-use/registry.ts +2 -2
  1181. package/src/tools/computer-use/request-computer-control.ts +21 -13
  1182. package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
  1183. package/src/tools/credentials/account-registry.ts +52 -35
  1184. package/src/tools/credentials/broker-types.ts +1 -1
  1185. package/src/tools/credentials/broker.ts +97 -55
  1186. package/src/tools/credentials/domain-policy.ts +5 -2
  1187. package/src/tools/credentials/host-pattern-match.ts +15 -8
  1188. package/src/tools/credentials/metadata-store.ts +93 -43
  1189. package/src/tools/credentials/policy-types.ts +5 -2
  1190. package/src/tools/credentials/policy-validate.ts +21 -14
  1191. package/src/tools/credentials/post-connect-hooks.ts +18 -7
  1192. package/src/tools/credentials/resolve.ts +11 -10
  1193. package/src/tools/credentials/selection.ts +30 -25
  1194. package/src/tools/credentials/tool-policy.ts +5 -2
  1195. package/src/tools/credentials/vault.ts +538 -185
  1196. package/src/tools/document/document-tool.ts +23 -17
  1197. package/src/tools/document/editor-template.ts +12 -7
  1198. package/src/tools/execution-target.ts +13 -10
  1199. package/src/tools/execution-timeout.ts +6 -5
  1200. package/src/tools/executor.ts +141 -74
  1201. package/src/tools/filesystem/edit.ts +82 -45
  1202. package/src/tools/filesystem/fuzzy-match.ts +70 -32
  1203. package/src/tools/filesystem/read.ts +46 -28
  1204. package/src/tools/filesystem/view-image.ts +86 -42
  1205. package/src/tools/filesystem/write.ts +53 -32
  1206. package/src/tools/followups/followup_create.ts +43 -17
  1207. package/src/tools/followups/followup_list.ts +28 -13
  1208. package/src/tools/followups/followup_resolve.ts +9 -6
  1209. package/src/tools/guardian-control-plane-policy.ts +15 -14
  1210. package/src/tools/host-filesystem/edit.ts +77 -42
  1211. package/src/tools/host-filesystem/read.ts +52 -33
  1212. package/src/tools/host-filesystem/write.ts +50 -29
  1213. package/src/tools/host-terminal/host-shell.ts +97 -61
  1214. package/src/tools/mcp/mcp-tool-factory.ts +21 -14
  1215. package/src/tools/memory/definitions.ts +60 -28
  1216. package/src/tools/memory/handlers.ts +149 -77
  1217. package/src/tools/memory/register.ts +39 -16
  1218. package/src/tools/network/__tests__/web-search.test.ts +236 -177
  1219. package/src/tools/network/domain-normalize.ts +13 -9
  1220. package/src/tools/network/script-proxy/__tests__/logging.test.ts +193 -123
  1221. package/src/tools/network/script-proxy/__tests__/policy.test.ts +225 -127
  1222. package/src/tools/network/script-proxy/index.ts +1 -17
  1223. package/src/tools/network/script-proxy/session-manager.ts +178 -86
  1224. package/src/tools/network/url-safety.ts +56 -34
  1225. package/src/tools/network/web-fetch.ts +273 -155
  1226. package/src/tools/network/web-search.ts +166 -81
  1227. package/src/tools/permission-checker.ts +24 -25
  1228. package/src/tools/policy-context.ts +8 -5
  1229. package/src/tools/registry.ts +73 -46
  1230. package/src/tools/reminder/reminder-store.ts +65 -44
  1231. package/src/tools/reminder/reminder.ts +76 -35
  1232. package/src/tools/schedule/create.ts +44 -21
  1233. package/src/tools/schedule/delete.ts +8 -5
  1234. package/src/tools/schedule/list.ts +39 -19
  1235. package/src/tools/schedule/update.ts +49 -26
  1236. package/src/tools/secret-detection-handler.ts +130 -49
  1237. package/src/tools/sensitive-output-placeholders.ts +15 -8
  1238. package/src/tools/shared/filesystem/edit-engine.ts +45 -14
  1239. package/src/tools/shared/filesystem/errors.ts +18 -18
  1240. package/src/tools/shared/filesystem/file-ops-service.ts +59 -32
  1241. package/src/tools/shared/filesystem/format-diff.ts +21 -11
  1242. package/src/tools/shared/filesystem/path-policy.ts +17 -13
  1243. package/src/tools/shared/filesystem/size-guard.ts +8 -4
  1244. package/src/tools/shared/filesystem/types.ts +2 -2
  1245. package/src/tools/shared/shell-output.ts +4 -3
  1246. package/src/tools/side-effects.ts +36 -28
  1247. package/src/tools/skills/delete-managed.ts +30 -17
  1248. package/src/tools/skills/load.ts +88 -46
  1249. package/src/tools/skills/sandbox-runner.ts +62 -46
  1250. package/src/tools/skills/scaffold-managed.ts +98 -48
  1251. package/src/tools/skills/script-contract.ts +5 -2
  1252. package/src/tools/skills/skill-script-runner.ts +29 -13
  1253. package/src/tools/skills/skill-tool-factory.ts +20 -10
  1254. package/src/tools/subagent/abort.ts +10 -4
  1255. package/src/tools/subagent/message.ts +14 -8
  1256. package/src/tools/subagent/read.ts +20 -11
  1257. package/src/tools/subagent/spawn.ts +14 -6
  1258. package/src/tools/subagent/status.ts +7 -4
  1259. package/src/tools/swarm/delegate.ts +75 -49
  1260. package/src/tools/system/avatar-generator.ts +46 -33
  1261. package/src/tools/system/navigate-settings.ts +29 -19
  1262. package/src/tools/system/open-system-settings.ts +30 -20
  1263. package/src/tools/system/request-permission.ts +59 -44
  1264. package/src/tools/system/version.ts +27 -16
  1265. package/src/tools/system/voice-config.ts +116 -53
  1266. package/src/tools/tasks/index.ts +8 -8
  1267. package/src/tools/tasks/task-delete.ts +61 -22
  1268. package/src/tools/tasks/task-list.ts +23 -11
  1269. package/src/tools/tasks/task-run.ts +41 -16
  1270. package/src/tools/tasks/task-save.ts +27 -10
  1271. package/src/tools/tasks/work-item-enqueue.ts +114 -48
  1272. package/src/tools/tasks/work-item-list.ts +20 -10
  1273. package/src/tools/tasks/work-item-remove.ts +49 -15
  1274. package/src/tools/tasks/work-item-run.ts +34 -13
  1275. package/src/tools/tasks/work-item-update.ts +84 -31
  1276. package/src/tools/terminal/backends/native.ts +64 -35
  1277. package/src/tools/terminal/backends/types.ts +6 -2
  1278. package/src/tools/terminal/parser.ts +200 -125
  1279. package/src/tools/terminal/safe-env.ts +27 -21
  1280. package/src/tools/terminal/sandbox-diagnostics.ts +31 -13
  1281. package/src/tools/terminal/sandbox.ts +10 -6
  1282. package/src/tools/terminal/shell.ts +134 -68
  1283. package/src/tools/tool-approval-handler.ts +239 -140
  1284. package/src/tools/types.ts +79 -22
  1285. package/src/tools/ui-surface/definitions.ts +124 -89
  1286. package/src/tools/ui-surface/registry.ts +2 -2
  1287. package/src/tools/watch/screen-watch.ts +50 -32
  1288. package/src/tools/watch/watch-state.ts +41 -15
  1289. package/src/tools/watcher/create.ts +37 -15
  1290. package/src/tools/watcher/delete.ts +9 -6
  1291. package/src/tools/watcher/digest.ts +10 -6
  1292. package/src/tools/watcher/list.ts +37 -14
  1293. package/src/tools/watcher/update.ts +33 -18
  1294. package/src/tools/weather/service.ts +331 -174
  1295. package/src/twitter/client.ts +261 -138
  1296. package/src/twitter/oauth-client.ts +17 -13
  1297. package/src/twitter/router.ts +51 -23
  1298. package/src/twitter/session.ts +27 -18
  1299. package/src/types/qrcode.d.ts +6 -3
  1300. package/src/usage/actors.ts +16 -16
  1301. package/src/usage/types.ts +3 -3
  1302. package/src/util/bundled-asset.ts +10 -6
  1303. package/src/util/canonicalize-identity.ts +11 -4
  1304. package/src/util/clipboard.ts +7 -7
  1305. package/src/util/content-id.ts +3 -3
  1306. package/src/util/debounce.ts +3 -2
  1307. package/src/util/diff.ts +55 -33
  1308. package/src/util/errors.ts +31 -27
  1309. package/src/util/fs.ts +8 -2
  1310. package/src/util/log-redact.ts +12 -12
  1311. package/src/util/logger.ts +112 -51
  1312. package/src/util/network-info.ts +13 -5
  1313. package/src/util/object.ts +4 -2
  1314. package/src/util/phone.ts +4 -4
  1315. package/src/util/platform.ts +80 -58
  1316. package/src/util/pricing.ts +49 -31
  1317. package/src/util/retry.ts +39 -7
  1318. package/src/util/row-mapper.ts +7 -4
  1319. package/src/util/silently.ts +7 -4
  1320. package/src/util/spawn.ts +48 -0
  1321. package/src/util/spinner.ts +9 -7
  1322. package/src/util/time.ts +16 -3
  1323. package/src/util/truncate.ts +1 -1
  1324. package/src/util/voice-code.ts +6 -4
  1325. package/src/util/xml.ts +5 -1
  1326. package/src/version.ts +12 -8
  1327. package/src/watcher/engine.ts +71 -44
  1328. package/src/watcher/provider-registry.ts +1 -1
  1329. package/src/watcher/providers/github.ts +40 -23
  1330. package/src/watcher/providers/gmail.ts +59 -38
  1331. package/src/watcher/providers/google-calendar.ts +62 -48
  1332. package/src/watcher/providers/linear.ts +219 -150
  1333. package/src/watcher/providers/slack.ts +125 -29
  1334. package/src/watcher/watcher-store.ts +75 -55
  1335. package/src/work-items/work-item-runner.ts +62 -29
  1336. package/src/work-items/work-item-store.ts +137 -47
  1337. package/src/workspace/commit-message-enrichment-service.ts +65 -25
  1338. package/src/workspace/commit-message-provider.ts +14 -12
  1339. package/src/workspace/git-service.ts +355 -239
  1340. package/src/workspace/heartbeat-service.ts +74 -37
  1341. package/src/workspace/provider-commit-message-generator.ts +95 -70
  1342. package/src/workspace/top-level-renderer.ts +10 -8
  1343. package/src/workspace/top-level-scanner.ts +9 -3
  1344. package/src/workspace/turn-commit.ts +63 -36
  1345. package/src/__tests__/ingress-member-store.test.ts +0 -294
  1346. package/src/__tests__/script-proxy-router.test.ts +0 -215
  1347. package/src/config/bundled-skills/trusted-contacts/SKILL.md +0 -372
  1348. package/src/memory/guardian-bindings.ts +0 -158
  1349. package/src/memory/ingress-member-store.ts +0 -352
  1350. package/src/runtime/routes/ingress-routes.ts +0 -229
  1351. package/src/tools/network/script-proxy/__tests__/router.test.ts +0 -77
  1352. package/src/tools/network/script-proxy/certs.ts +0 -7
  1353. package/src/tools/network/script-proxy/connect-tunnel.ts +0 -1
  1354. package/src/tools/network/script-proxy/http-forwarder.ts +0 -2
  1355. package/src/tools/network/script-proxy/logging.ts +0 -12
  1356. package/src/tools/network/script-proxy/mitm-handler.ts +0 -2
  1357. package/src/tools/network/script-proxy/policy.ts +0 -4
  1358. package/src/tools/network/script-proxy/router.ts +0 -2
  1359. package/src/tools/network/script-proxy/server.ts +0 -5
  1360. package/src/tools/network/script-proxy/types.ts +0 -19
@@ -32,32 +32,44 @@ import {
32
32
  getGatewayInternalBaseUrl,
33
33
  hasUngatedHttpAuthDisabled,
34
34
  isHttpAuthDisabled,
35
- } from '../config/env.js';
36
- import type { ServerMessage } from '../daemon/ipc-contract.js';
37
- import { PairingStore } from '../daemon/pairing-store.js';
38
- import { type Confidence, getAttentionStateByConversationIds, recordConversationSeenSignal, type SignalType } from '../memory/conversation-attention-store.js';
39
- import * as conversationStore from '../memory/conversation-store.js';
40
- import * as externalConversationStore from '../memory/external-conversation-store.js';
41
- import { consumeCallback, consumeCallbackError } from '../security/oauth-callback-registry.js';
42
- import { getLogger } from '../util/logger.js';
43
- import { buildAssistantEvent } from './assistant-event.js';
44
- import { assistantEventHub } from './assistant-event-hub.js';
45
- import { DAEMON_INTERNAL_ASSISTANT_ID } from './assistant-scope.js';
35
+ } from "../config/env.js";
36
+ import type { ServerMessage } from "../daemon/ipc-contract.js";
37
+ import { PairingStore } from "../daemon/pairing-store.js";
38
+ import {
39
+ type Confidence,
40
+ getAttentionStateByConversationIds,
41
+ recordConversationSeenSignal,
42
+ type SignalType,
43
+ } from "../memory/conversation-attention-store.js";
44
+ import * as conversationStore from "../memory/conversation-store.js";
45
+ import * as externalConversationStore from "../memory/external-conversation-store.js";
46
+ import {
47
+ consumeCallback,
48
+ consumeCallbackError,
49
+ } from "../security/oauth-callback-registry.js";
50
+ import { getLogger } from "../util/logger.js";
51
+ import { buildAssistantEvent } from "./assistant-event.js";
52
+ import { assistantEventHub } from "./assistant-event-hub.js";
53
+ import { DAEMON_INTERNAL_ASSISTANT_ID } from "./assistant-scope.js";
46
54
  // Auth
47
- import { authenticateRequest } from './auth/middleware.js';
48
- import { enforcePolicy, getPolicy } from './auth/route-policy.js';
49
- import { mintDaemonDeliveryToken, mintUiPageToken, verifyToken } from './auth/token-service.js';
50
- import type { AuthContext } from './auth/types.js';
51
- import { sweepFailedEvents } from './channel-retry-sweep.js';
52
- import { httpError } from './http-errors.js';
55
+ import { authenticateRequest } from "./auth/middleware.js";
56
+ import {
57
+ mintDaemonDeliveryToken,
58
+ mintUiPageToken,
59
+ verifyToken,
60
+ } from "./auth/token-service.js";
61
+ import { sweepFailedEvents } from "./channel-retry-sweep.js";
62
+ import { httpError } from "./http-errors.js";
63
+ import type { RouteDefinition } from "./http-router.js";
64
+ import { HttpRouter } from "./http-router.js";
53
65
  // Middleware
54
66
  import {
55
67
  extractBearerToken,
56
68
  isLoopbackHost,
57
69
  isPrivateNetworkOrigin,
58
70
  isPrivateNetworkPeer,
59
- } from './middleware/auth.js';
60
- import { withErrorHandling } from './middleware/error-handler.js';
71
+ } from "./middleware/auth.js";
72
+ import { withErrorHandling } from "./middleware/error-handler.js";
61
73
  import {
62
74
  apiRateLimiter,
63
75
  extractClientIp,
@@ -126,6 +138,8 @@ import {
126
138
  handleGetContact,
127
139
  handleListContacts,
128
140
  handleMergeContacts,
141
+ handleUpdateContactChannel,
142
+ handleUpsertContact,
129
143
  } from "./routes/contact-routes.js";
130
144
  import { handleListConversationAttention } from "./routes/conversation-attention-routes.js";
131
145
  // Route handlers — grouped by domain
@@ -137,6 +151,7 @@ import {
137
151
  } from "./routes/conversation-routes.js";
138
152
  import { handleDebug } from "./routes/debug-routes.js";
139
153
  import { handleSubscribeAssistantEvents } from "./routes/events-routes.js";
154
+ import { handleGlobalSearch } from "./routes/global-search-routes.js";
140
155
  import {
141
156
  handleGuardianActionDecision,
142
157
  handleGuardianActionsPending,
@@ -144,16 +159,6 @@ import {
144
159
  import { handleGuardianBootstrap } from "./routes/guardian-bootstrap-routes.js";
145
160
  import { handleGuardianRefresh } from "./routes/guardian-refresh-routes.js";
146
161
  import { handleGetIdentity, handleHealth } from "./routes/identity-routes.js";
147
- import {
148
- handleBlockMember,
149
- handleCreateInvite,
150
- handleListInvites,
151
- handleListMembers,
152
- handleRedeemInvite,
153
- handleRevokeInvite,
154
- handleRevokeMember,
155
- handleUpsertMember,
156
- } from "./routes/ingress-routes.js";
157
162
  import {
158
163
  handleCancelOutbound,
159
164
  handleClearSlackChannelConfig,
@@ -163,12 +168,25 @@ import {
163
168
  handleGetSlackChannelConfig,
164
169
  handleGetTelegramConfig,
165
170
  handleResendOutbound,
171
+ handleRevokeGuardian,
166
172
  handleSetSlackChannelConfig,
167
173
  handleSetTelegramCommands,
168
174
  handleSetTelegramConfig,
169
175
  handleSetupTelegram,
170
176
  handleStartOutbound,
171
177
  } from "./routes/integration-routes.js";
178
+ import {
179
+ handleCreateInvite,
180
+ handleListInvites,
181
+ handleRedeemInvite,
182
+ handleRevokeInvite,
183
+ } from "./routes/invite-routes.js";
184
+ import {
185
+ handleMigrationExport,
186
+ handleMigrationImport,
187
+ handleMigrationImportPreflight,
188
+ handleMigrationValidate,
189
+ } from "./routes/migration-routes.js";
172
190
  import type { PairingHandlerContext } from "./routes/pairing-routes.js";
173
191
  // Extracted route handlers
174
192
  import {
@@ -236,68 +254,6 @@ const DEFAULT_HOSTNAME = "127.0.0.1";
236
254
  /** Global hard cap on request body size (50 MB). */
237
255
  const MAX_REQUEST_BODY_BYTES = 50 * 1024 * 1024;
238
256
 
239
- // ---------------------------------------------------------------------------
240
- // Parameterized endpoint normalization for policy lookup
241
- // ---------------------------------------------------------------------------
242
-
243
- /**
244
- * Patterns that map parameterized URLs back to their policy registry keys.
245
- * Order matters: more specific patterns must come before general ones so
246
- * that e.g. `attachments/{id}/content` matches before `attachments/{id}`.
247
- */
248
- const PARAMETERIZED_ROUTE_PATTERNS: Array<{ re: RegExp; policyBase: string }> = [
249
- // calls/{id}/cancel, calls/{id}/answer, calls/{id}/instruction
250
- { re: /^calls\/[^/]+\/(cancel|answer|instruction)$/, policyBase: 'calls/$1' },
251
- // calls/{id} (GET status)
252
- { re: /^calls\/[^/]+$/, policyBase: 'calls' },
253
- // contacts/{id}
254
- { re: /^contacts\/[^/]+$/, policyBase: 'contacts' },
255
- // ingress/members/{id}/block
256
- { re: /^ingress\/members\/[^/]+\/block$/, policyBase: 'ingress/members/block' },
257
- // ingress/members/{id}
258
- { re: /^ingress\/members\/[^/]+$/, policyBase: 'ingress/members' },
259
- // ingress/invites/{id}
260
- { re: /^ingress\/invites\/[^/]+$/, policyBase: 'ingress/invites' },
261
- // integrations/twilio/sms/compliance/tollfree/{sid}
262
- { re: /^integrations\/twilio\/sms\/compliance\/tollfree\/[^/]+$/, policyBase: 'integrations/twilio/sms/compliance/tollfree' },
263
- // attachments/{id}/content
264
- { re: /^attachments\/[^/]+\/content$/, policyBase: 'attachments/content' },
265
- // attachments/{id}
266
- { re: /^attachments\/[^/]+$/, policyBase: 'attachments' },
267
- // trust-rules/manage/{id}
268
- { re: /^trust-rules\/manage\/[^/]+$/, policyBase: 'trust-rules/manage' },
269
- // interfaces/{path}
270
- { re: /^interfaces\/.+$/, policyBase: 'interfaces' },
271
- ];
272
-
273
- /**
274
- * Strip parameterized segments from an endpoint string so it matches
275
- * the base route name used in the policy registry.
276
- *
277
- * For example, `calls/abc123` becomes `calls`, and
278
- * `attachments/abc123/content` becomes `attachments/content`.
279
- *
280
- * If the raw endpoint already has a direct policy registered (either
281
- * bare or with a method qualifier), normalization is skipped. This
282
- * prevents literal sub-routes like `calls/start` from being
283
- * incorrectly collapsed to `calls`.
284
- */
285
- function normalizeEndpointForPolicy(endpoint: string, method: string): string {
286
- // If the exact endpoint (with or without method) has a direct policy, don't normalize
287
- if (getPolicy(`${endpoint}:${method}`) || getPolicy(endpoint)) {
288
- return endpoint;
289
- }
290
-
291
- for (const { re, policyBase } of PARAMETERIZED_ROUTE_PATTERNS) {
292
- const match = endpoint.match(re);
293
- if (match) {
294
- // Support capture-group substitution (e.g. calls/$1 -> calls/cancel)
295
- return policyBase.replace(/\$(\d+)/g, (_, idx) => match[Number(idx)] ?? '');
296
- }
297
- }
298
- return endpoint;
299
- }
300
-
301
257
  export class RuntimeHttpServer {
302
258
  private server: ReturnType<typeof Bun.serve> | null = null;
303
259
  private port: number;
@@ -327,6 +283,7 @@ export class RuntimeHttpServer {
327
283
  ): void;
328
284
  }
329
285
  | undefined;
286
+ private router: HttpRouter;
330
287
 
331
288
  constructor(options: RuntimeHttpServerOptions = {}) {
332
289
  this.port = options.port ?? DEFAULT_PORT;
@@ -342,6 +299,7 @@ export class RuntimeHttpServer {
342
299
  this.interfacesDir = options.interfacesDir ?? null;
343
300
  this.sendMessageDeps = options.sendMessageDeps;
344
301
  this.findSession = options.findSession;
302
+ this.router = new HttpRouter(this.buildRouteTable());
345
303
  }
346
304
 
347
305
  /** The port the server is actually listening on (resolved after start). */
@@ -597,10 +555,16 @@ export class RuntimeHttpServer {
597
555
  // needs to work when the access token is expired. Bootstrap has its
598
556
  // own loopback IP validation; refresh is secured by the refresh token
599
557
  // in the request body (32 random bytes, hash-only storage).
600
- if (path === '/v1/integrations/guardian/vellum/bootstrap' && req.method === 'POST') {
558
+ if (
559
+ path === "/v1/integrations/guardian/vellum/bootstrap" &&
560
+ req.method === "POST"
561
+ ) {
601
562
  return await handleGuardianBootstrap(req, server);
602
563
  }
603
- if (path === '/v1/integrations/guardian/vellum/refresh' && req.method === 'POST') {
564
+ if (
565
+ path === "/v1/integrations/guardian/vellum/refresh" &&
566
+ req.method === "POST"
567
+ ) {
604
568
  return await handleGuardianRefresh(req);
605
569
  }
606
570
 
@@ -612,13 +576,27 @@ export class RuntimeHttpServer {
612
576
  }
613
577
  const authContext = authResult.context;
614
578
 
579
+ // Serve shareable app pages (outside /v1/ namespace, no rate limiting)
580
+ const pagesMatch = path.match(/^\/pages\/([^/]+)$/);
581
+ if (pagesMatch && req.method === "GET") {
582
+ return withErrorHandling("pages", async () =>
583
+ handleServePage(pagesMatch[1]),
584
+ );
585
+ }
586
+
615
587
  // Per-client-IP rate limiting for /v1/* endpoints. Authenticated requests
616
588
  // get a higher limit; unauthenticated requests get a lower limit to reduce
617
589
  // abuse surface. We key on IP rather than bearer token because the gateway
618
590
  // uses a single shared token for all proxied requests, which would collapse
619
591
  // all users into one bucket.
620
592
  // Skip rate limiting entirely when HTTP auth is disabled (local Docker dev).
621
- if (path.startsWith("/v1/") && !isHttpAuthDisabled()) {
593
+ if (!path.startsWith("/v1/")) {
594
+ return httpError("NOT_FOUND", "Not found", 404);
595
+ }
596
+
597
+ const endpoint = path.slice("/v1/".length);
598
+
599
+ if (!isHttpAuthDisabled()) {
622
600
  const clientIp = extractClientIp(req, server);
623
601
  const token = extractBearerToken(req);
624
602
  const result = token
@@ -627,113 +605,34 @@ export class RuntimeHttpServer {
627
605
  if (!result.allowed) {
628
606
  return rateLimitResponse(result);
629
607
  }
630
- // Attach rate limit headers to the eventual response
631
- const originalResponse = await this.handleAuthenticatedRequest(req, url, path, server, authContext);
632
- const headers = new Headers(originalResponse.headers);
608
+ const routerResponse = await this.router.dispatch(
609
+ endpoint,
610
+ req,
611
+ url,
612
+ server,
613
+ authContext,
614
+ );
615
+ const response =
616
+ routerResponse ?? httpError("NOT_FOUND", "Not found", 404);
617
+ const headers = new Headers(response.headers);
633
618
  for (const [k, v] of Object.entries(rateLimitHeaders(result))) {
634
619
  headers.set(k, v);
635
620
  }
636
- return new Response(originalResponse.body, {
637
- status: originalResponse.status,
638
- statusText: originalResponse.statusText,
621
+ return new Response(response.body, {
622
+ status: response.status,
623
+ statusText: response.statusText,
639
624
  headers,
640
625
  });
641
626
  }
642
627
 
643
- return this.handleAuthenticatedRequest(req, url, path, server, authContext);
644
- }
645
-
646
- /**
647
- * Handle requests that have already passed auth and rate limiting.
648
- */
649
- private async handleAuthenticatedRequest(req: Request, url: URL, path: string, server: ReturnType<typeof Bun.serve>, authContext: AuthContext): Promise<Response> {
650
- // Pairing registration (bearer-authenticated)
651
- if (path === '/v1/pairing/register' && req.method === 'POST') {
652
- const policyDenied = enforcePolicy('pairing/register', authContext);
653
- if (policyDenied) return policyDenied;
654
- return await handlePairingRegister(req, this.pairingContext);
655
- }
656
-
657
- // Serve shareable app pages
658
- const pagesMatch = path.match(/^\/pages\/([^/]+)$/);
659
- if (pagesMatch && req.method === "GET") {
660
- try {
661
- return handleServePage(pagesMatch[1]);
662
- } catch (err) {
663
- log.error(
664
- { err, appId: pagesMatch[1] },
665
- "Runtime HTTP handler error serving page",
666
- );
667
- return httpError("INTERNAL_ERROR", "Internal server error", 500);
668
- }
669
- }
670
-
671
- // Cloud sharing endpoints
672
- if (path === '/v1/apps/share' && req.method === 'POST') {
673
- const policyDenied = enforcePolicy('apps/share', authContext);
674
- if (policyDenied) return policyDenied;
675
- try { return await handleShareApp(req); } catch (err) {
676
- log.error({ err }, 'Runtime HTTP handler error sharing app');
677
- return httpError('INTERNAL_ERROR', 'Internal server error', 500);
678
- }
679
- }
680
-
681
- const sharedTokenMatch = path.match(/^\/v1\/apps\/shared\/([^/]+)$/);
682
- if (sharedTokenMatch) {
683
- const shareToken = sharedTokenMatch[1];
684
- if (req.method === 'GET') {
685
- const policyDenied = enforcePolicy('apps/shared:GET', authContext);
686
- if (policyDenied) return policyDenied;
687
- try { return handleDownloadSharedApp(shareToken); } catch (err) {
688
- log.error({ err, shareToken }, 'Runtime HTTP handler error downloading shared app');
689
- return httpError('INTERNAL_ERROR', 'Internal server error', 500);
690
- }
691
- }
692
- if (req.method === 'DELETE') {
693
- const policyDenied = enforcePolicy('apps/shared:DELETE', authContext);
694
- if (policyDenied) return policyDenied;
695
- try { return handleDeleteSharedApp(shareToken); } catch (err) {
696
- log.error({ err, shareToken }, 'Runtime HTTP handler error deleting shared app');
697
- return httpError('INTERNAL_ERROR', 'Internal server error', 500);
698
- }
699
- }
700
- }
701
-
702
- const sharedMetadataMatch = path.match(/^\/v1\/apps\/shared\/([^/]+)\/metadata$/);
703
- if (sharedMetadataMatch && req.method === 'GET') {
704
- const policyDenied = enforcePolicy('apps/shared/metadata', authContext);
705
- if (policyDenied) return policyDenied;
706
- try { return handleGetSharedAppMetadata(sharedMetadataMatch[1]); } catch (err) {
707
- log.error({ err, shareToken: sharedMetadataMatch[1] }, 'Runtime HTTP handler error getting shared app metadata');
708
- return httpError('INTERNAL_ERROR', 'Internal server error', 500);
709
- }
710
- }
711
-
712
- // Secret management endpoint
713
- if (path === '/v1/secrets' && req.method === 'POST') {
714
- const policyDenied = enforcePolicy('secrets', authContext);
715
- if (policyDenied) return policyDenied;
716
- try { return await handleAddSecret(req); } catch (err) {
717
- log.error({ err }, 'Runtime HTTP handler error adding secret');
718
- return httpError('INTERNAL_ERROR', 'Internal server error', 500);
719
- }
720
- }
721
- if (path === '/v1/secrets' && req.method === 'DELETE') {
722
- const policyDenied = enforcePolicy('secrets', authContext);
723
- if (policyDenied) return policyDenied;
724
- try { return await handleDeleteSecret(req); } catch (err) {
725
- log.error({ err }, 'Runtime HTTP handler error deleting secret');
726
- return httpError('INTERNAL_ERROR', 'Internal server error', 500);
727
- }
728
- }
729
-
730
- // Runtime routes: /v1/<endpoint>
731
- const routeMatch = path.match(/^\/v1\/(.+)$/);
732
- if (routeMatch) {
733
- return this.dispatchEndpoint(routeMatch[1], req, url, server, authContext);
734
- }
735
-
736
- return httpError("NOT_FOUND", "Not found", 404);
628
+ const routerResponse = await this.router.dispatch(
629
+ endpoint,
630
+ req,
631
+ url,
632
+ server,
633
+ authContext,
634
+ );
635
+ return routerResponse ?? httpError("NOT_FOUND", "Not found", 404);
737
636
  }
738
637
 
739
638
  private handleBrowserRelayUpgrade(
@@ -753,13 +652,13 @@ export class RuntimeHttpServer {
753
652
 
754
653
  if (!isHttpAuthDisabled()) {
755
654
  const wsUrl = new URL(req.url);
756
- const token = wsUrl.searchParams.get('token');
655
+ const token = wsUrl.searchParams.get("token");
757
656
  if (!token) {
758
- return httpError('UNAUTHORIZED', 'Unauthorized', 401);
657
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
759
658
  }
760
- const jwtResult = verifyToken(token, 'vellum-daemon');
659
+ const jwtResult = verifyToken(token, "vellum-daemon");
761
660
  if (!jwtResult.ok) {
762
- return httpError('UNAUTHORIZED', 'Unauthorized', 401);
661
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
763
662
  }
764
663
  }
765
664
 
@@ -842,41 +741,110 @@ export class RuntimeHttpServer {
842
741
  return null;
843
742
  }
844
743
 
744
+ private handleGetInterface(interfacePath: string): Response {
745
+ if (!this.interfacesDir) {
746
+ return httpError("NOT_FOUND", "Interface not found", 404);
747
+ }
748
+ const fullPath = resolve(this.interfacesDir, interfacePath);
749
+ if (
750
+ (fullPath !== this.interfacesDir &&
751
+ !fullPath.startsWith(this.interfacesDir + "/")) ||
752
+ !existsSync(fullPath)
753
+ ) {
754
+ return httpError("NOT_FOUND", "Interface not found", 404);
755
+ }
756
+ const source = readFileSync(fullPath, "utf-8");
757
+ return new Response(source, {
758
+ headers: { "Content-Type": "text/plain; charset=utf-8" },
759
+ });
760
+ }
761
+
762
+ // ---------------------------------------------------------------------------
763
+ // Declarative route table
764
+ // ---------------------------------------------------------------------------
765
+
845
766
  /**
846
- * Dispatch a request to the appropriate endpoint handler.
767
+ * Build the full set of route definitions. Routes are matched in order,
768
+ * so more specific patterns (e.g. `calls/:id/cancel`) must precede
769
+ * more general ones (e.g. `calls/:id`).
847
770
  */
848
- private async dispatchEndpoint(
849
- endpoint: string,
850
- req: Request,
851
- url: URL,
852
- server: ReturnType<typeof Bun.serve>,
853
- authContext: AuthContext,
854
- ): Promise<Response> {
771
+ private buildRouteTable(): RouteDefinition[] {
855
772
  const assistantId = DAEMON_INTERNAL_ASSISTANT_ID;
856
773
 
857
- // Normalize parameterized endpoints to their base policy key so that
858
- // routes like `calls/abc123` match the registered key `calls` and
859
- // `attachments/abc123/content` matches `attachments/content`.
860
- const normalizedEndpoint = normalizeEndpointForPolicy(endpoint, req.method);
861
-
862
- // Enforce route-level scope/principal policy before invoking any handler.
863
- // Try method-specific key first (e.g. "messages:POST"); fall back to the
864
- // plain endpoint key only when no method-specific policy is registered.
865
- const methodKey = `${normalizedEndpoint}:${req.method}`;
866
- const policyKey = getPolicy(methodKey) ? methodKey : normalizedEndpoint;
867
- const policyDenied = enforcePolicy(policyKey, authContext);
868
- if (policyDenied) return policyDenied;
869
-
870
- return withErrorHandling(endpoint, async () => {
871
- if (endpoint === "health" && req.method === "GET") return handleHealth();
872
- if (endpoint === "debug" && req.method === "GET") return handleDebug();
873
-
874
- if (endpoint === "browser-relay/status" && req.method === "GET") {
875
- return Response.json(extensionRelayServer.getStatus());
876
- }
774
+ return [
775
+ // ------------------------------------------------------------------
776
+ // Pairing (authenticated)
777
+ // ------------------------------------------------------------------
778
+ {
779
+ endpoint: "pairing/register",
780
+ method: "POST",
781
+ handler: async ({ req }) =>
782
+ handlePairingRegister(req, this.pairingContext),
783
+ },
877
784
 
878
- if (endpoint === "browser-relay/command" && req.method === "POST") {
879
- try {
785
+ // ------------------------------------------------------------------
786
+ // Apps — cloud sharing
787
+ // ------------------------------------------------------------------
788
+ {
789
+ endpoint: "apps/share",
790
+ method: "POST",
791
+ handler: async ({ req }) => handleShareApp(req),
792
+ },
793
+ {
794
+ endpoint: "apps/shared/:token/metadata",
795
+ method: "GET",
796
+ policyKey: "apps/shared/metadata",
797
+ handler: ({ params }) => handleGetSharedAppMetadata(params.token),
798
+ },
799
+ {
800
+ endpoint: "apps/shared/:token",
801
+ method: "GET",
802
+ policyKey: "apps/shared",
803
+ handler: ({ params }) => handleDownloadSharedApp(params.token),
804
+ },
805
+ {
806
+ endpoint: "apps/shared/:token",
807
+ method: "DELETE",
808
+ policyKey: "apps/shared",
809
+ handler: ({ params }) => handleDeleteSharedApp(params.token),
810
+ },
811
+
812
+ // ------------------------------------------------------------------
813
+ // Secrets
814
+ // ------------------------------------------------------------------
815
+ {
816
+ endpoint: "secrets",
817
+ method: "POST",
818
+ handler: async ({ req }) => handleAddSecret(req),
819
+ },
820
+ {
821
+ endpoint: "secrets",
822
+ method: "DELETE",
823
+ handler: async ({ req }) => handleDeleteSecret(req),
824
+ },
825
+
826
+ // ------------------------------------------------------------------
827
+ // Health / debug / browser relay
828
+ // ------------------------------------------------------------------
829
+ {
830
+ endpoint: "health",
831
+ method: "GET",
832
+ handler: () => handleHealth(),
833
+ },
834
+ {
835
+ endpoint: "debug",
836
+ method: "GET",
837
+ handler: () => handleDebug(),
838
+ },
839
+ {
840
+ endpoint: "browser-relay/status",
841
+ method: "GET",
842
+ handler: () => Response.json(extensionRelayServer.getStatus()),
843
+ },
844
+ {
845
+ endpoint: "browser-relay/command",
846
+ method: "POST",
847
+ handler: async ({ req }) => {
880
848
  const body = (await req.json()) as Record<string, unknown>;
881
849
  const resp = await extensionRelayServer.sendCommand(
882
850
  body as Omit<
@@ -885,482 +853,747 @@ export class RuntimeHttpServer {
885
853
  >,
886
854
  );
887
855
  return Response.json(resp);
888
- } catch (err) {
889
- return httpError(
890
- "INTERNAL_ERROR",
891
- err instanceof Error ? err.message : String(err),
892
- 500,
893
- );
894
- }
895
- }
856
+ },
857
+ },
896
858
 
897
- if (endpoint === "conversations" && req.method === "GET") {
898
- const limit = Number(url.searchParams.get("limit") ?? 50);
899
- const offset = Number(url.searchParams.get("offset") ?? 0);
900
- const conversations = conversationStore.listConversations(
901
- limit,
902
- false,
903
- offset,
904
- );
905
- const totalCount = conversationStore.countConversations();
906
- const conversationIds = conversations.map((c) => c.id);
907
- const bindings =
908
- externalConversationStore.getBindingsForConversations(
909
- conversationIds,
859
+ // ------------------------------------------------------------------
860
+ // Conversations
861
+ // ------------------------------------------------------------------
862
+ {
863
+ endpoint: "conversations",
864
+ method: "GET",
865
+ handler: ({ url }) => {
866
+ const limit = Number(url.searchParams.get("limit") ?? 50);
867
+ const offset = Number(url.searchParams.get("offset") ?? 0);
868
+ const conversations = conversationStore.listConversations(
869
+ limit,
870
+ false,
871
+ offset,
910
872
  );
911
- const attentionStates =
912
- getAttentionStateByConversationIds(conversationIds);
913
- return Response.json({
914
- sessions: conversations.map((c) => {
915
- const binding = bindings.get(c.id);
916
- const originChannel = parseChannelId(c.originChannel);
917
- const attn = attentionStates.get(c.id);
918
- const assistantAttention = attn
919
- ? {
920
- hasUnseenLatestAssistantMessage:
921
- attn.latestAssistantMessageAt != null &&
922
- (attn.lastSeenAssistantMessageAt == null ||
923
- attn.lastSeenAssistantMessageAt <
924
- attn.latestAssistantMessageAt),
925
- ...(attn.latestAssistantMessageAt != null
926
- ? {
927
- latestAssistantMessageAt: attn.latestAssistantMessageAt,
928
- }
929
- : {}),
930
- ...(attn.lastSeenAssistantMessageAt != null
931
- ? {
932
- lastSeenAssistantMessageAt:
933
- attn.lastSeenAssistantMessageAt,
934
- }
935
- : {}),
936
- ...(attn.lastSeenConfidence != null
937
- ? { lastSeenConfidence: attn.lastSeenConfidence }
938
- : {}),
939
- ...(attn.lastSeenSignalType != null
940
- ? { lastSeenSignalType: attn.lastSeenSignalType }
941
- : {}),
942
- }
943
- : undefined;
944
- return {
945
- id: c.id,
946
- title: c.title ?? "Untitled",
947
- createdAt: c.createdAt,
948
- updatedAt: c.updatedAt,
949
- threadType: c.threadType === "private" ? "private" : "standard",
950
- source: c.source ?? "user",
951
- ...(binding
873
+ const totalCount = conversationStore.countConversations();
874
+ const conversationIds = conversations.map((c) => c.id);
875
+ const bindings =
876
+ externalConversationStore.getBindingsForConversations(
877
+ conversationIds,
878
+ );
879
+ const attentionStates =
880
+ getAttentionStateByConversationIds(conversationIds);
881
+ return Response.json({
882
+ sessions: conversations.map((c) => {
883
+ const binding = bindings.get(c.id);
884
+ const originChannel = parseChannelId(c.originChannel);
885
+ const attn = attentionStates.get(c.id);
886
+ const assistantAttention = attn
952
887
  ? {
953
- channelBinding: {
954
- sourceChannel: binding.sourceChannel,
955
- externalChatId: binding.externalChatId,
956
- externalUserId: binding.externalUserId,
957
- displayName: binding.displayName,
958
- username: binding.username,
959
- },
888
+ hasUnseenLatestAssistantMessage:
889
+ attn.latestAssistantMessageAt != null &&
890
+ (attn.lastSeenAssistantMessageAt == null ||
891
+ attn.lastSeenAssistantMessageAt <
892
+ attn.latestAssistantMessageAt),
893
+ ...(attn.latestAssistantMessageAt != null
894
+ ? {
895
+ latestAssistantMessageAt:
896
+ attn.latestAssistantMessageAt,
897
+ }
898
+ : {}),
899
+ ...(attn.lastSeenAssistantMessageAt != null
900
+ ? {
901
+ lastSeenAssistantMessageAt:
902
+ attn.lastSeenAssistantMessageAt,
903
+ }
904
+ : {}),
905
+ ...(attn.lastSeenConfidence != null
906
+ ? { lastSeenConfidence: attn.lastSeenConfidence }
907
+ : {}),
908
+ ...(attn.lastSeenSignalType != null
909
+ ? { lastSeenSignalType: attn.lastSeenSignalType }
910
+ : {}),
960
911
  }
961
- : {}),
962
- ...(originChannel
963
- ? { conversationOriginChannel: originChannel }
964
- : {}),
965
- ...(assistantAttention ? { assistantAttention } : {}),
966
- };
967
- }),
968
- hasMore: offset + conversations.length < totalCount,
969
- });
970
- }
971
-
972
- if (endpoint === "conversations/attention" && req.method === "GET")
973
- return handleListConversationAttention(url);
974
-
975
- if (endpoint === "conversations/seen" && req.method === "POST") {
976
- const body = (await req.json()) as Record<string, unknown>;
977
- const conversationId = body.conversationId as string | undefined;
978
- if (!conversationId)
979
- return httpError("BAD_REQUEST", "Missing conversationId", 400);
980
- try {
981
- recordConversationSeenSignal({
982
- conversationId,
983
- assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
984
- sourceChannel: (body.sourceChannel as string) ?? "vellum",
985
- signalType: ((body.signalType as string) ??
986
- "macos_conversation_opened") as SignalType,
987
- confidence: ((body.confidence as string) ??
988
- "explicit") as Confidence,
989
- source: (body.source as string) ?? "http-api",
990
- evidenceText: body.evidenceText as string | undefined,
991
- metadata: body.metadata as Record<string, unknown> | undefined,
992
- observedAt: body.observedAt as number | undefined,
912
+ : undefined;
913
+ return {
914
+ id: c.id,
915
+ title: c.title ?? "Untitled",
916
+ createdAt: c.createdAt,
917
+ updatedAt: c.updatedAt,
918
+ threadType: c.threadType === "private" ? "private" : "standard",
919
+ source: c.source ?? "user",
920
+ ...(binding
921
+ ? {
922
+ channelBinding: {
923
+ sourceChannel: binding.sourceChannel,
924
+ externalChatId: binding.externalChatId,
925
+ externalUserId: binding.externalUserId,
926
+ displayName: binding.displayName,
927
+ username: binding.username,
928
+ },
929
+ }
930
+ : {}),
931
+ ...(originChannel
932
+ ? { conversationOriginChannel: originChannel }
933
+ : {}),
934
+ ...(assistantAttention ? { assistantAttention } : {}),
935
+ };
936
+ }),
937
+ hasMore: offset + conversations.length < totalCount,
993
938
  });
994
- return Response.json({ ok: true });
995
- } catch (err) {
996
- log.error(
997
- { err, conversationId },
998
- "POST /v1/conversations/seen: failed",
999
- );
1000
- return httpError(
1001
- "INTERNAL_ERROR",
1002
- "Failed to record seen signal",
1003
- 500,
1004
- );
1005
- }
1006
- }
939
+ },
940
+ },
941
+ {
942
+ endpoint: "conversations/attention",
943
+ method: "GET",
944
+ handler: ({ url }) => handleListConversationAttention(url),
945
+ },
946
+ {
947
+ endpoint: "conversations/seen",
948
+ method: "POST",
949
+ handler: async ({ req }) => {
950
+ const body = (await req.json()) as Record<string, unknown>;
951
+ const conversationId = body.conversationId as string | undefined;
952
+ if (!conversationId)
953
+ return httpError("BAD_REQUEST", "Missing conversationId", 400);
954
+ try {
955
+ recordConversationSeenSignal({
956
+ conversationId,
957
+ assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
958
+ sourceChannel: (body.sourceChannel as string) ?? "vellum",
959
+ signalType: ((body.signalType as string) ??
960
+ "macos_conversation_opened") as SignalType,
961
+ confidence: ((body.confidence as string) ??
962
+ "explicit") as Confidence,
963
+ source: (body.source as string) ?? "http-api",
964
+ evidenceText: body.evidenceText as string | undefined,
965
+ metadata: body.metadata as Record<string, unknown> | undefined,
966
+ observedAt: body.observedAt as number | undefined,
967
+ });
968
+ return Response.json({ ok: true });
969
+ } catch (err) {
970
+ log.error(
971
+ { err, conversationId },
972
+ "POST /v1/conversations/seen: failed",
973
+ );
974
+ return httpError(
975
+ "INTERNAL_ERROR",
976
+ "Failed to record seen signal",
977
+ 500,
978
+ );
979
+ }
980
+ },
981
+ },
1007
982
 
1008
- if (endpoint === "messages" && req.method === "GET")
1009
- return handleListMessages(url, this.interfacesDir);
1010
- if (endpoint === "search" && req.method === "GET")
1011
- return handleSearchConversations(url);
1012
-
1013
- if (endpoint === 'messages' && req.method === 'POST') {
1014
- return await handleSendMessage(req, {
1015
- processMessage: this.processMessage,
1016
- persistAndProcessMessage: this.persistAndProcessMessage,
1017
- sendMessageDeps: this.sendMessageDeps,
1018
- approvalConversationGenerator: this.approvalConversationGenerator,
1019
- }, authContext);
1020
- }
983
+ // ------------------------------------------------------------------
984
+ // Messages / search
985
+ // ------------------------------------------------------------------
986
+ {
987
+ endpoint: "messages",
988
+ method: "GET",
989
+ handler: ({ url }) => handleListMessages(url, this.interfacesDir),
990
+ },
991
+ {
992
+ endpoint: "messages",
993
+ method: "POST",
994
+ handler: async ({ req, authContext }) =>
995
+ handleSendMessage(
996
+ req,
997
+ {
998
+ processMessage: this.processMessage,
999
+ persistAndProcessMessage: this.persistAndProcessMessage,
1000
+ sendMessageDeps: this.sendMessageDeps,
1001
+ approvalConversationGenerator: this.approvalConversationGenerator,
1002
+ },
1003
+ authContext,
1004
+ ),
1005
+ },
1006
+ {
1007
+ endpoint: "search",
1008
+ method: "GET",
1009
+ handler: ({ url }) => handleSearchConversations(url),
1010
+ },
1011
+ {
1012
+ endpoint: "search/global",
1013
+ method: "GET",
1014
+ handler: async ({ url }) => handleGlobalSearch(url),
1015
+ },
1021
1016
 
1022
- // Standalone approval endpoints — keyed by requestId, orthogonal to message sending
1023
- if (endpoint === 'confirm' && req.method === 'POST') return await handleConfirm(req, authContext);
1024
- if (endpoint === 'secret' && req.method === 'POST') return await handleSecret(req, authContext);
1025
- if (endpoint === 'trust-rules' && req.method === 'POST') return await handleTrustRule(req, authContext);
1026
- if (endpoint === 'pending-interactions' && req.method === 'GET') return handleListPendingInteractions(url, authContext);
1027
-
1028
- // Trust rule CRUD standalone management (not approval-flow)
1029
- if (endpoint === "trust-rules/manage" && req.method === "GET")
1030
- return handleListTrustRules();
1031
- if (endpoint === "trust-rules/manage" && req.method === "POST")
1032
- return await handleAddTrustRuleManage(req);
1033
- const trustRuleManageMatch = endpoint.match(
1034
- /^trust-rules\/manage\/([^/]+)$/,
1035
- );
1036
- if (trustRuleManageMatch && req.method === "DELETE")
1037
- return handleRemoveTrustRuleManage(trustRuleManageMatch[1]);
1038
- if (trustRuleManageMatch && req.method === "PATCH")
1039
- return await handleUpdateTrustRuleManage(req, trustRuleManageMatch[1]);
1040
-
1041
- // Surface action dispatch
1042
- if (endpoint === "surface-actions" && req.method === "POST") {
1043
- if (!this.findSession) {
1044
- return httpError(
1045
- "NOT_IMPLEMENTED",
1046
- "Surface actions not available",
1047
- 501,
1048
- );
1049
- }
1050
- return await handleSurfaceAction(req, this.findSession);
1051
- }
1017
+ // ------------------------------------------------------------------
1018
+ // Approvals
1019
+ // ------------------------------------------------------------------
1020
+ {
1021
+ endpoint: "confirm",
1022
+ method: "POST",
1023
+ handler: async ({ req, authContext }) =>
1024
+ handleConfirm(req, authContext),
1025
+ },
1026
+ {
1027
+ endpoint: "secret",
1028
+ method: "POST",
1029
+ handler: async ({ req, authContext }) => handleSecret(req, authContext),
1030
+ },
1031
+ {
1032
+ endpoint: "trust-rules",
1033
+ method: "POST",
1034
+ handler: async ({ req, authContext }) =>
1035
+ handleTrustRule(req, authContext),
1036
+ },
1037
+ {
1038
+ endpoint: "pending-interactions",
1039
+ method: "GET",
1040
+ handler: ({ url, authContext }) =>
1041
+ handleListPendingInteractions(url, authContext),
1042
+ },
1052
1043
 
1053
- // Guardian action endpoints — deterministic button-based decisions
1054
- if (endpoint === 'guardian-actions/pending' && req.method === 'GET') return handleGuardianActionsPending(url, authContext);
1055
- if (endpoint === 'guardian-actions/decision' && req.method === 'POST') return await handleGuardianActionDecision(req, authContext);
1044
+ // ------------------------------------------------------------------
1045
+ // Trust rule CRUD management
1046
+ // ------------------------------------------------------------------
1047
+ {
1048
+ endpoint: "trust-rules/manage",
1049
+ method: "GET",
1050
+ handler: () => handleListTrustRules(),
1051
+ },
1052
+ {
1053
+ endpoint: "trust-rules/manage",
1054
+ method: "POST",
1055
+ handler: async ({ req }) => handleAddTrustRuleManage(req),
1056
+ },
1057
+ {
1058
+ endpoint: "trust-rules/manage/:id",
1059
+ method: "DELETE",
1060
+ handler: ({ params }) => handleRemoveTrustRuleManage(params.id),
1061
+ },
1062
+ {
1063
+ endpoint: "trust-rules/manage/:id",
1064
+ method: "PATCH",
1065
+ handler: async ({ req, params }) =>
1066
+ handleUpdateTrustRuleManage(req, params.id),
1067
+ },
1068
+
1069
+ // ------------------------------------------------------------------
1070
+ // Surface actions
1071
+ // ------------------------------------------------------------------
1072
+ {
1073
+ endpoint: "surface-actions",
1074
+ method: "POST",
1075
+ handler: async ({ req }) => {
1076
+ if (!this.findSession) {
1077
+ return httpError(
1078
+ "NOT_IMPLEMENTED",
1079
+ "Surface actions not available",
1080
+ 501,
1081
+ );
1082
+ }
1083
+ return handleSurfaceAction(req, this.findSession);
1084
+ },
1085
+ },
1086
+
1087
+ // ------------------------------------------------------------------
1088
+ // Guardian actions
1089
+ // ------------------------------------------------------------------
1090
+ {
1091
+ endpoint: "guardian-actions/pending",
1092
+ method: "GET",
1093
+ handler: ({ url, authContext }) =>
1094
+ handleGuardianActionsPending(url, authContext),
1095
+ },
1096
+ {
1097
+ endpoint: "guardian-actions/decision",
1098
+ method: "POST",
1099
+ handler: async ({ req, authContext }) =>
1100
+ handleGuardianActionDecision(req, authContext),
1101
+ },
1056
1102
 
1103
+ // ------------------------------------------------------------------
1057
1104
  // Contacts
1058
- if (endpoint === "contacts" && req.method === "GET")
1059
- return handleListContacts(url);
1060
- if (endpoint === "contacts/merge" && req.method === "POST")
1061
- return await handleMergeContacts(req);
1062
- const contactMatch = endpoint.match(/^contacts\/([^/]+)$/);
1063
- if (contactMatch && req.method === "GET")
1064
- return handleGetContact(contactMatch[1]);
1065
-
1066
- // Ingress members
1067
- if (endpoint === "ingress/members" && req.method === "GET")
1068
- return handleListMembers(url);
1069
- if (endpoint === "ingress/members" && req.method === "POST")
1070
- return await handleUpsertMember(req);
1071
- const memberBlockMatch = endpoint.match(
1072
- /^ingress\/members\/([^/]+)\/block$/,
1073
- );
1074
- if (memberBlockMatch && req.method === "POST")
1075
- return await handleBlockMember(req, memberBlockMatch[1]);
1076
- const memberMatch = endpoint.match(/^ingress\/members\/([^/]+)$/);
1077
- if (memberMatch && req.method === "DELETE")
1078
- return await handleRevokeMember(req, memberMatch[1]);
1079
-
1080
- // Ingress invites
1081
- if (endpoint === "ingress/invites" && req.method === "GET")
1082
- return handleListInvites(url);
1083
- if (endpoint === "ingress/invites" && req.method === "POST")
1084
- return await handleCreateInvite(req);
1085
- if (endpoint === "ingress/invites/redeem" && req.method === "POST")
1086
- return await handleRedeemInvite(req);
1087
- const inviteMatch = endpoint.match(/^ingress\/invites\/([^/]+)$/);
1088
- if (inviteMatch && req.method === "DELETE")
1089
- return handleRevokeInvite(inviteMatch[1]);
1090
-
1091
- // Integrations — Telegram config
1092
- if (endpoint === "integrations/telegram/config" && req.method === "GET")
1093
- return handleGetTelegramConfig();
1094
- if (endpoint === "integrations/telegram/config" && req.method === "POST")
1095
- return await handleSetTelegramConfig(req);
1096
- if (
1097
- endpoint === "integrations/telegram/config" &&
1098
- req.method === "DELETE"
1099
- )
1100
- return await handleClearTelegramConfig();
1101
- if (
1102
- endpoint === "integrations/telegram/commands" &&
1103
- req.method === "POST"
1104
- )
1105
- return await handleSetTelegramCommands(req);
1106
- if (endpoint === "integrations/telegram/setup" && req.method === "POST")
1107
- return await handleSetupTelegram(req);
1108
-
1109
- // Integrations — Slack channel config
1110
- if (
1111
- endpoint === "integrations/slack/channel/config" &&
1112
- req.method === "GET"
1113
- )
1114
- return handleGetSlackChannelConfig();
1115
- if (
1116
- endpoint === "integrations/slack/channel/config" &&
1117
- req.method === "POST"
1118
- )
1119
- return await handleSetSlackChannelConfig(req);
1120
- if (
1121
- endpoint === "integrations/slack/channel/config" &&
1122
- req.method === "DELETE"
1123
- )
1124
- return handleClearSlackChannelConfig();
1125
-
1126
- // Integrations — Guardian verification
1127
- if (
1128
- endpoint === "integrations/guardian/challenge" &&
1129
- req.method === "POST"
1130
- )
1131
- return await handleCreateGuardianChallenge(req);
1132
- if (endpoint === "integrations/guardian/status" && req.method === "GET")
1133
- return handleGetGuardianStatus(url);
1134
- if (
1135
- endpoint === "integrations/guardian/outbound/start" &&
1136
- req.method === "POST"
1137
- )
1138
- return await handleStartOutbound(req);
1139
- if (
1140
- endpoint === "integrations/guardian/outbound/resend" &&
1141
- req.method === "POST"
1142
- )
1143
- return await handleResendOutbound(req);
1144
- if (
1145
- endpoint === "integrations/guardian/outbound/cancel" &&
1146
- req.method === "POST"
1147
- )
1148
- return await handleCancelOutbound(req);
1149
-
1150
- // Guardian vellum channel bootstrap and refresh are handled before
1151
- // JWT auth in routeRequest() — they are not dispatched here.
1152
-
1153
- // Integrations — Twilio config
1154
- if (endpoint === "integrations/twilio/config" && req.method === "GET")
1155
- return handleGetTwilioConfig();
1156
- if (
1157
- endpoint === "integrations/twilio/credentials" &&
1158
- req.method === "POST"
1159
- )
1160
- return await handleSetTwilioCredentials(req);
1161
- if (
1162
- endpoint === "integrations/twilio/credentials" &&
1163
- req.method === "DELETE"
1164
- )
1165
- return handleClearTwilioCredentials();
1166
- if (endpoint === "integrations/twilio/numbers" && req.method === "GET")
1167
- return await handleListTwilioNumbers();
1168
- if (
1169
- endpoint === "integrations/twilio/numbers/provision" &&
1170
- req.method === "POST"
1171
- )
1172
- return await handleProvisionTwilioNumber(req);
1173
- if (
1174
- endpoint === "integrations/twilio/numbers/assign" &&
1175
- req.method === "POST"
1176
- )
1177
- return await handleAssignTwilioNumber(req);
1178
- if (
1179
- endpoint === "integrations/twilio/numbers/release" &&
1180
- req.method === "POST"
1181
- )
1182
- return await handleReleaseTwilioNumber(req);
1183
- if (
1184
- endpoint === "integrations/twilio/sms/compliance" &&
1185
- req.method === "GET"
1186
- )
1187
- return await handleGetSmsCompliance();
1188
- if (
1189
- endpoint === "integrations/twilio/sms/compliance/tollfree" &&
1190
- req.method === "POST"
1191
- )
1192
- return await handleSubmitTollfreeVerification(req);
1193
- if (endpoint === "integrations/twilio/sms/test" && req.method === "POST")
1194
- return await handleSmsSendTest(req);
1195
- if (
1196
- endpoint === "integrations/twilio/sms/doctor" &&
1197
- req.method === "POST"
1198
- )
1199
- return await handleSmsDoctor();
1200
-
1201
- // Twilio toll-free verification PATCH/DELETE with :verificationSid
1202
- const tollfreeVerificationMatch = endpoint.match(
1203
- /^integrations\/twilio\/sms\/compliance\/tollfree\/([^/]+)$/,
1204
- );
1205
- if (tollfreeVerificationMatch) {
1206
- const verificationSid = tollfreeVerificationMatch[1];
1207
- if (req.method === "PATCH")
1208
- return await handleUpdateTollfreeVerification(req, verificationSid);
1209
- if (req.method === "DELETE")
1210
- return await handleDeleteTollfreeVerification(verificationSid);
1211
- }
1105
+ // ------------------------------------------------------------------
1106
+ {
1107
+ endpoint: "contacts",
1108
+ method: "GET",
1109
+ handler: ({ url, authContext }) =>
1110
+ handleListContacts(url, authContext.assistantId),
1111
+ },
1112
+ {
1113
+ endpoint: "contacts",
1114
+ method: "POST",
1115
+ handler: async ({ req, authContext }) =>
1116
+ handleUpsertContact(req, authContext.assistantId),
1117
+ },
1118
+ {
1119
+ endpoint: "contacts/merge",
1120
+ method: "POST",
1121
+ handler: async ({ req, authContext }) =>
1122
+ handleMergeContacts(req, authContext.assistantId),
1123
+ },
1124
+ {
1125
+ endpoint: "contacts/channels/:id",
1126
+ method: "PATCH",
1127
+ policyKey: "contacts/channels",
1128
+ handler: async ({ req, params, authContext }) =>
1129
+ handleUpdateContactChannel(req, params.id, authContext.assistantId),
1130
+ },
1212
1131
 
1213
- // Channel readiness
1214
- if (endpoint === "channels/readiness" && req.method === "GET")
1215
- return await handleGetChannelReadiness(url);
1216
- if (endpoint === "channels/readiness/refresh" && req.method === "POST")
1217
- return await handleRefreshChannelReadiness(req);
1218
-
1219
- if (endpoint === "attachments" && req.method === "POST")
1220
- return await handleUploadAttachment(req);
1221
- if (endpoint === "attachments" && req.method === "DELETE")
1222
- return await handleDeleteAttachment(req);
1223
-
1224
- const attachmentContentMatch = endpoint.match(
1225
- /^attachments\/([^/]+)\/content$/,
1226
- );
1227
- if (attachmentContentMatch && req.method === "GET")
1228
- return handleGetAttachmentContent(attachmentContentMatch[1], req);
1132
+ // ------------------------------------------------------------------
1133
+ // Contacts invites must precede contacts/:id to avoid shadowing
1134
+ // ------------------------------------------------------------------
1135
+ {
1136
+ endpoint: "contacts/invites",
1137
+ method: "GET",
1138
+ handler: ({ url }) => handleListInvites(url),
1139
+ },
1140
+ {
1141
+ endpoint: "contacts/invites",
1142
+ method: "POST",
1143
+ handler: async ({ req }) => handleCreateInvite(req),
1144
+ },
1145
+ {
1146
+ endpoint: "contacts/invites/redeem",
1147
+ method: "POST",
1148
+ handler: async ({ req }) => handleRedeemInvite(req),
1149
+ },
1150
+ {
1151
+ endpoint: "contacts/invites/:id",
1152
+ method: "DELETE",
1153
+ policyKey: "contacts/invites",
1154
+ handler: ({ params }) => handleRevokeInvite(params.id),
1155
+ },
1156
+
1157
+ {
1158
+ endpoint: "contacts/:id",
1159
+ method: "GET",
1160
+ policyKey: "contacts",
1161
+ handler: ({ params, authContext }) =>
1162
+ handleGetContact(params.id, authContext.assistantId),
1163
+ },
1229
1164
 
1230
- const attachmentMatch = endpoint.match(/^attachments\/([^/]+)$/);
1231
- if (attachmentMatch && req.method === "GET")
1232
- return handleGetAttachment(attachmentMatch[1]);
1165
+ // ------------------------------------------------------------------
1166
+ // Integrations Telegram
1167
+ // ------------------------------------------------------------------
1168
+ {
1169
+ endpoint: "integrations/telegram/config",
1170
+ method: "GET",
1171
+ handler: () => handleGetTelegramConfig(),
1172
+ },
1173
+ {
1174
+ endpoint: "integrations/telegram/config",
1175
+ method: "POST",
1176
+ handler: async ({ req }) => handleSetTelegramConfig(req),
1177
+ },
1178
+ {
1179
+ endpoint: "integrations/telegram/config",
1180
+ method: "DELETE",
1181
+ handler: async () => handleClearTelegramConfig(),
1182
+ },
1183
+ {
1184
+ endpoint: "integrations/telegram/commands",
1185
+ method: "POST",
1186
+ handler: async ({ req }) => handleSetTelegramCommands(req),
1187
+ },
1188
+ {
1189
+ endpoint: "integrations/telegram/setup",
1190
+ method: "POST",
1191
+ handler: async ({ req }) => handleSetupTelegram(req),
1192
+ },
1233
1193
 
1234
- if (endpoint === "suggestion" && req.method === "GET") {
1235
- return await handleGetSuggestion(url, {
1236
- suggestionCache: this.suggestionCache,
1237
- suggestionInFlight: this.suggestionInFlight,
1238
- });
1239
- }
1194
+ // ------------------------------------------------------------------
1195
+ // Integrations Slack
1196
+ // ------------------------------------------------------------------
1197
+ {
1198
+ endpoint: "integrations/slack/channel/config",
1199
+ method: "GET",
1200
+ handler: () => handleGetSlackChannelConfig(),
1201
+ },
1202
+ {
1203
+ endpoint: "integrations/slack/channel/config",
1204
+ method: "POST",
1205
+ handler: async ({ req }) => handleSetSlackChannelConfig(req),
1206
+ },
1207
+ {
1208
+ endpoint: "integrations/slack/channel/config",
1209
+ method: "DELETE",
1210
+ handler: () => handleClearSlackChannelConfig(),
1211
+ },
1240
1212
 
1241
- const interfacesMatch = endpoint.match(/^interfaces\/(.+)$/);
1242
- if (interfacesMatch && req.method === "GET")
1243
- return this.handleGetInterface(interfacesMatch[1]);
1213
+ // ------------------------------------------------------------------
1214
+ // Integrations Guardian
1215
+ // ------------------------------------------------------------------
1216
+ {
1217
+ endpoint: "integrations/guardian/challenge",
1218
+ method: "POST",
1219
+ handler: async ({ req }) => handleCreateGuardianChallenge(req),
1220
+ },
1221
+ {
1222
+ endpoint: "integrations/guardian/status",
1223
+ method: "GET",
1224
+ handler: ({ url }) => handleGetGuardianStatus(url),
1225
+ },
1226
+ {
1227
+ endpoint: "integrations/guardian/revoke",
1228
+ method: "POST",
1229
+ handler: async ({ req }) => handleRevokeGuardian(req),
1230
+ },
1231
+ {
1232
+ endpoint: "integrations/guardian/outbound/start",
1233
+ method: "POST",
1234
+ handler: async ({ req }) => handleStartOutbound(req),
1235
+ },
1236
+ {
1237
+ endpoint: "integrations/guardian/outbound/resend",
1238
+ method: "POST",
1239
+ handler: async ({ req }) => handleResendOutbound(req),
1240
+ },
1241
+ {
1242
+ endpoint: "integrations/guardian/outbound/cancel",
1243
+ method: "POST",
1244
+ handler: async ({ req }) => handleCancelOutbound(req),
1245
+ },
1244
1246
 
1245
- if (endpoint === "channels/conversation" && req.method === "DELETE")
1246
- return await handleDeleteConversation(req, assistantId);
1247
+ // ------------------------------------------------------------------
1248
+ // Integrations Twilio
1249
+ // ------------------------------------------------------------------
1250
+ {
1251
+ endpoint: "integrations/twilio/config",
1252
+ method: "GET",
1253
+ handler: () => handleGetTwilioConfig(),
1254
+ },
1255
+ {
1256
+ endpoint: "integrations/twilio/credentials",
1257
+ method: "POST",
1258
+ handler: async ({ req }) => handleSetTwilioCredentials(req),
1259
+ },
1260
+ {
1261
+ endpoint: "integrations/twilio/credentials",
1262
+ method: "DELETE",
1263
+ handler: () => handleClearTwilioCredentials(),
1264
+ },
1265
+ {
1266
+ endpoint: "integrations/twilio/numbers",
1267
+ method: "GET",
1268
+ handler: async () => handleListTwilioNumbers(),
1269
+ },
1270
+ {
1271
+ endpoint: "integrations/twilio/numbers/provision",
1272
+ method: "POST",
1273
+ handler: async ({ req }) => handleProvisionTwilioNumber(req),
1274
+ },
1275
+ {
1276
+ endpoint: "integrations/twilio/numbers/assign",
1277
+ method: "POST",
1278
+ handler: async ({ req }) => handleAssignTwilioNumber(req),
1279
+ },
1280
+ {
1281
+ endpoint: "integrations/twilio/numbers/release",
1282
+ method: "POST",
1283
+ handler: async ({ req }) => handleReleaseTwilioNumber(req),
1284
+ },
1285
+ {
1286
+ endpoint: "integrations/twilio/sms/compliance",
1287
+ method: "GET",
1288
+ handler: async () => handleGetSmsCompliance(),
1289
+ },
1290
+ {
1291
+ endpoint: "integrations/twilio/sms/compliance/tollfree",
1292
+ method: "POST",
1293
+ handler: async ({ req }) => handleSubmitTollfreeVerification(req),
1294
+ },
1295
+ {
1296
+ endpoint: "integrations/twilio/sms/compliance/tollfree/:sid",
1297
+ method: "PATCH",
1298
+ policyKey: "integrations/twilio/sms/compliance/tollfree",
1299
+ handler: async ({ req, params }) =>
1300
+ handleUpdateTollfreeVerification(req, params.sid),
1301
+ },
1302
+ {
1303
+ endpoint: "integrations/twilio/sms/compliance/tollfree/:sid",
1304
+ method: "DELETE",
1305
+ policyKey: "integrations/twilio/sms/compliance/tollfree",
1306
+ handler: async ({ params }) =>
1307
+ handleDeleteTollfreeVerification(params.sid),
1308
+ },
1309
+ {
1310
+ endpoint: "integrations/twilio/sms/test",
1311
+ method: "POST",
1312
+ handler: async ({ req }) => handleSmsSendTest(req),
1313
+ },
1314
+ {
1315
+ endpoint: "integrations/twilio/sms/doctor",
1316
+ method: "POST",
1317
+ handler: async () => handleSmsDoctor(),
1318
+ },
1247
1319
 
1248
- if (endpoint === 'channels/inbound' && req.method === 'POST') {
1249
- // Route policy enforces svc_gateway principal type.
1250
- return await handleChannelInbound(req, this.processMessage, assistantId, this.approvalCopyGenerator, this.approvalConversationGenerator, this.guardianActionCopyGenerator, this.guardianFollowUpConversationGenerator);
1251
- }
1320
+ // ------------------------------------------------------------------
1321
+ // Channel readiness
1322
+ // ------------------------------------------------------------------
1323
+ {
1324
+ endpoint: "channels/readiness",
1325
+ method: "GET",
1326
+ handler: async ({ url }) => handleGetChannelReadiness(url),
1327
+ },
1328
+ {
1329
+ endpoint: "channels/readiness/refresh",
1330
+ method: "POST",
1331
+ handler: async ({ req }) => handleRefreshChannelReadiness(req),
1332
+ },
1252
1333
 
1253
- if (endpoint === "channels/delivery-ack" && req.method === "POST")
1254
- return await handleChannelDeliveryAck(req);
1255
- if (endpoint === "channels/dead-letters" && req.method === "GET")
1256
- return handleListDeadLetters();
1257
- if (endpoint === "channels/replay" && req.method === "POST")
1258
- return await handleReplayDeadLetters(req);
1334
+ // ------------------------------------------------------------------
1335
+ // Attachments — specific sub-resource routes before generic ones
1336
+ // ------------------------------------------------------------------
1337
+ {
1338
+ endpoint: "attachments",
1339
+ method: "POST",
1340
+ handler: async ({ req }) => handleUploadAttachment(req),
1341
+ },
1342
+ {
1343
+ endpoint: "attachments",
1344
+ method: "DELETE",
1345
+ handler: async ({ req }) => handleDeleteAttachment(req),
1346
+ },
1347
+ {
1348
+ endpoint: "attachments/:id/content",
1349
+ method: "GET",
1350
+ policyKey: "attachments/content",
1351
+ handler: ({ req, params }) =>
1352
+ handleGetAttachmentContent(params.id, req),
1353
+ },
1354
+ {
1355
+ endpoint: "attachments/:id",
1356
+ method: "GET",
1357
+ policyKey: "attachments",
1358
+ handler: ({ params }) => handleGetAttachment(params.id),
1359
+ },
1259
1360
 
1260
- if (endpoint === "calls/start" && req.method === "POST")
1261
- return await handleStartCall(req, assistantId);
1361
+ // ------------------------------------------------------------------
1362
+ // Suggestion
1363
+ // ------------------------------------------------------------------
1364
+ {
1365
+ endpoint: "suggestion",
1366
+ method: "GET",
1367
+ handler: async ({ url }) =>
1368
+ handleGetSuggestion(url, {
1369
+ suggestionCache: this.suggestionCache,
1370
+ suggestionInFlight: this.suggestionInFlight,
1371
+ }),
1372
+ },
1262
1373
 
1263
- const callsMatch = endpoint.match(
1264
- /^calls\/([^/]+?)(\/cancel|\/answer|\/instruction)?$/,
1265
- );
1266
- if (callsMatch) {
1267
- const callSessionId = callsMatch[1];
1268
- if (
1269
- callSessionId !== "twilio" &&
1270
- callSessionId !== "relay" &&
1271
- callSessionId !== "start"
1272
- ) {
1273
- if (callsMatch[2] === "/cancel" && req.method === "POST")
1274
- return await handleCancelCall(req, callSessionId);
1275
- if (callsMatch[2] === "/answer" && req.method === "POST")
1276
- return await handleAnswerCall(req, callSessionId);
1277
- if (callsMatch[2] === "/instruction" && req.method === "POST")
1278
- return await handleInstructionCall(req, callSessionId);
1279
- if (!callsMatch[2] && req.method === "GET")
1280
- return handleGetCallStatus(callSessionId);
1281
- }
1282
- }
1374
+ // ------------------------------------------------------------------
1375
+ // Interfaces
1376
+ // ------------------------------------------------------------------
1377
+ {
1378
+ endpoint: "interfaces/:path*",
1379
+ method: "GET",
1380
+ policyKey: "interfaces",
1381
+ handler: ({ params }) => this.handleGetInterface(params.path),
1382
+ },
1283
1383
 
1284
- // Internal Twilio forwarding endpoints (gateway -> runtime).
1285
- // Route policy enforces svc_gateway principal type.
1286
- if (endpoint === 'internal/twilio/voice-webhook' && req.method === 'POST') {
1287
- const json = await req.json() as { params: Record<string, string>; originalUrl?: string };
1288
- const formBody = new URLSearchParams(json.params).toString();
1289
- const reconstructedUrl = json.originalUrl ?? req.url;
1290
- const fakeReq = new Request(reconstructedUrl, {
1291
- method: "POST",
1292
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1293
- body: formBody,
1294
- });
1295
- return await handleVoiceWebhook(fakeReq);
1296
- }
1384
+ // ------------------------------------------------------------------
1385
+ // Channel operations
1386
+ // ------------------------------------------------------------------
1387
+ {
1388
+ endpoint: "channels/conversation",
1389
+ method: "DELETE",
1390
+ handler: async ({ req }) => handleDeleteConversation(req, assistantId),
1391
+ },
1392
+ {
1393
+ endpoint: "channels/inbound",
1394
+ method: "POST",
1395
+ handler: async ({ req }) =>
1396
+ handleChannelInbound(
1397
+ req,
1398
+ this.processMessage,
1399
+ assistantId,
1400
+ this.approvalCopyGenerator,
1401
+ this.approvalConversationGenerator,
1402
+ this.guardianActionCopyGenerator,
1403
+ this.guardianFollowUpConversationGenerator,
1404
+ ),
1405
+ },
1406
+ {
1407
+ endpoint: "channels/delivery-ack",
1408
+ method: "POST",
1409
+ handler: async ({ req }) => handleChannelDeliveryAck(req),
1410
+ },
1411
+ {
1412
+ endpoint: "channels/dead-letters",
1413
+ method: "GET",
1414
+ handler: () => handleListDeadLetters(),
1415
+ },
1416
+ {
1417
+ endpoint: "channels/replay",
1418
+ method: "POST",
1419
+ handler: async ({ req }) => handleReplayDeadLetters(req),
1420
+ },
1297
1421
 
1298
- if (endpoint === 'internal/twilio/status' && req.method === 'POST') {
1299
- const json = await req.json() as { params: Record<string, string> };
1300
- const formBody = new URLSearchParams(json.params).toString();
1301
- const fakeReq = new Request(req.url, {
1302
- method: "POST",
1303
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1304
- body: formBody,
1305
- });
1306
- return await handleStatusCallback(fakeReq);
1307
- }
1422
+ // ------------------------------------------------------------------
1423
+ // Calls specific sub-actions before the generic calls/:id route
1424
+ // ------------------------------------------------------------------
1425
+ {
1426
+ endpoint: "calls/start",
1427
+ method: "POST",
1428
+ handler: async ({ req }) => handleStartCall(req, assistantId),
1429
+ },
1430
+ {
1431
+ endpoint: "calls/:id/cancel",
1432
+ method: "POST",
1433
+ policyKey: "calls/cancel",
1434
+ handler: async ({ req, params }) => handleCancelCall(req, params.id),
1435
+ },
1436
+ {
1437
+ endpoint: "calls/:id/answer",
1438
+ method: "POST",
1439
+ policyKey: "calls/answer",
1440
+ handler: async ({ req, params }) => handleAnswerCall(req, params.id),
1441
+ },
1442
+ {
1443
+ endpoint: "calls/:id/instruction",
1444
+ method: "POST",
1445
+ policyKey: "calls/instruction",
1446
+ handler: async ({ req, params }) =>
1447
+ handleInstructionCall(req, params.id),
1448
+ },
1449
+ {
1450
+ endpoint: "calls/:id",
1451
+ method: "GET",
1452
+ policyKey: "calls",
1453
+ handler: ({ params }) => handleGetCallStatus(params.id),
1454
+ },
1308
1455
 
1309
- if (endpoint === 'internal/twilio/connect-action' && req.method === 'POST') {
1310
- const json = await req.json() as { params: Record<string, string> };
1311
- const formBody = new URLSearchParams(json.params).toString();
1312
- const fakeReq = new Request(req.url, {
1313
- method: "POST",
1314
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1315
- body: formBody,
1316
- });
1317
- return await handleConnectAction(fakeReq);
1318
- }
1456
+ // ------------------------------------------------------------------
1457
+ // Internal Twilio forwarding (gateway -> runtime)
1458
+ // ------------------------------------------------------------------
1459
+ {
1460
+ endpoint: "internal/twilio/voice-webhook",
1461
+ method: "POST",
1462
+ handler: async ({ req }) => {
1463
+ const json = (await req.json()) as {
1464
+ params: Record<string, string>;
1465
+ originalUrl?: string;
1466
+ };
1467
+ const formBody = new URLSearchParams(json.params).toString();
1468
+ const reconstructedUrl = json.originalUrl ?? req.url;
1469
+ const fakeReq = new Request(reconstructedUrl, {
1470
+ method: "POST",
1471
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1472
+ body: formBody,
1473
+ });
1474
+ return handleVoiceWebhook(fakeReq);
1475
+ },
1476
+ },
1477
+ {
1478
+ endpoint: "internal/twilio/status",
1479
+ method: "POST",
1480
+ handler: async ({ req }) => {
1481
+ const json = (await req.json()) as {
1482
+ params: Record<string, string>;
1483
+ };
1484
+ const formBody = new URLSearchParams(json.params).toString();
1485
+ const fakeReq = new Request(req.url, {
1486
+ method: "POST",
1487
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1488
+ body: formBody,
1489
+ });
1490
+ return handleStatusCallback(fakeReq);
1491
+ },
1492
+ },
1493
+ {
1494
+ endpoint: "internal/twilio/connect-action",
1495
+ method: "POST",
1496
+ handler: async ({ req }) => {
1497
+ const json = (await req.json()) as {
1498
+ params: Record<string, string>;
1499
+ };
1500
+ const formBody = new URLSearchParams(json.params).toString();
1501
+ const fakeReq = new Request(req.url, {
1502
+ method: "POST",
1503
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1504
+ body: formBody,
1505
+ });
1506
+ return handleConnectAction(fakeReq);
1507
+ },
1508
+ },
1319
1509
 
1320
- if (endpoint === 'identity' && req.method === 'GET') return handleGetIdentity();
1321
- if (endpoint === 'brain-graph' && req.method === 'GET') return handleGetBrainGraph();
1322
- if (endpoint === 'brain-graph-ui' && req.method === 'GET') return handleServeBrainGraphUI(mintUiPageToken());
1323
- if (endpoint === 'home-base-ui' && req.method === 'GET') return handleServeHomeBaseUI(mintUiPageToken());
1324
- if (endpoint === 'events' && req.method === 'GET') return handleSubscribeAssistantEvents(req, url, { authContext });
1325
-
1326
- // Internal OAuth callback endpoint (gateway -> runtime)
1327
- if (endpoint === 'internal/oauth/callback' && req.method === 'POST') {
1328
- const json = await req.json() as { state: string; code?: string; error?: string };
1329
- if (!json.state) return httpError('BAD_REQUEST', 'Missing state parameter', 400);
1330
- if (json.error) {
1331
- const consumed = consumeCallbackError(json.state, json.error);
1332
- return consumed
1333
- ? Response.json({ ok: true })
1334
- : httpError("NOT_FOUND", "Unknown state", 404);
1335
- }
1336
- if (json.code) {
1337
- const consumed = consumeCallback(json.state, json.code);
1338
- return consumed
1339
- ? Response.json({ ok: true })
1340
- : httpError("NOT_FOUND", "Unknown state", 404);
1341
- }
1342
- return httpError("BAD_REQUEST", "Missing code or error parameter", 400);
1343
- }
1510
+ // ------------------------------------------------------------------
1511
+ // Identity / brain graph / UIs / events
1512
+ // ------------------------------------------------------------------
1513
+ {
1514
+ endpoint: "identity",
1515
+ method: "GET",
1516
+ handler: () => handleGetIdentity(),
1517
+ },
1518
+ {
1519
+ endpoint: "brain-graph",
1520
+ method: "GET",
1521
+ handler: () => handleGetBrainGraph(),
1522
+ },
1523
+ {
1524
+ endpoint: "brain-graph-ui",
1525
+ method: "GET",
1526
+ handler: () => handleServeBrainGraphUI(mintUiPageToken()),
1527
+ },
1528
+ {
1529
+ endpoint: "home-base-ui",
1530
+ method: "GET",
1531
+ handler: () => handleServeHomeBaseUI(mintUiPageToken()),
1532
+ },
1533
+ {
1534
+ endpoint: "events",
1535
+ method: "GET",
1536
+ handler: ({ req, url, authContext }) =>
1537
+ handleSubscribeAssistantEvents(req, url, { authContext }),
1538
+ },
1344
1539
 
1345
- return httpError("NOT_FOUND", "Not found", 404);
1346
- });
1347
- }
1540
+ // ------------------------------------------------------------------
1541
+ // Migrations
1542
+ // ------------------------------------------------------------------
1543
+ {
1544
+ endpoint: "migrations/validate",
1545
+ method: "POST",
1546
+ handler: async ({ req }) => handleMigrationValidate(req),
1547
+ },
1548
+ {
1549
+ endpoint: "migrations/export",
1550
+ method: "POST",
1551
+ handler: async ({ req }) => handleMigrationExport(req),
1552
+ },
1553
+ {
1554
+ endpoint: "migrations/import-preflight",
1555
+ method: "POST",
1556
+ handler: async ({ req }) => handleMigrationImportPreflight(req),
1557
+ },
1558
+ {
1559
+ endpoint: "migrations/import",
1560
+ method: "POST",
1561
+ handler: async ({ req }) => handleMigrationImport(req),
1562
+ },
1348
1563
 
1349
- private handleGetInterface(interfacePath: string): Response {
1350
- if (!this.interfacesDir) {
1351
- return httpError("NOT_FOUND", "Interface not found", 404);
1352
- }
1353
- const fullPath = resolve(this.interfacesDir, interfacePath);
1354
- if (
1355
- (fullPath !== this.interfacesDir &&
1356
- !fullPath.startsWith(this.interfacesDir + "/")) ||
1357
- !existsSync(fullPath)
1358
- ) {
1359
- return httpError("NOT_FOUND", "Interface not found", 404);
1360
- }
1361
- const source = readFileSync(fullPath, "utf-8");
1362
- return new Response(source, {
1363
- headers: { "Content-Type": "text/plain; charset=utf-8" },
1364
- });
1564
+ // ------------------------------------------------------------------
1565
+ // Internal OAuth callback (gateway -> runtime)
1566
+ // ------------------------------------------------------------------
1567
+ {
1568
+ endpoint: "internal/oauth/callback",
1569
+ method: "POST",
1570
+ handler: async ({ req }) => {
1571
+ const json = (await req.json()) as {
1572
+ state: string;
1573
+ code?: string;
1574
+ error?: string;
1575
+ };
1576
+ if (!json.state)
1577
+ return httpError("BAD_REQUEST", "Missing state parameter", 400);
1578
+ if (json.error) {
1579
+ const consumed = consumeCallbackError(json.state, json.error);
1580
+ return consumed
1581
+ ? Response.json({ ok: true })
1582
+ : httpError("NOT_FOUND", "Unknown state", 404);
1583
+ }
1584
+ if (json.code) {
1585
+ const consumed = consumeCallback(json.state, json.code);
1586
+ return consumed
1587
+ ? Response.json({ ok: true })
1588
+ : httpError("NOT_FOUND", "Unknown state", 404);
1589
+ }
1590
+ return httpError(
1591
+ "BAD_REQUEST",
1592
+ "Missing code or error parameter",
1593
+ 400,
1594
+ );
1595
+ },
1596
+ },
1597
+ ];
1365
1598
  }
1366
1599
  }