@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
@@ -2,8 +2,6 @@ import { join } from "node:path";
2
2
 
3
3
  import { config as dotenvConfig } from "dotenv";
4
4
 
5
- import type { BackupWorkerHandle } from "../backup/backup-worker.js";
6
- import { startBackupWorker } from "../backup/backup-worker.js";
7
5
  import { setPointerMessageProcessor } from "../calls/call-pointer-messages.js";
8
6
  import { reconcileCallsOnStartup } from "../calls/call-recovery.js";
9
7
  import { setRelayBroadcast } from "../calls/relay-server.js";
@@ -25,10 +23,6 @@ import type { AssistantConfig } from "../config/schema.js";
25
23
  import { seedInferenceProfiles } from "../config/seed-inference-profiles.js";
26
24
  import type { CesClient } from "../credential-execution/client.js";
27
25
  import { createCesClient } from "../credential-execution/client.js";
28
- import {
29
- isCesCredentialBackendEnabled,
30
- isCesToolsEnabled,
31
- } from "../credential-execution/feature-gates.js";
32
26
  import {
33
27
  type CesProcessManager,
34
28
  CesUnavailableError,
@@ -54,10 +48,7 @@ import {
54
48
  import { expireAllPendingCanonicalRequests } from "../memory/canonical-guardian-store.js";
55
49
  import { deleteMessageById, getMessages } from "../memory/conversation-crud.js";
56
50
  import { initializeDb } from "../memory/db-init.js";
57
- import {
58
- selectEmbeddingBackend,
59
- SPARSE_EMBEDDING_VERSION,
60
- } from "../memory/embedding-backend.js";
51
+ import { selectEmbeddingBackend } from "../memory/embedding-backend.js";
61
52
  import { enqueueMemoryJob } from "../memory/jobs-store.js";
62
53
  import { startMemoryJobsWorker } from "../memory/jobs-worker.js";
63
54
  import { initQdrantClient, resolveQdrantUrl } from "../memory/qdrant-client.js";
@@ -81,6 +72,7 @@ import {
81
72
  import { RuntimeHttpServer } from "../runtime/http-server.js";
82
73
  import { recoverInterruptedImport } from "../runtime/migrations/vbundle-streaming-importer.js";
83
74
  import { registerSecretsDeps } from "../runtime/routes/secrets-deps.js";
75
+ import { recoverStaleSchedules } from "../schedule/schedule-recovery.js";
84
76
  import { startScheduler } from "../schedule/scheduler.js";
85
77
  import {
86
78
  onCesClientChanged,
@@ -157,17 +149,6 @@ export interface CesStartupResult {
157
149
  async function startCesProcess(
158
150
  config: AssistantConfig,
159
151
  ): Promise<CesStartupResult> {
160
- const shouldStartCes =
161
- isCesToolsEnabled(config) || isCesCredentialBackendEnabled(config);
162
- if (!shouldStartCes) {
163
- return {
164
- client: undefined,
165
- processManager: undefined,
166
- clientPromise: undefined,
167
- abortController: undefined,
168
- };
169
- }
170
-
171
152
  const pm = createCesProcessManager({ assistantConfig: config });
172
153
  const abortController = new AbortController();
173
154
  let clientRef: CesClient | undefined;
@@ -291,9 +272,16 @@ export async function runDaemon(): Promise<void> {
291
272
  // Fired non-blocking so a slow or unreachable gateway doesn't delay
292
273
  // daemon startup (the IPC call has a 3s connect + 5s call timeout
293
274
  // that would otherwise stall the critical path).
294
- void initFeatureFlagOverrides().catch((err) =>
295
- log.warn({ err }, "Background feature flag init failed"),
296
- );
275
+ //
276
+ // On resolve, retry the v2 skill seed: the synchronous gate at the
277
+ // skill-seed call site below evaluates the memory-v2-enabled flag
278
+ // before the gateway has populated overrides, so a cold-boot race
279
+ // can leave the v2 skill collection unseeded for the lifetime of
280
+ // the daemon. seedV2SkillEntries is idempotent, so re-running after
281
+ // overrides land is safe.
282
+ void initFeatureFlagOverrides()
283
+ .then(() => maybeSeedMemoryV2Skills(loadConfig()))
284
+ .catch((err) => log.warn({ err }, "Background feature flag init failed"));
297
285
 
298
286
  seedInterfaceFiles();
299
287
 
@@ -524,89 +512,81 @@ export async function runDaemon(): Promise<void> {
524
512
  // bootstrap connection, so startup must happen at the process level.
525
513
  const cesStartupPromise = startCesProcess(config);
526
514
 
527
- // When the credential backend flag is enabled, CES startup must complete
528
- // BEFORE provider initialization so credential reads can go through CES.
529
- // Block with a 20-second timeout — fall back to direct credential store
530
- // on timeout.
531
- if (isCesCredentialBackendEnabled(config)) {
532
- const cesResult = await cesStartupPromise;
533
- // startCesProcess() returns immediately the actual handshake runs
534
- // inside clientPromise. Await it (with a 20s timeout) so the CES client
535
- // is available before provider initialization.
536
- if (cesResult.clientPromise) {
537
- const client = await awaitCesClientWithTimeout(
538
- cesResult.clientPromise,
539
- {
540
- timeoutMs: DEFAULT_CES_STARTUP_TIMEOUT_MS,
541
- onTimeout: () => {
542
- log.warn(
543
- "CES handshake timed out after 20s — falling back to direct credential store",
544
- );
545
- },
546
- },
547
- );
548
- if (client) {
549
- setCesClient(client);
550
- }
515
+ // CES startup must complete BEFORE provider initialization so credential
516
+ // reads can go through CES. Block with a 20-second timeout — fall back to
517
+ // direct credential store on timeout.
518
+ const cesResult = await cesStartupPromise;
519
+ // startCesProcess() returns immediately — the actual handshake runs
520
+ // inside clientPromise. Await it (with a 20s timeout) so the CES client
521
+ // is available before provider initialization.
522
+ if (cesResult.clientPromise) {
523
+ const client = await awaitCesClientWithTimeout(cesResult.clientPromise, {
524
+ timeoutMs: DEFAULT_CES_STARTUP_TIMEOUT_MS,
525
+ onTimeout: () => {
526
+ log.warn(
527
+ "CES handshake timed out after 20s — falling back to direct credential store",
528
+ );
529
+ },
530
+ });
531
+ if (client) {
532
+ setCesClient(client);
551
533
  }
534
+ }
552
535
 
553
- // Register CES reconnection callback so the credential layer can
554
- // re-establish the connection when the transport dies, instead of
555
- // falling back to the encrypted file store.
556
- if (cesResult.processManager) {
557
- const pm = cesResult.processManager;
558
-
559
- // Snapshot the managed-proxy context and assistant ID at CES startup
560
- // so the reconnect closure below never calls back into
561
- // `resolveManagedProxyContext()`. That function reads the assistant
562
- // API key via `getSecureKeyAsync()`, which — once `setCesClient()`
563
- // has resolved the backend to CES RPC — routes the read through CES
564
- // itself. During a reconnect the old transport is dead and a new
565
- // one is being set up by this very closure, so the nested credential
566
- // read recursively awaits its own in-flight reconnection and
567
- // deadlocks until `CREDENTIAL_OP_TIMEOUT_MS` (45s) fires. That
568
- // 45-second stall delays every CES restart and causes dependent
569
- // credential reads (e.g. Meet's STT provider resolution) to return
570
- // `undefined` during the window. API key rotation uses the
571
- // `updateAssistantApiKey` RPC on the live client, not a reconnect,
572
- // so caching at startup is safe.
573
- const startupProxyCtx = await resolveManagedProxyContext();
574
- const startupAssistantId = getPlatformAssistantId();
575
-
576
- setCesReconnect(async () => {
577
- try {
578
- await pm.stop();
579
- const transport = await pm.start();
580
- const newClient = createCesClient(transport);
581
- const { accepted, reason } = await newClient.handshake({
582
- ...(startupProxyCtx.assistantApiKey
583
- ? { assistantApiKey: startupProxyCtx.assistantApiKey }
584
- : {}),
585
- ...(startupAssistantId
586
- ? { assistantId: startupAssistantId }
587
- : {}),
588
- });
589
- if (accepted) {
590
- log.info("CES reconnection handshake accepted");
591
- return newClient;
592
- }
593
- log.warn({ reason }, "CES reconnection handshake rejected");
594
- newClient.close();
595
- await pm.stop().catch(() => {});
596
- return undefined;
597
- } catch (err) {
598
- log.warn(
599
- { error: err instanceof Error ? err.message : String(err) },
600
- "CES reconnection attempt failed",
601
- );
602
- await pm.stop().catch(() => {});
603
- return undefined;
536
+ // Register CES reconnection callback so the credential layer can
537
+ // re-establish the connection when the transport dies, instead of
538
+ // falling back to the encrypted file store.
539
+ if (cesResult.processManager) {
540
+ const pm = cesResult.processManager;
541
+
542
+ // Snapshot the managed-proxy context and assistant ID at CES startup
543
+ // so the reconnect closure below never calls back into
544
+ // `resolveManagedProxyContext()`. That function reads the assistant
545
+ // API key via `getSecureKeyAsync()`, which — once `setCesClient()`
546
+ // has resolved the backend to CES RPC — routes the read through CES
547
+ // itself. During a reconnect the old transport is dead and a new
548
+ // one is being set up by this very closure, so the nested credential
549
+ // read recursively awaits its own in-flight reconnection and
550
+ // deadlocks until `CREDENTIAL_OP_TIMEOUT_MS` (45s) fires. That
551
+ // 45-second stall delays every CES restart and causes dependent
552
+ // credential reads (e.g. Meet's STT provider resolution) to return
553
+ // `undefined` during the window. API key rotation uses the
554
+ // `updateAssistantApiKey` RPC on the live client, not a reconnect,
555
+ // so caching at startup is safe.
556
+ const startupProxyCtx = await resolveManagedProxyContext();
557
+ const startupAssistantId = getPlatformAssistantId();
558
+
559
+ setCesReconnect(async () => {
560
+ try {
561
+ await pm.stop();
562
+ const transport = await pm.start();
563
+ const newClient = createCesClient(transport);
564
+ const { accepted, reason } = await newClient.handshake({
565
+ ...(startupProxyCtx.assistantApiKey
566
+ ? { assistantApiKey: startupProxyCtx.assistantApiKey }
567
+ : {}),
568
+ ...(startupAssistantId ? { assistantId: startupAssistantId } : {}),
569
+ });
570
+ if (accepted) {
571
+ log.info("CES reconnection handshake accepted");
572
+ return newClient;
604
573
  }
605
- });
606
- }
574
+ log.warn({ reason }, "CES reconnection handshake rejected");
575
+ newClient.close();
576
+ await pm.stop().catch(() => {});
577
+ return undefined;
578
+ } catch (err) {
579
+ log.warn(
580
+ { error: err instanceof Error ? err.message : String(err) },
581
+ "CES reconnection attempt failed",
582
+ );
583
+ await pm.stop().catch(() => {});
584
+ return undefined;
585
+ }
586
+ });
607
587
  }
608
588
 
609
- // Populate the registry with user plugins from `~/.vellum/plugins/*`
589
+ // Populate the registry with user plugins from `<workspaceDir>/plugins/*`
610
590
  // AFTER first-party plugins have already registered via their static
611
591
  // side-effect imports. User plugins may fail to load individually; a
612
592
  // failing user plugin is logged and skipped so one bad install can't
@@ -660,13 +640,12 @@ export async function runDaemon(): Promise<void> {
660
640
  );
661
641
  }
662
642
 
663
- // Mutable refs for Qdrant, memory worker, and backup worker so background
643
+ // Mutable refs for Qdrant and memory worker so background
664
644
  // init can assign them and the shutdown handler always sees the latest value.
665
645
  const bgRefs: {
666
646
  qdrantManager: QdrantManager | null;
667
647
  memoryWorker: { stop(): void } | null;
668
- backupWorker: BackupWorkerHandle | null;
669
- } = { qdrantManager: null, memoryWorker: null, backupWorker: null };
648
+ } = { qdrantManager: null, memoryWorker: null };
670
649
 
671
650
  // Initialize Qdrant vector store and memory worker in the background so the
672
651
  // RuntimeHttpServer can start accepting requests without waiting for Qdrant.
@@ -707,8 +686,11 @@ export async function runDaemon(): Promise<void> {
707
686
  if (qdrantStarted) {
708
687
  try {
709
688
  const embeddingSelection = await selectEmbeddingBackend(config);
689
+ // Sentinel only encodes the dense provider+model identity; sparse
690
+ // encoder changes never require collection recreation, so they
691
+ // intentionally do not contribute to the v1 collection identity.
710
692
  const embeddingModel = embeddingSelection.backend
711
- ? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}:sparse-v${SPARSE_EMBEDDING_VERSION}`
693
+ ? `${embeddingSelection.backend.provider}:${embeddingSelection.backend.model}`
712
694
  : undefined;
713
695
  const qdrantClient = initQdrantClient({
714
696
  url: qdrantUrl,
@@ -760,21 +742,32 @@ export async function runDaemon(): Promise<void> {
760
742
  );
761
743
  }
762
744
  })();
745
+
746
+ // Build the BM25 corpus stats (per-token document frequencies and
747
+ // average document length) used by the v2 sparse channel. Without
748
+ // this, document-side sparse embeddings fall back to legacy TF-only
749
+ // weighting via the chicken-and-egg guard in
750
+ // `embed-concept-page.ts`. Fire-and-forget for the same reason as
751
+ // PKB reconcile — the stats are an optional optimization, never a
752
+ // boot-blocking dependency.
753
+ void (async () => {
754
+ try {
755
+ const { rebuildConceptPageCorpusStats } =
756
+ await import("../memory/v2/sparse-bm25.js");
757
+ await rebuildConceptPageCorpusStats(getWorkspaceDir());
758
+ log.info("Memory v2 BM25 corpus stats built");
759
+ } catch (err) {
760
+ log.warn(
761
+ { err },
762
+ "BM25 corpus-stats rebuild failed — sparse channel will fall back to TF-only until next rebuild",
763
+ );
764
+ }
765
+ })();
763
766
  }
764
767
 
765
768
  log.info("Daemon startup: starting memory worker");
766
769
  bgRefs.memoryWorker = startMemoryJobsWorker();
767
770
 
768
- log.info("Daemon startup: starting backup worker");
769
- try {
770
- bgRefs.backupWorker = startBackupWorker();
771
- } catch (err) {
772
- log.warn(
773
- { err },
774
- "Backup worker failed to start — continuing without backups",
775
- );
776
- }
777
-
778
771
  // Seed capability graph nodes (new memory graph system)
779
772
  try {
780
773
  const {
@@ -818,6 +811,12 @@ export async function runDaemon(): Promise<void> {
818
811
  // macOS adapter so it can deliver notification_intent messages to clients.
819
812
  registerBroadcastFn((msg) => broadcastMessage(msg));
820
813
 
814
+ try {
815
+ recoverStaleSchedules();
816
+ } catch (err) {
817
+ log.error({ err }, "Schedule recovery failed — continuing startup");
818
+ }
819
+
821
820
  const scheduler = startScheduler(
822
821
  async (conversationId, message, options) => {
823
822
  await processMessage(
@@ -1279,7 +1278,6 @@ export async function runDaemon(): Promise<void> {
1279
1278
  scheduler,
1280
1279
  feedScheduler,
1281
1280
  getMemoryWorker: () => bgRefs.memoryWorker,
1282
- getBackupWorker: () => bgRefs.backupWorker,
1283
1281
  getQdrantManager: () => bgRefs.qdrantManager,
1284
1282
  mcpManager,
1285
1283
  telemetryReporter,
@@ -23,6 +23,7 @@ export * from "./message-types/diagnostics.js";
23
23
  export * from "./message-types/documents.js";
24
24
  export * from "./message-types/guardian-actions.js";
25
25
  export * from "./message-types/home.js";
26
+ export * from "./message-types/host-app-control.js";
26
27
  export * from "./message-types/host-bash.js";
27
28
  export * from "./message-types/host-browser.js";
28
29
  export * from "./message-types/host-cu.js";
@@ -34,7 +35,6 @@ export * from "./message-types/meet.js";
34
35
  export * from "./message-types/memory.js";
35
36
  export * from "./message-types/messages.js";
36
37
  export * from "./message-types/notifications.js";
37
- export * from "./message-types/pairing.js";
38
38
  export * from "./message-types/schedules.js";
39
39
  export * from "./message-types/settings.js";
40
40
  export * from "./message-types/shared.js";
@@ -80,6 +80,7 @@ import type {
80
80
  _GuardianActionsServerMessages,
81
81
  } from "./message-types/guardian-actions.js";
82
82
  import type { _HomeServerMessages } from "./message-types/home.js";
83
+ import type { _HostAppControlServerMessages } from "./message-types/host-app-control.js";
83
84
  import type { _HostBashServerMessages } from "./message-types/host-bash.js";
84
85
  import type {
85
86
  _HostBrowserClientMessages,
@@ -106,10 +107,6 @@ import type {
106
107
  _NotificationsClientMessages,
107
108
  _NotificationsServerMessages,
108
109
  } from "./message-types/notifications.js";
109
- import type {
110
- _PairingClientMessages,
111
- _PairingServerMessages,
112
- } from "./message-types/pairing.js";
113
110
  import type {
114
111
  _SchedulesClientMessages,
115
112
  _SchedulesServerMessages,
@@ -170,7 +167,6 @@ export type ClientMessage =
170
167
  | _SchedulesClientMessages
171
168
  | _DiagnosticsClientMessages
172
169
  | _InboxClientMessages
173
- | _PairingClientMessages
174
170
  | _NotificationsClientMessages
175
171
  | _SettingsClientMessages;
176
172
 
@@ -191,6 +187,7 @@ export type ServerMessage =
191
187
  | _DocumentsServerMessages
192
188
  | _GuardianActionsServerMessages
193
189
  | _HomeServerMessages
190
+ | _HostAppControlServerMessages
194
191
  | _HostBashServerMessages
195
192
  | _HostBrowserServerMessages
196
193
  | _HostCuServerMessages
@@ -203,7 +200,6 @@ export type ServerMessage =
203
200
  | _SettingsServerMessages
204
201
  | _DiagnosticsServerMessages
205
202
  | _InboxServerMessages
206
- | _PairingServerMessages
207
203
  | _NotificationsServerMessages
208
204
  | _UpgradesServerMessages
209
205
  | _AcpServerMessages
@@ -215,4 +211,3 @@ export interface ContractSchema {
215
211
  client: ClientMessage;
216
212
  server: ServerMessage;
217
213
  }
218
-
@@ -36,6 +36,25 @@ export interface ContactsChanged {
36
36
  type: "contacts_changed";
37
37
  }
38
38
 
39
+ /**
40
+ * Server → Client prompt requesting the user to enter a contact channel address.
41
+ * Emitted by the `contacts/prompt` IPC route.
42
+ */
43
+ export interface ContactRequest {
44
+ type: "contact_request";
45
+ requestId: string;
46
+ /** Suggested channel type (e.g. "phone", "email") — used as a hint, not enforced. */
47
+ channel?: string;
48
+ /** Placeholder text for the address input field. */
49
+ placeholder?: string;
50
+ /** Display label shown above the input field. */
51
+ label?: string;
52
+ /** Longer description shown below the label. */
53
+ description?: string;
54
+ /** Suggested role for the new contact (guardian / trusted-contact / unknown). */
55
+ role?: string;
56
+ }
57
+
39
58
  export interface ContactPayload {
40
59
  id: string;
41
60
  displayName: string;
@@ -68,4 +87,7 @@ export interface ContactChannelPayload {
68
87
 
69
88
  export type _ContactsClientMessages = ContactsRequest;
70
89
 
71
- export type _ContactsServerMessages = ContactsResponse | ContactsChanged;
90
+ export type _ContactsServerMessages =
91
+ | ContactsResponse
92
+ | ContactsChanged
93
+ | ContactRequest;
@@ -184,7 +184,7 @@ export interface ReorderConversationsRequest {
184
184
 
185
185
  // === Server → Client ===
186
186
 
187
- export interface ConversationSearchMatchingMessage {
187
+ interface ConversationSearchMatchingMessage {
188
188
  messageId: string;
189
189
  role: string;
190
190
  /** Plain-text excerpt around the match, truncated to ~200 chars. */
@@ -192,7 +192,7 @@ export interface ConversationSearchMatchingMessage {
192
192
  createdAt: number;
193
193
  }
194
194
 
195
- export interface ConversationSearchResultItem {
195
+ interface ConversationSearchResultItem {
196
196
  conversationId: string;
197
197
  conversationTitle: string | null;
198
198
  conversationUpdatedAt: number;
@@ -225,7 +225,7 @@ export interface ConversationTitleUpdated {
225
225
  }
226
226
 
227
227
  /** Channel binding metadata exposed in conversation list APIs. */
228
- export interface ChannelBinding {
228
+ interface ChannelBinding {
229
229
  sourceChannel: ChannelId;
230
230
  externalChatId: string;
231
231
  externalUserId?: string | null;
@@ -234,7 +234,7 @@ export interface ChannelBinding {
234
234
  }
235
235
 
236
236
  /** Attention state metadata for a conversation's latest assistant message. */
237
- export interface AssistantAttention {
237
+ interface AssistantAttention {
238
238
  hasUnseenLatestAssistantMessage: boolean;
239
239
  latestAssistantMessageAt?: number;
240
240
  lastSeenAssistantMessageAt?: number;
@@ -242,7 +242,7 @@ export interface AssistantAttention {
242
242
  lastSeenSignalType?: string;
243
243
  }
244
244
 
245
- export interface ConversationForkParent {
245
+ interface ConversationForkParent {
246
246
  conversationId: string;
247
247
  messageId: string;
248
248
  title: string;
@@ -329,7 +329,7 @@ export interface ModelInfo {
329
329
  }>;
330
330
  }
331
331
 
332
- export interface HistoryResponseToolCall {
332
+ interface HistoryResponseToolCall {
333
333
  name: string;
334
334
  input: Record<string, unknown>;
335
335
  result?: string;
@@ -350,7 +350,10 @@ export interface HistoryResponseToolCall {
350
350
  riskLevel?: string;
351
351
  /** Human-readable reason for the risk classification. */
352
352
  riskReason?: string;
353
- /** Whether the tool was auto-approved (true) or required explicit user input (false). */
353
+ /**
354
+ * @deprecated Use `approvalMode` and `approvalReason` instead.
355
+ * Kept for backward compatibility during the migration window.
356
+ */
354
357
  autoApproved?: boolean;
355
358
  /** How the approval decision was reached: prompted, auto, blocked, or unknown (legacy). */
356
359
  approvalMode?: string;
@@ -360,7 +363,7 @@ export interface HistoryResponseToolCall {
360
363
  riskThreshold?: string;
361
364
  }
362
365
 
363
- export interface HistoryResponseSurface {
366
+ interface HistoryResponseSurface {
364
367
  surfaceId: string;
365
368
  surfaceType: string;
366
369
  title?: string;
@@ -0,0 +1,150 @@
1
+ // Host app-control proxy types.
2
+ // Enables proxying app-control actions (start, observe, press, combo, type,
3
+ // click, drag, stop) to the desktop client (host machine) when running as a
4
+ // managed assistant. Targets a specific application by bundle ID or process
5
+ // name — distinct from the system-wide computer-use proxy in host-cu.ts.
6
+
7
+ // === Tool input discriminated union ===
8
+
9
+ /** Inputs accepted by the nine app-control tool variants. */
10
+ export type HostAppControlInput =
11
+ | HostAppControlStartInput
12
+ | HostAppControlObserveInput
13
+ | HostAppControlPressInput
14
+ | HostAppControlComboInput
15
+ | HostAppControlSequenceInput
16
+ | HostAppControlTypeInput
17
+ | HostAppControlClickInput
18
+ | HostAppControlDragInput
19
+ | HostAppControlStopInput;
20
+
21
+ export interface HostAppControlStartInput {
22
+ tool: "start";
23
+ /** Bundle ID (preferred) or process name. */
24
+ app: string;
25
+ /** Optional command-line arguments to launch the app with. */
26
+ args?: string[];
27
+ }
28
+
29
+ export interface HostAppControlObserveInput {
30
+ tool: "observe";
31
+ app: string;
32
+ /**
33
+ * Milliseconds to wait between receiving the request and capturing the
34
+ * window. Lets the target app process pending input and the WindowServer
35
+ * composite a fresh frame. When omitted, the client uses its default
36
+ * (~200ms, sized for emulator-class apps at 60fps). Pass `0` for static
37
+ * UIs to make `observe` snappier; raise it for slow-feedback apps.
38
+ */
39
+ settle_ms?: number;
40
+ }
41
+
42
+ export interface HostAppControlPressInput {
43
+ tool: "press";
44
+ app: string;
45
+ /** Single key identifier, e.g. "return", "a", "f12". */
46
+ key: string;
47
+ /** Modifier list, e.g. ["cmd", "shift"]. */
48
+ modifiers?: string[];
49
+ /** Hold duration in milliseconds. */
50
+ duration_ms?: number;
51
+ }
52
+
53
+ export interface HostAppControlComboInput {
54
+ tool: "combo";
55
+ app: string;
56
+ /** Sequence of keys pressed simultaneously, e.g. ["cmd", "shift", "4"]. */
57
+ keys: string[];
58
+ /** Hold duration in milliseconds. */
59
+ duration_ms?: number;
60
+ }
61
+
62
+ /** A single step inside a sequence: one key press with optional modifiers, hold duration, and post-press gap. */
63
+ export interface HostAppControlSequenceStep {
64
+ /** Single key identifier, e.g. "right", "a", "return". */
65
+ key: string;
66
+ /** Modifier list, e.g. ["cmd", "shift"]. Omit for no modifiers. */
67
+ modifiers?: string[];
68
+ /** Hold duration for this key in milliseconds. */
69
+ duration_ms?: number;
70
+ /** Pause after this step before starting the next, in milliseconds. */
71
+ gap_ms?: number;
72
+ }
73
+
74
+ export interface HostAppControlSequenceInput {
75
+ tool: "sequence";
76
+ app: string;
77
+ /** Ordered list of single-key presses to execute serially. */
78
+ steps: HostAppControlSequenceStep[];
79
+ }
80
+
81
+ export interface HostAppControlTypeInput {
82
+ tool: "type";
83
+ app: string;
84
+ text: string;
85
+ }
86
+
87
+ export interface HostAppControlClickInput {
88
+ tool: "click";
89
+ app: string;
90
+ x: number;
91
+ y: number;
92
+ button?: "left" | "right" | "middle";
93
+ double?: boolean;
94
+ }
95
+
96
+ export interface HostAppControlDragInput {
97
+ tool: "drag";
98
+ app: string;
99
+ from_x: number;
100
+ from_y: number;
101
+ to_x: number;
102
+ to_y: number;
103
+ button?: "left" | "right" | "middle";
104
+ }
105
+
106
+ export interface HostAppControlStopInput {
107
+ tool: "stop";
108
+ /** Optional — when omitted the proxy stops whichever app currently holds the session. */
109
+ app?: string;
110
+ /** Free-form reason, surfaced for logging. */
111
+ reason?: string;
112
+ }
113
+
114
+ // === Server → Client ===
115
+
116
+ export interface HostAppControlRequest {
117
+ type: "host_app_control_request";
118
+ requestId: string;
119
+ conversationId: string;
120
+ toolName: string; // "app_control_start", "app_control_observe", etc.
121
+ input: HostAppControlInput;
122
+ }
123
+
124
+ export interface HostAppControlCancel {
125
+ type: "host_app_control_cancel";
126
+ requestId: string;
127
+ conversationId: string;
128
+ }
129
+
130
+ // === Result payload (HTTP /v1/host-app-control-result body) ===
131
+
132
+ /** Lifecycle state of the targeted application as seen by the client. */
133
+ export type HostAppControlState = "running" | "missing" | "minimized";
134
+
135
+ export interface HostAppControlResultPayload {
136
+ requestId: string;
137
+ state: HostAppControlState;
138
+ /** Base64-encoded PNG screenshot of the targeted app window, when available. */
139
+ pngBase64?: string;
140
+ /** Window bounds in screen-space points. */
141
+ windowBounds?: { x: number; y: number; width: number; height: number };
142
+ executionResult?: string;
143
+ executionError?: string;
144
+ }
145
+
146
+ // --- Domain-level union aliases (consumed by the barrel file) ---
147
+
148
+ export type _HostAppControlServerMessages =
149
+ | HostAppControlRequest
150
+ | HostAppControlCancel;
@@ -13,12 +13,16 @@ export interface HostBashRequest {
13
13
  timeout_seconds?: number;
14
14
  /** Extra environment variables to inject into the subprocess (e.g. VELLUM_UNTRUSTED_SHELL). */
15
15
  env?: Record<string, string>;
16
+ /** When set, route this request only to the client with this ID. */
17
+ targetClientId?: string;
16
18
  }
17
19
 
18
20
  export interface HostBashCancelRequest {
19
21
  type: "host_bash_cancel";
20
22
  requestId: string;
21
23
  conversationId: string;
24
+ /** When set, route this cancel only to the client that owns the request. */
25
+ targetClientId?: string;
22
26
  }
23
27
 
24
28
  // --- Domain-level union aliases (consumed by the barrel file) ---