@vellumai/assistant 0.7.1 → 0.7.2

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 (535) hide show
  1. package/ARCHITECTURE.md +32 -49
  2. package/Dockerfile +1 -0
  3. package/README.md +1 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
  5. package/bun.lock +26 -26
  6. package/docs/architecture/security.md +20 -0
  7. package/docs/plugins.md +7 -9
  8. package/knip.json +1 -0
  9. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +39 -1
  11. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  12. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  13. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  15. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  16. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  17. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +9 -0
  19. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  20. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  21. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  22. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  23. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  24. package/openapi.yaml +565 -12
  25. package/package.json +6 -3
  26. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  27. package/src/__tests__/app-bundler.test.ts +170 -1
  28. package/src/__tests__/app-control-flow.test.ts +374 -0
  29. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  30. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  31. package/src/__tests__/app-executors.test.ts +30 -43
  32. package/src/__tests__/approval-routes-http.test.ts +23 -6
  33. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  34. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  35. package/src/__tests__/assistant-event-hub.test.ts +109 -2
  36. package/src/__tests__/assistant-event.test.ts +10 -0
  37. package/src/__tests__/assistant-events-sse-hardening.test.ts +7 -2
  38. package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -7
  39. package/src/__tests__/background-shell-host-bash.test.ts +14 -15
  40. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  41. package/src/__tests__/btw-routes.test.ts +13 -4
  42. package/src/__tests__/call-controller.test.ts +49 -1
  43. package/src/__tests__/call-domain.test.ts +0 -2
  44. package/src/__tests__/call-routes-http.test.ts +0 -2
  45. package/src/__tests__/channel-readiness-service.test.ts +59 -1
  46. package/src/__tests__/checker.test.ts +3 -4
  47. package/src/__tests__/config-loader-backfill.test.ts +90 -155
  48. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  49. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  50. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  51. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
  52. package/src/__tests__/config-watcher.test.ts +2 -2
  53. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  54. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  55. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  56. package/src/__tests__/conversation-lifecycle.test.ts +36 -0
  57. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  58. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
  59. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
  60. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  61. package/src/__tests__/conversation-slash-commands.test.ts +0 -4
  62. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  63. package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -0
  64. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  65. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  66. package/src/__tests__/credentials-cli.test.ts +5 -12
  67. package/src/__tests__/cu-unified-flow.test.ts +185 -23
  68. package/src/__tests__/daemon-credential-client.test.ts +101 -19
  69. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  70. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  71. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  72. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  73. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
  74. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
  75. package/src/__tests__/heartbeat-service.test.ts +718 -1
  76. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  77. package/src/__tests__/host-app-control-proxy.test.ts +602 -0
  78. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  79. package/src/__tests__/host-bash-proxy.test.ts +246 -47
  80. package/src/__tests__/host-bash-routes.test.ts +294 -0
  81. package/src/__tests__/host-browser-proxy.test.ts +24 -22
  82. package/src/__tests__/host-browser-routes.test.ts +39 -13
  83. package/src/__tests__/host-cu-proxy.test.ts +41 -52
  84. package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
  85. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  86. package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
  87. package/src/__tests__/host-file-proxy.test.ts +37 -43
  88. package/src/__tests__/host-file-read-tool.test.ts +17 -0
  89. package/src/__tests__/host-file-routes-targeted.test.ts +262 -0
  90. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  91. package/src/__tests__/host-proxy-base.test.ts +312 -0
  92. package/src/__tests__/host-shell-tool.test.ts +22 -4
  93. package/src/__tests__/host-transfer-proxy-targeted.test.ts +583 -0
  94. package/src/__tests__/host-transfer-proxy.test.ts +121 -22
  95. package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
  96. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  97. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  98. package/src/__tests__/identity-routes.test.ts +103 -1
  99. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  100. package/src/__tests__/inline-command-runner.test.ts +0 -1
  101. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
  102. package/src/__tests__/integration-status.test.ts +85 -5
  103. package/src/__tests__/intent-routing.test.ts +0 -1
  104. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  105. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  106. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
  107. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  108. package/src/__tests__/mcp-cli.test.ts +338 -2
  109. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  110. package/src/__tests__/migration-import-commit-http.test.ts +108 -2
  111. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  112. package/src/__tests__/oauth-cli.test.ts +0 -2
  113. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  114. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  115. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
  116. package/src/__tests__/prechat-onboarding-contract.test.ts +3 -1
  117. package/src/__tests__/process-message-background-slack.test.ts +2 -0
  118. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  119. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  120. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  121. package/src/__tests__/retry-backoff.test.ts +87 -0
  122. package/src/__tests__/runtime-events-sse.test.ts +10 -6
  123. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  124. package/src/__tests__/schedule-retry.test.ts +715 -0
  125. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  126. package/src/__tests__/secret-ingress-http.test.ts +1 -0
  127. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  128. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
  129. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  130. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  131. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  132. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  133. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  134. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
  135. package/src/__tests__/slack-channel-config.test.ts +9 -14
  136. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  137. package/src/__tests__/system-prompt.test.ts +0 -1
  138. package/src/__tests__/telegram-config.test.ts +0 -1
  139. package/src/__tests__/test-preload.ts +8 -0
  140. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  141. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  142. package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
  143. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  144. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  145. package/src/__tests__/tool-executor.test.ts +0 -1
  146. package/src/__tests__/twilio-config.test.ts +3 -16
  147. package/src/__tests__/twilio-routes.test.ts +3 -5
  148. package/src/__tests__/twilio-validation.test.ts +93 -0
  149. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
  150. package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
  151. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  152. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  153. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  154. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  155. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  156. package/src/backup/__tests__/paths.test.ts +0 -22
  157. package/src/backup/__tests__/restore.test.ts +51 -151
  158. package/src/backup/paths.ts +2 -18
  159. package/src/backup/restore.ts +107 -231
  160. package/src/bundler/app-bundler.ts +51 -3
  161. package/src/calls/relay-server.ts +4 -44
  162. package/src/calls/twilio-config.ts +2 -17
  163. package/src/calls/twilio-rest.ts +33 -105
  164. package/src/calls/twilio-routes.ts +11 -12
  165. package/src/channels/types.ts +8 -7
  166. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  167. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  168. package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
  169. package/src/cli/commands/__tests__/webhooks.test.ts +0 -1
  170. package/src/cli/commands/backup.ts +6 -331
  171. package/src/cli/commands/clients.ts +36 -37
  172. package/src/cli/commands/contacts.ts +73 -0
  173. package/src/cli/commands/conversations.ts +2 -5
  174. package/src/cli/commands/credentials.ts +15 -7
  175. package/src/cli/commands/domain.ts +66 -15
  176. package/src/cli/commands/gateway.ts +183 -0
  177. package/src/cli/commands/keys.ts +9 -6
  178. package/src/cli/commands/mcp.ts +116 -156
  179. package/src/cli/commands/memory-v2.ts +296 -1
  180. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
  181. package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
  182. package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
  183. package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
  184. package/src/cli/commands/platform/disconnect.ts +5 -4
  185. package/src/cli/commands/platform/index.ts +0 -18
  186. package/src/cli/lib/daemon-credential-client.ts +110 -28
  187. package/src/cli/program.ts +2 -0
  188. package/src/config/assistant-feature-flags.ts +67 -10
  189. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  190. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  191. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  192. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  193. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  194. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  195. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  196. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  197. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  198. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  199. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  200. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  201. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  202. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  203. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  204. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  205. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  206. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  207. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  208. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  209. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  210. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  211. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  212. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  213. package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
  214. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  215. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
  216. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  217. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  218. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  219. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  220. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  221. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  222. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  223. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  224. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  225. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  226. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  227. package/src/config/bundled-tool-registry.ts +21 -0
  228. package/src/config/env-registry.ts +0 -2
  229. package/src/config/env.ts +19 -12
  230. package/src/config/feature-flag-registry.json +21 -133
  231. package/src/config/loader.ts +73 -99
  232. package/src/config/sanitize-for-transfer.ts +2 -0
  233. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  234. package/src/config/schemas/__tests__/memory-v2.test.ts +7 -4
  235. package/src/config/schemas/calls.ts +0 -9
  236. package/src/config/schemas/heartbeat.ts +63 -0
  237. package/src/config/schemas/ingress.ts +10 -6
  238. package/src/config/schemas/llm.ts +5 -10
  239. package/src/config/schemas/memory-lifecycle.ts +77 -24
  240. package/src/config/schemas/memory-v2.ts +48 -4
  241. package/src/config/schemas/platform.ts +6 -0
  242. package/src/config/schemas/services.ts +1 -15
  243. package/src/config/schemas/skills.ts +0 -6
  244. package/src/config/seed-inference-profiles.ts +1 -1
  245. package/src/contacts/contact-store.ts +0 -30
  246. package/src/contacts/contacts-write.ts +0 -27
  247. package/src/context/window-manager.ts +1 -2
  248. package/src/credential-execution/feature-gates.ts +10 -10
  249. package/src/credential-execution/process-manager.ts +12 -41
  250. package/src/daemon/__tests__/conversation-tool-setup.test.ts +126 -5
  251. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  252. package/src/daemon/config-watcher.ts +4 -3
  253. package/src/daemon/conversation-agent-loop-handlers.ts +21 -3
  254. package/src/daemon/conversation-agent-loop.ts +32 -28
  255. package/src/daemon/conversation-lifecycle.ts +8 -1
  256. package/src/daemon/conversation-process.ts +16 -11
  257. package/src/daemon/conversation-runtime-assembly.ts +2 -2
  258. package/src/daemon/conversation-surfaces.ts +125 -4
  259. package/src/daemon/conversation-tool-setup.ts +16 -55
  260. package/src/daemon/conversation.ts +21 -2
  261. package/src/daemon/doordash-steps.ts +1 -1
  262. package/src/daemon/handlers/shared.ts +4 -1
  263. package/src/daemon/host-app-control-proxy.ts +293 -0
  264. package/src/daemon/host-bash-proxy.ts +84 -74
  265. package/src/daemon/host-browser-proxy.ts +67 -82
  266. package/src/daemon/host-cu-proxy.ts +81 -86
  267. package/src/daemon/host-file-proxy.ts +93 -69
  268. package/src/daemon/host-proxy-base.ts +294 -0
  269. package/src/daemon/host-proxy-preactivation.ts +82 -0
  270. package/src/daemon/host-transfer-proxy.ts +247 -129
  271. package/src/daemon/lifecycle.ts +115 -117
  272. package/src/daemon/message-protocol.ts +3 -8
  273. package/src/daemon/message-types/contacts.ts +23 -1
  274. package/src/daemon/message-types/conversations.ts +11 -8
  275. package/src/daemon/message-types/host-app-control.ts +150 -0
  276. package/src/daemon/message-types/host-bash.ts +4 -0
  277. package/src/daemon/message-types/host-cu.ts +2 -0
  278. package/src/daemon/message-types/host-file.ts +4 -0
  279. package/src/daemon/message-types/host-transfer.ts +3 -0
  280. package/src/daemon/message-types/schedules.ts +8 -3
  281. package/src/daemon/message-types/skills.ts +2 -2
  282. package/src/daemon/process-message.ts +18 -1
  283. package/src/daemon/shutdown-handlers.ts +0 -3
  284. package/src/daemon/tool-setup-types.ts +51 -0
  285. package/src/daemon/tool-side-effects.ts +1 -1
  286. package/src/events/tool-audit-listener.ts +2 -1
  287. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +15 -7
  288. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
  289. package/src/heartbeat/heartbeat-run-store.ts +236 -0
  290. package/src/heartbeat/heartbeat-service.ts +280 -49
  291. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  292. package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
  293. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  294. package/src/home/post-connect-feed.ts +68 -0
  295. package/src/home/relationship-state-writer.ts +17 -92
  296. package/src/home/suggested-prompts.ts +46 -10
  297. package/src/inbound/public-ingress-urls.ts +32 -34
  298. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  299. package/src/ipc/assistant-server.ts +14 -1
  300. package/src/ipc/cli-client.ts +32 -1
  301. package/src/live-voice/live-voice-metrics.ts +10 -10
  302. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  303. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  304. package/src/mcp/mcp-auth-state.ts +133 -0
  305. package/src/mcp/mcp-oauth-provider.ts +19 -0
  306. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  307. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  308. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  309. package/src/memory/anisotropy.test.ts +247 -0
  310. package/src/memory/anisotropy.ts +443 -0
  311. package/src/memory/auto-analysis-constants.ts +17 -0
  312. package/src/memory/auto-analysis-guard.ts +5 -15
  313. package/src/memory/canonical-guardian-store.ts +7 -7
  314. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  315. package/src/memory/context-search/agent-protocol.ts +6 -6
  316. package/src/memory/context-search/agent-runner.ts +32 -7
  317. package/src/memory/context-search/sources/memory-v2.ts +17 -5
  318. package/src/memory/conversation-crud.ts +1 -1
  319. package/src/memory/conversation-key-store.ts +2 -15
  320. package/src/memory/db-init.ts +4 -0
  321. package/src/memory/embedding-backend.ts +9 -21
  322. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -4
  323. package/src/memory/graph/conversation-graph-memory.ts +1 -24
  324. package/src/memory/graph/graph-search.ts +8 -0
  325. package/src/memory/graph/retriever.ts +28 -0
  326. package/src/memory/graph/tools.ts +1 -1
  327. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  328. package/src/memory/jobs/embed-concept-page.ts +28 -2
  329. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  330. package/src/memory/jobs-store.ts +66 -22
  331. package/src/memory/jobs-worker.ts +112 -63
  332. package/src/memory/memory-v2-activation-log-store.ts +1 -1
  333. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  334. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  335. package/src/memory/migrations/index.ts +5 -0
  336. package/src/memory/migrations/registry.ts +8 -0
  337. package/src/memory/pkb/pkb-search.ts +7 -0
  338. package/src/memory/qdrant-client.ts +50 -20
  339. package/src/memory/schema/infrastructure.ts +15 -0
  340. package/src/memory/search/semantic.ts +7 -0
  341. package/src/memory/sparse-tokenize.ts +49 -0
  342. package/src/memory/v2/__tests__/activation.test.ts +77 -95
  343. package/src/memory/v2/__tests__/injection.test.ts +43 -21
  344. package/src/memory/v2/__tests__/sim.test.ts +166 -6
  345. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  346. package/src/memory/v2/__tests__/static-context.test.ts +0 -1
  347. package/src/memory/v2/activation.ts +69 -88
  348. package/src/memory/v2/consolidation-job.ts +3 -5
  349. package/src/memory/v2/constants.ts +7 -0
  350. package/src/memory/v2/injection.ts +86 -53
  351. package/src/memory/v2/prompts/consolidation.ts +312 -91
  352. package/src/memory/v2/qdrant.ts +99 -1
  353. package/src/memory/v2/sim.ts +126 -16
  354. package/src/memory/v2/skill-qdrant.ts +12 -3
  355. package/src/memory/v2/skill-store.ts +16 -1
  356. package/src/memory/v2/sparse-bm25.ts +245 -0
  357. package/src/memory/v2/static-context.ts +6 -5
  358. package/src/messaging/providers/gmail/types.ts +0 -49
  359. package/src/messaging/providers/slack/adapter.ts +1 -31
  360. package/src/messaging/providers/slack/types.ts +0 -32
  361. package/src/notifications/README.md +10 -10
  362. package/src/notifications/broadcaster.ts +1 -1
  363. package/src/notifications/guardian-question-mode.ts +5 -5
  364. package/src/oauth/connect-orchestrator.ts +4 -0
  365. package/src/oauth/credential-token-resolver.ts +1 -3
  366. package/src/oauth/manual-token-connection.ts +0 -4
  367. package/src/outbound-proxy/index.ts +1 -37
  368. package/src/outbound-proxy/logging.ts +1 -1
  369. package/src/outbound-proxy/policy.ts +6 -5
  370. package/src/outbound-proxy/router.ts +2 -1
  371. package/src/permissions/approval-policy.test.ts +6 -275
  372. package/src/permissions/approval-policy.ts +0 -51
  373. package/src/permissions/checker.test.ts +0 -1
  374. package/src/permissions/checker.ts +3 -17
  375. package/src/permissions/gateway-threshold-reader.ts +2 -0
  376. package/src/permissions/prompter.ts +34 -1
  377. package/src/permissions/secret-prompter.ts +6 -2
  378. package/src/prompts/bootstrap-cleanup.ts +27 -0
  379. package/src/prompts/system-prompt.ts +3 -18
  380. package/src/prompts/templates/SOUL.md +13 -1
  381. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  382. package/src/runtime/assistant-event-hub.ts +118 -96
  383. package/src/runtime/assistant-event.ts +1 -0
  384. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  385. package/src/runtime/auth/middleware.ts +0 -96
  386. package/src/runtime/auth/route-policy.ts +19 -0
  387. package/src/runtime/btw-sidechain.ts +2 -3
  388. package/src/runtime/channel-invite-transport.ts +2 -48
  389. package/src/runtime/channel-invite-transports/email.ts +1 -1
  390. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  391. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  392. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  393. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  394. package/src/runtime/channel-invite-types.ts +54 -0
  395. package/src/runtime/channel-readiness-service.ts +32 -13
  396. package/src/runtime/http-server.ts +3 -329
  397. package/src/runtime/http-types.ts +0 -5
  398. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  399. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  400. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  401. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
  402. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  403. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  404. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  405. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  406. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  407. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
  408. package/src/runtime/migrations/migration-transport.ts +7 -7
  409. package/src/runtime/migrations/vbundle-builder.ts +327 -60
  410. package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
  411. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  412. package/src/runtime/migrations/vbundle-importer.ts +245 -68
  413. package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
  414. package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
  415. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  416. package/src/runtime/migrations/vbundle-validator.ts +114 -0
  417. package/src/runtime/pending-interactions.ts +35 -9
  418. package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
  419. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
  420. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  421. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  422. package/src/runtime/routes/approval-interception-types.ts +13 -0
  423. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  424. package/src/runtime/routes/backup-routes.ts +15 -38
  425. package/src/runtime/routes/btw-routes.ts +14 -37
  426. package/src/runtime/routes/client-routes.ts +1 -0
  427. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  428. package/src/runtime/routes/conversation-query-routes.ts +36 -1
  429. package/src/runtime/routes/conversation-routes.ts +30 -13
  430. package/src/runtime/routes/document-pdf-renderer.ts +165 -0
  431. package/src/runtime/routes/documents-routes.ts +30 -0
  432. package/src/runtime/routes/errors.ts +19 -4
  433. package/src/runtime/routes/events-routes.ts +12 -6
  434. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  435. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  436. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  437. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  438. package/src/runtime/routes/host-bash-routes.ts +36 -6
  439. package/src/runtime/routes/host-browser-routes.ts +108 -13
  440. package/src/runtime/routes/host-cu-routes.ts +44 -14
  441. package/src/runtime/routes/host-file-routes.ts +33 -10
  442. package/src/runtime/routes/host-transfer-routes.ts +64 -24
  443. package/src/runtime/routes/http-adapter.ts +1 -0
  444. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  445. package/src/runtime/routes/identity-routes.ts +15 -43
  446. package/src/runtime/routes/inbound-message-handler.ts +1 -9
  447. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
  448. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  449. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  450. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  451. package/src/runtime/routes/index.ts +8 -0
  452. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  453. package/src/runtime/routes/memory-item-routes.ts +10 -12
  454. package/src/runtime/routes/memory-v2-routes.ts +441 -1
  455. package/src/runtime/routes/migration-routes.ts +96 -0
  456. package/src/runtime/routes/schedule-routes.ts +7 -0
  457. package/src/runtime/verification-templates.ts +4 -7
  458. package/src/schedule/integration-status.ts +66 -2
  459. package/src/schedule/recurrence-engine.ts +4 -1
  460. package/src/schedule/retry-backoff.ts +18 -0
  461. package/src/schedule/retry-policy.ts +82 -0
  462. package/src/schedule/schedule-recovery.ts +64 -0
  463. package/src/schedule/schedule-store.ts +106 -2
  464. package/src/schedule/scheduler-types.ts +25 -0
  465. package/src/schedule/scheduler.ts +63 -38
  466. package/src/security/oauth-callback-registry.ts +8 -0
  467. package/src/sequence/analytics.ts +5 -5
  468. package/src/sequence/engine.ts +1 -1
  469. package/src/skills/catalog-files.ts +2 -8
  470. package/src/skills/include-graph.ts +5 -5
  471. package/src/skills/remote-skill-policy.ts +5 -5
  472. package/src/skills/skill-file-provider.ts +1 -1
  473. package/src/skills/skill-file-types.ts +13 -0
  474. package/src/skills/skillssh-audit-types.ts +28 -0
  475. package/src/skills/skillssh-registry.ts +8 -21
  476. package/src/telemetry/types.ts +2 -0
  477. package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
  478. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  479. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  480. package/src/tools/apps/executors.ts +56 -69
  481. package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
  482. package/src/tools/browser/browser-execution.ts +2 -2
  483. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
  484. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  485. package/src/tools/browser/cdp-client/factory.ts +23 -24
  486. package/src/tools/browser/cdp-client/index.ts +1 -14
  487. package/src/tools/computer-use/definitions.ts +42 -20
  488. package/src/tools/executor.ts +2 -0
  489. package/src/tools/host-filesystem/edit.ts +26 -0
  490. package/src/tools/host-filesystem/read.ts +26 -0
  491. package/src/tools/host-filesystem/transfer.ts +31 -1
  492. package/src/tools/host-filesystem/write.ts +26 -0
  493. package/src/tools/host-terminal/host-shell.ts +58 -0
  494. package/src/tools/schedule/create.ts +6 -0
  495. package/src/tools/schedule/list.ts +2 -0
  496. package/src/tools/schedule/update.ts +10 -0
  497. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  498. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  499. package/src/tools/skills/load.ts +0 -32
  500. package/src/tools/tool-approval-handler.ts +1 -5
  501. package/src/tools/types.ts +4 -0
  502. package/src/usage/pricing.ts +1 -1
  503. package/src/workspace/hatched-date.ts +86 -0
  504. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  505. package/src/workspace/migrations/006-services-config.ts +8 -5
  506. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  507. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  508. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  509. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  510. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  511. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  512. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
  513. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  514. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
  515. package/src/workspace/migrations/AGENTS.md +1 -1
  516. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  517. package/src/workspace/migrations/utils.ts +21 -0
  518. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
  519. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
  520. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
  521. package/src/__tests__/twilio-rest.test.ts +0 -34
  522. package/src/backup/__tests__/backup-key.test.ts +0 -152
  523. package/src/backup/__tests__/backup-worker.test.ts +0 -782
  524. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  525. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  526. package/src/backup/backup-key.ts +0 -137
  527. package/src/backup/backup-worker.ts +0 -472
  528. package/src/backup/offsite-writer.ts +0 -222
  529. package/src/backup/stream-crypt.ts +0 -263
  530. package/src/daemon/message-types/pairing.ts +0 -58
  531. package/src/outbound-proxy/config.ts +0 -20
  532. package/src/outbound-proxy/health.ts +0 -18
  533. package/src/outbound-proxy/types.ts +0 -150
  534. package/src/runtime/capability-tokens.ts +0 -190
  535. package/src/signals/mcp-reload.ts +0 -18
@@ -1,263 +0,0 @@
1
- /**
2
- * Streaming AES-256-GCM file encryption/decryption for backup bundles.
3
- *
4
- * The on-disk format is:
5
- *
6
- * [12-byte IV][ciphertext...][16-byte GCM auth tag]
7
- *
8
- * Both encrypt and decrypt use Node streams so peak memory stays bounded
9
- * regardless of input size. This is important for backup archives which may
10
- * run to many gigabytes on larger workspaces.
11
- *
12
- * The key must be exactly 32 bytes (AES-256). The IV is randomly generated
13
- * per call, which is required for GCM semantic security — never reuse an
14
- * IV with the same key.
15
- */
16
-
17
- import {
18
- createCipheriv,
19
- createDecipheriv,
20
- randomBytes,
21
- } from "node:crypto";
22
- import {
23
- createReadStream,
24
- createWriteStream,
25
- } from "node:fs";
26
- import { open, rename, stat, unlink } from "node:fs/promises";
27
- import { Readable, Writable } from "node:stream";
28
- import { pipeline } from "node:stream/promises";
29
-
30
- // ---------------------------------------------------------------------------
31
- // Constants
32
- // ---------------------------------------------------------------------------
33
-
34
- /** Size of the AES-GCM initialization vector prefix, in bytes. */
35
- export const ENCRYPTED_HEADER_SIZE = 12;
36
-
37
- /** Size of the AES-GCM authentication tag suffix, in bytes. */
38
- export const GCM_TAG_SIZE = 16;
39
-
40
- const ALGORITHM = "aes-256-gcm";
41
- const KEY_LENGTH = 32;
42
-
43
- // ---------------------------------------------------------------------------
44
- // Helpers
45
- // ---------------------------------------------------------------------------
46
-
47
- function assertKey(key: Buffer): void {
48
- if (key.length !== KEY_LENGTH) {
49
- throw new Error("Backup encryption key must be 32 bytes");
50
- }
51
- }
52
-
53
- async function safeUnlink(path: string): Promise<void> {
54
- try {
55
- await unlink(path);
56
- } catch {
57
- // best-effort cleanup — swallow ENOENT and other errors
58
- }
59
- }
60
-
61
- function tempPath(outputPath: string): string {
62
- return `${outputPath}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
63
- }
64
-
65
- // ---------------------------------------------------------------------------
66
- // Encrypt
67
- // ---------------------------------------------------------------------------
68
-
69
- /**
70
- * Stream-encrypt `inputPath` to `outputPath` using AES-256-GCM.
71
- *
72
- * Produces `[IV (12 bytes)][ciphertext][auth tag (16 bytes)]` in the output.
73
- * Writes to a temp file and atomically renames on success; unlinks the temp
74
- * file on any error so failed writes don't leave partial bundles behind.
75
- */
76
- export async function encryptFile(
77
- inputPath: string,
78
- outputPath: string,
79
- key: Buffer,
80
- ): Promise<void> {
81
- assertKey(key);
82
-
83
- const iv = randomBytes(ENCRYPTED_HEADER_SIZE);
84
- const cipher = createCipheriv(ALGORITHM, key, iv);
85
-
86
- const tmp = tempPath(outputPath);
87
- const writeStream = createWriteStream(tmp);
88
-
89
- try {
90
- // Write IV first so decrypt can read it without knowing the ciphertext size.
91
- await new Promise<void>((resolve, reject) => {
92
- writeStream.write(iv, (err) => (err ? reject(err) : resolve()));
93
- });
94
-
95
- // Stream plaintext through the cipher into the output.
96
- const readStream = createReadStream(inputPath);
97
- await pipeline(readStream, cipher, writeStream, { end: false });
98
-
99
- // Append the auth tag after the ciphertext body.
100
- const tag = cipher.getAuthTag();
101
- await new Promise<void>((resolve, reject) => {
102
- writeStream.write(tag, (err) => (err ? reject(err) : resolve()));
103
- });
104
-
105
- await new Promise<void>((resolve, reject) => {
106
- writeStream.end((err?: Error | null) => (err ? reject(err) : resolve()));
107
- });
108
-
109
- await rename(tmp, outputPath);
110
- } catch (err) {
111
- // Make sure the write stream is closed before we try to unlink the temp file.
112
- writeStream.destroy();
113
- await safeUnlink(tmp);
114
- throw err;
115
- }
116
- }
117
-
118
- // ---------------------------------------------------------------------------
119
- // Decrypt
120
- // ---------------------------------------------------------------------------
121
-
122
- /**
123
- * Stream-decrypt `inputPath` to `outputPath`. Expects the on-disk format
124
- * produced by `encryptFile`: `[IV][ciphertext][auth tag]`.
125
- *
126
- * Reads the IV and auth tag via positional reads, then streams only the
127
- * ciphertext body through the decipher. Atomic tmp + rename semantics.
128
- */
129
- export async function decryptFile(
130
- inputPath: string,
131
- outputPath: string,
132
- key: Buffer,
133
- ): Promise<void> {
134
- assertKey(key);
135
-
136
- const info = await stat(inputPath);
137
- const totalSize = info.size;
138
- const minSize = ENCRYPTED_HEADER_SIZE + GCM_TAG_SIZE;
139
- if (totalSize < minSize) {
140
- throw new Error(
141
- `Encrypted file is too small: ${totalSize} bytes (need at least ${minSize})`,
142
- );
143
- }
144
-
145
- // Read IV (first 12 bytes) and auth tag (last 16 bytes) via positional reads.
146
- const iv = Buffer.alloc(ENCRYPTED_HEADER_SIZE);
147
- const tag = Buffer.alloc(GCM_TAG_SIZE);
148
- const fh = await open(inputPath, "r");
149
- try {
150
- await fh.read(iv, 0, ENCRYPTED_HEADER_SIZE, 0);
151
- await fh.read(tag, 0, GCM_TAG_SIZE, totalSize - GCM_TAG_SIZE);
152
- } finally {
153
- await fh.close();
154
- }
155
-
156
- const decipher = createDecipheriv(ALGORITHM, key, iv);
157
- decipher.setAuthTag(tag);
158
-
159
- const ciphertextStart = ENCRYPTED_HEADER_SIZE;
160
- const ciphertextEnd = totalSize - GCM_TAG_SIZE - 1; // createReadStream end is inclusive
161
- const hasCiphertext = ciphertextEnd >= ciphertextStart;
162
-
163
- const tmp = tempPath(outputPath);
164
- const writeStream = createWriteStream(tmp);
165
-
166
- try {
167
- const ciphertextStream = hasCiphertext
168
- ? createReadStream(inputPath, {
169
- start: ciphertextStart,
170
- end: ciphertextEnd,
171
- })
172
- : Readable.from([]);
173
-
174
- // pipeline consumes the ciphertext, pushes it through the decipher, and
175
- // calls decipher.final() at the end — which is where auth tag verification
176
- // happens. A bad tag surfaces here as a thrown error.
177
- await pipeline(ciphertextStream, decipher, writeStream);
178
-
179
- await rename(tmp, outputPath);
180
- } catch (err) {
181
- writeStream.destroy();
182
- await safeUnlink(tmp);
183
- throw err;
184
- }
185
- }
186
-
187
- // ---------------------------------------------------------------------------
188
- // Verify
189
- // ---------------------------------------------------------------------------
190
-
191
- /**
192
- * Verify that `path` is a valid AES-256-GCM encrypted bundle for `key`.
193
- *
194
- * Streams the ciphertext through the decipher into a null sink and relies on
195
- * `decipher.final()` to either succeed (tag matches) or throw (tamper / wrong
196
- * key). No scratch file is written, so a full or read-only tmpdir cannot
197
- * cause a healthy backup to be reported as invalid.
198
- *
199
- * Returns `true` if the bundle authenticates, `false` on a cryptographic
200
- * failure (bad auth tag, wrong key, truncated/short input). Filesystem errors
201
- * on the *source* file (ENOENT, EACCES, EIO, …) are rethrown so callers can
202
- * distinguish tamper from transient I/O.
203
- */
204
- export async function verifyEncryptedFile(
205
- path: string,
206
- key: Buffer,
207
- ): Promise<boolean> {
208
- assertKey(key);
209
-
210
- const info = await stat(path);
211
- const totalSize = info.size;
212
- const minSize = ENCRYPTED_HEADER_SIZE + GCM_TAG_SIZE;
213
- if (totalSize < minSize) {
214
- // Too short to contain an IV + tag — not a valid bundle.
215
- return false;
216
- }
217
-
218
- const iv = Buffer.alloc(ENCRYPTED_HEADER_SIZE);
219
- const tag = Buffer.alloc(GCM_TAG_SIZE);
220
- const fh = await open(path, "r");
221
- try {
222
- await fh.read(iv, 0, ENCRYPTED_HEADER_SIZE, 0);
223
- await fh.read(tag, 0, GCM_TAG_SIZE, totalSize - GCM_TAG_SIZE);
224
- } finally {
225
- await fh.close();
226
- }
227
-
228
- const decipher = createDecipheriv(ALGORITHM, key, iv);
229
- decipher.setAuthTag(tag);
230
-
231
- const ciphertextStart = ENCRYPTED_HEADER_SIZE;
232
- const ciphertextEnd = totalSize - GCM_TAG_SIZE - 1;
233
- const hasCiphertext = ciphertextEnd >= ciphertextStart;
234
- const ciphertextStream = hasCiphertext
235
- ? createReadStream(path, { start: ciphertextStart, end: ciphertextEnd })
236
- : Readable.from([]);
237
-
238
- // Discard-only sink — verification never touches scratch disk.
239
- const nullSink = new Writable({
240
- write(_chunk, _encoding, cb) {
241
- cb();
242
- },
243
- });
244
-
245
- try {
246
- await pipeline(ciphertextStream, decipher, nullSink);
247
- return true;
248
- } catch (err) {
249
- if (isFilesystemError(err)) {
250
- throw err;
251
- }
252
- return false;
253
- }
254
- }
255
-
256
- // Node errno exceptions surface as uppercase `E`-prefixed codes (ENOENT,
257
- // EACCES, ENOSPC, EIO, EROFS, …). Crypto errors use `ERR_*` codes or no code
258
- // at all, so the regex rules them out.
259
- function isFilesystemError(err: unknown): boolean {
260
- if (!err || typeof err !== "object") return false;
261
- const code = (err as { code?: unknown }).code;
262
- return typeof code === "string" && /^E[A-Z]+$/.test(code);
263
- }
@@ -1,58 +0,0 @@
1
- // Pairing approval and approved-device management types.
2
-
3
- // === Client → Server ===
4
-
5
- export interface PairingApprovalResponse {
6
- type: "pairing_approval_response";
7
- pairingRequestId: string;
8
- decision: "approve_once" | "always_allow" | "deny";
9
- }
10
-
11
- export interface ApprovedDevicesList {
12
- type: "approved_devices_list";
13
- }
14
-
15
- export interface ApprovedDeviceRemove {
16
- type: "approved_device_remove";
17
- hashedDeviceId: string;
18
- }
19
-
20
- export interface ApprovedDevicesClear {
21
- type: "approved_devices_clear";
22
- }
23
-
24
- // === Server → Client ===
25
-
26
- export interface PairingApprovalRequest {
27
- type: "pairing_approval_request";
28
- pairingRequestId: string;
29
- deviceId: string;
30
- deviceName: string;
31
- }
32
-
33
- export interface ApprovedDevicesListResponse {
34
- type: "approved_devices_list_response";
35
- devices: Array<{
36
- hashedDeviceId: string;
37
- deviceName: string;
38
- lastPairedAt: number;
39
- }>;
40
- }
41
-
42
- export interface ApprovedDeviceRemoveResponse {
43
- type: "approved_device_remove_response";
44
- success: boolean;
45
- }
46
-
47
- // --- Domain-level union aliases (consumed by the barrel file) ---
48
-
49
- export type _PairingClientMessages =
50
- | PairingApprovalResponse
51
- | ApprovedDevicesList
52
- | ApprovedDeviceRemove
53
- | ApprovedDevicesClear;
54
-
55
- export type _PairingServerMessages =
56
- | PairingApprovalRequest
57
- | ApprovedDevicesListResponse
58
- | ApprovedDeviceRemoveResponse;
@@ -1,20 +0,0 @@
1
- /**
2
- * Configuration for the standalone proxy sidecar server.
3
- *
4
- * All values are sourced from environment variables with sensible defaults.
5
- * Invalid values cause the process to exit with a descriptive error so
6
- * misconfigurations are caught immediately at startup.
7
- */
8
-
9
- export interface SidecarConfig {
10
- /** Port the proxy server listens on. */
11
- port: number;
12
- /** Host address to bind to. */
13
- host: string;
14
- /** Port for the health/readiness HTTP server. */
15
- healthPort: number;
16
- /** Optional CA directory for MITM interception (contains ca.pem / ca-key.pem). */
17
- caDir: string | null;
18
- /** Log level for the sidecar process. */
19
- logLevel: "debug" | "info" | "warn" | "error";
20
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Health / readiness HTTP server for the proxy sidecar.
3
- *
4
- * Exposes two endpoints on a separate control port:
5
- * GET /healthz - Liveness probe. Returns 200 whenever the process is alive.
6
- * GET /readyz - Readiness probe. Returns 200 only when the proxy server
7
- * is listening and ready to accept connections.
8
- *
9
- * All other paths return 404. Non-GET methods return 405.
10
- */
11
-
12
- export interface HealthServerOptions {
13
- /**
14
- * Callback that returns `true` when the proxy server is ready to accept
15
- * connections. The readiness probe delegates to this function.
16
- */
17
- isReady: () => boolean;
18
- }
@@ -1,150 +0,0 @@
1
- /** How a credential value is injected into an outbound proxied request. */
2
- export type CredentialInjectionType = "header" | "query";
3
-
4
- /**
5
- * Describes where and how to inject a credential into proxied requests
6
- * matching a specific host pattern.
7
- */
8
- export interface CredentialInjectionTemplate {
9
- /** Glob pattern for matching request hosts (e.g. "*.fal.ai"). */
10
- hostPattern: string;
11
- /** Where the credential value is injected. */
12
- injectionType: CredentialInjectionType;
13
- /** Header name when injectionType is 'header' (e.g. "Authorization"). */
14
- headerName?: string;
15
- /** Prefix prepended to the secret value (e.g. "Key ", "Bearer "). */
16
- valuePrefix?: string;
17
- /** Query parameter name when injectionType is 'query'. */
18
- queryParamName?: string;
19
- }
20
-
21
- /** Unique identifier for a proxy session. */
22
- export type ProxySessionId = string;
23
-
24
- export type ProxySessionStatus = "starting" | "active" | "stopping" | "stopped";
25
-
26
- export interface ProxySession {
27
- id: ProxySessionId;
28
- conversationId: string;
29
- credentialIds: string[];
30
- status: ProxySessionStatus;
31
- createdAt: Date;
32
- /** Ephemeral port assigned once the session starts listening. */
33
- port: number | null;
34
- }
35
-
36
- export interface ProxySessionConfig {
37
- /** How long (ms) an idle session stays alive before auto-stopping. */
38
- idleTimeoutMs: number;
39
- /** Maximum concurrent sessions per conversation. */
40
- maxSessionsPerConversation: number;
41
- }
42
-
43
- export interface ProxyEnvVars {
44
- HTTP_PROXY: string;
45
- HTTPS_PROXY: string;
46
- NO_PROXY: string;
47
- NODE_EXTRA_CA_CERTS?: string;
48
- /** Combined CA bundle (system roots + proxy CA) for non-Node TLS clients (curl, Python, etc.). */
49
- SSL_CERT_FILE?: string;
50
- }
51
-
52
- // ---------------------------------------------------------------------------
53
- // Policy engine types
54
- // ---------------------------------------------------------------------------
55
-
56
- /** A single credential matched -- inject it. */
57
- export interface PolicyDecisionMatched {
58
- kind: "matched";
59
- credentialId: string;
60
- template: CredentialInjectionTemplate;
61
- }
62
-
63
- /** Multiple credentials match -- caller must disambiguate. */
64
- export interface PolicyDecisionAmbiguous {
65
- kind: "ambiguous";
66
- candidates: Array<{
67
- credentialId: string;
68
- template: CredentialInjectionTemplate;
69
- }>;
70
- }
71
-
72
- /** No credential matches the target host/path. */
73
- export interface PolicyDecisionMissing {
74
- kind: "missing";
75
- }
76
-
77
- /** No credential_ids were requested -- pass-through. */
78
- export interface PolicyDecisionUnauthenticated {
79
- kind: "unauthenticated";
80
- }
81
-
82
- // ---------------------------------------------------------------------------
83
- // Approval hook outcomes -- structured data for triggering permission prompts.
84
- // ---------------------------------------------------------------------------
85
-
86
- /** Context about the outbound request target, used to build permission prompts. */
87
- export interface RequestTargetContext {
88
- hostname: string;
89
- port: number | null;
90
- path: string;
91
- /** The protocol scheme of the original request ('http' or 'https'). */
92
- scheme: "http" | "https";
93
- }
94
-
95
- /**
96
- * The target host matches a known credential template pattern, but the
97
- * session has no credential bound for it. The UI should prompt the user
98
- * to bind or create a credential.
99
- */
100
- export interface PolicyDecisionAskMissingCredential {
101
- kind: "ask_missing_credential";
102
- target: RequestTargetContext;
103
- /** Host patterns from the known registry that matched the target. */
104
- matchingPatterns: string[];
105
- }
106
-
107
- /**
108
- * The request doesn't match any known credential template and the session
109
- * has no credentials. The UI should prompt the user to allow or deny the
110
- * unauthenticated request.
111
- */
112
- export interface PolicyDecisionAskUnauthenticated {
113
- kind: "ask_unauthenticated";
114
- target: RequestTargetContext;
115
- }
116
-
117
- export type PolicyDecision =
118
- | PolicyDecisionMatched
119
- | PolicyDecisionAmbiguous
120
- | PolicyDecisionMissing
121
- | PolicyDecisionUnauthenticated
122
- | PolicyDecisionAskMissingCredential
123
- | PolicyDecisionAskUnauthenticated;
124
-
125
- // ---------------------------------------------------------------------------
126
- // Proxy approval callback -- wires policy "ask" decisions to the UI prompter.
127
- // ---------------------------------------------------------------------------
128
-
129
- /**
130
- * Payload passed to the approval callback when the policy engine emits an
131
- * `ask_missing_credential` or `ask_unauthenticated` decision. Contains
132
- * enough context for the prompter to build a meaningful confirmation dialog.
133
- */
134
- export interface ProxyApprovalRequest {
135
- /** The policy decision that triggered the approval prompt. */
136
- decision:
137
- | PolicyDecisionAskMissingCredential
138
- | PolicyDecisionAskUnauthenticated;
139
- /** The proxy session ID that originated the request. */
140
- sessionId: ProxySessionId;
141
- }
142
-
143
- /**
144
- * Callback signature for proxy approval prompts. The proxy service calls
145
- * this when an outbound request requires user confirmation. Returns `true`
146
- * if the user approves, `false` if denied.
147
- */
148
- export type ProxyApprovalCallback = (
149
- request: ProxyApprovalRequest,
150
- ) => Promise<boolean>;
@@ -1,190 +0,0 @@
1
- /**
2
- * Capability token verification for scoped, short-lived tokens issued to the
3
- * chrome extension (and other thin clients).
4
- *
5
- * Both minting and verification are owned by the gateway
6
- * (`gateway/src/auth/capability-tokens.ts`). The daemon delegates
7
- * verification to the gateway via IPC so it never needs to read the
8
- * HMAC secret from the filesystem.
9
- *
10
- * Test-only helpers (`mintHostBrowserCapability`,
11
- * `setCapabilityTokenSecretForTests`, `resetCapabilityTokenSecretForTests`)
12
- * implement the same HMAC logic in-process so assistant tests can create
13
- * and verify tokens without a live gateway.
14
- */
15
-
16
- import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
17
-
18
- import { ipcCall } from "../ipc/gateway-client.js";
19
- import { getLogger } from "../util/logger.js";
20
-
21
- const log = getLogger("capability-tokens");
22
-
23
- // ---------------------------------------------------------------------------
24
- // Types (mirror the gateway's types for consumer convenience)
25
- // ---------------------------------------------------------------------------
26
-
27
- /** Capability identifiers that can be bound to a capability token. */
28
- export type Capability = "host_browser_command";
29
-
30
- /** Claims encoded in the signed payload. */
31
- export interface CapabilityClaims {
32
- capability: Capability;
33
- guardianId: string;
34
- /** 16-byte random nonce, hex-encoded. Prevents replay across fresh mints. */
35
- nonce: string;
36
- /** ms-since-epoch expiry. */
37
- expiresAt: number;
38
- }
39
-
40
- /** A freshly-minted capability token and its absolute expiry. */
41
- export interface CapabilityToken {
42
- token: string;
43
- expiresAt: number;
44
- }
45
-
46
- // ---------------------------------------------------------------------------
47
- // In-process HMAC helpers (shared between test mint/verify and IPC verify)
48
- // ---------------------------------------------------------------------------
49
-
50
- let _testSecret: Buffer | undefined;
51
-
52
- function base64urlEncode(buf: Buffer): string {
53
- return buf
54
- .toString("base64")
55
- .replace(/\+/g, "-")
56
- .replace(/\//g, "_")
57
- .replace(/=+$/, "");
58
- }
59
-
60
- function base64urlDecode(s: string): Buffer {
61
- const pad = s.length % 4 === 0 ? 0 : 4 - (s.length % 4);
62
- const b64 = s.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat(pad);
63
- return Buffer.from(b64, "base64");
64
- }
65
-
66
- function sign(payload: string, secret: Buffer): string {
67
- return base64urlEncode(createHmac("sha256", secret).update(payload).digest());
68
- }
69
-
70
- // ---------------------------------------------------------------------------
71
- // Verify (production: gateway IPC, test: in-process)
72
- // ---------------------------------------------------------------------------
73
-
74
- /**
75
- * Verify a capability token.
76
- *
77
- * In production, delegates to the gateway via IPC. In tests (when a
78
- * secret has been injected via `setCapabilityTokenSecretForTests`),
79
- * verifies in-process so tests don't need a live gateway.
80
- *
81
- * Returns the decoded claims on success or null on any failure.
82
- */
83
- export async function verifyHostBrowserCapability(
84
- token: string,
85
- ): Promise<CapabilityClaims | null> {
86
- if (typeof token !== "string" || token.length === 0) return null;
87
-
88
- // Test path: in-process verification with the injected secret.
89
- if (_testSecret) {
90
- return verifyInProcess(token, _testSecret);
91
- }
92
-
93
- // Production path: delegate to the gateway.
94
- try {
95
- const result = await ipcCall("verify_capability_token", { token });
96
- if (!result || typeof result !== "object") return null;
97
-
98
- const claims = result as Record<string, unknown>;
99
- if (claims.valid === false) return null;
100
- if (claims.capability !== "host_browser_command") return null;
101
- if (
102
- typeof claims.guardianId !== "string" ||
103
- claims.guardianId.length === 0
104
- ) {
105
- return null;
106
- }
107
-
108
- return claims as unknown as CapabilityClaims;
109
- } catch (err) {
110
- log.warn({ err }, "Failed to verify capability token via gateway IPC");
111
- return null;
112
- }
113
- }
114
-
115
- function verifyInProcess(
116
- token: string,
117
- secret: Buffer,
118
- ): CapabilityClaims | null {
119
- const dot = token.indexOf(".");
120
- if (dot < 0) return null;
121
- const payload = token.slice(0, dot);
122
- const sig = token.slice(dot + 1);
123
- if (!payload || !sig) return null;
124
-
125
- const expected = sign(payload, secret);
126
- const a = Buffer.from(sig, "utf8");
127
- const b = Buffer.from(expected, "utf8");
128
- if (a.length !== b.length) return null;
129
- if (!timingSafeEqual(a, b)) return null;
130
-
131
- let claims: CapabilityClaims;
132
- try {
133
- claims = JSON.parse(
134
- base64urlDecode(payload).toString("utf8"),
135
- ) as CapabilityClaims;
136
- } catch {
137
- return null;
138
- }
139
-
140
- if (!claims || typeof claims !== "object") return null;
141
- if (claims.capability !== "host_browser_command") return null;
142
- if (typeof claims.guardianId !== "string" || claims.guardianId.length === 0) {
143
- return null;
144
- }
145
- if (typeof claims.expiresAt !== "number" || claims.expiresAt <= Date.now()) {
146
- return null;
147
- }
148
- return claims;
149
- }
150
-
151
- // ---------------------------------------------------------------------------
152
- // Test-only helpers
153
- // ---------------------------------------------------------------------------
154
-
155
- /**
156
- * Mint a capability token in-process. Test-only — production minting is
157
- * done by the gateway.
158
- */
159
- export function mintHostBrowserCapability(
160
- guardianId: string,
161
- ttlMs: number = 30 * 60 * 1000,
162
- ): CapabilityToken {
163
- const secret = _testSecret;
164
- if (!secret) {
165
- throw new Error(
166
- "capability token secret not set — call setCapabilityTokenSecretForTests() first",
167
- );
168
- }
169
- const expiresAt = Date.now() + ttlMs;
170
- const nonce = randomBytes(16).toString("hex");
171
- const claims: CapabilityClaims = {
172
- capability: "host_browser_command",
173
- guardianId,
174
- nonce,
175
- expiresAt,
176
- };
177
- const payload = base64urlEncode(Buffer.from(JSON.stringify(claims), "utf8"));
178
- const sig = sign(payload, secret);
179
- return { token: `${payload}.${sig}`, expiresAt };
180
- }
181
-
182
- /** Inject a deterministic secret for tests. */
183
- export function setCapabilityTokenSecretForTests(secret: Buffer): void {
184
- _testSecret = secret;
185
- }
186
-
187
- /** Reset the test secret. */
188
- export function resetCapabilityTokenSecretForTests(): void {
189
- _testSecret = undefined;
190
- }