@vellumai/assistant 0.7.1 → 0.7.3

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 (739) hide show
  1. package/ARCHITECTURE.md +48 -50
  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/memory.md +5 -2
  7. package/docs/architecture/security.md +20 -0
  8. package/docs/plugins.md +7 -9
  9. package/knip.json +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  11. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
  12. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  13. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  15. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  16. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  17. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  18. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  19. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  20. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  21. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  22. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  23. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  24. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  25. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  26. package/openapi.yaml +1020 -40
  27. package/package.json +6 -3
  28. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  29. package/src/__tests__/app-bundler.test.ts +170 -1
  30. package/src/__tests__/app-control-flow.test.ts +384 -0
  31. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  32. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  33. package/src/__tests__/app-executors.test.ts +30 -43
  34. package/src/__tests__/approval-routes-http.test.ts +23 -6
  35. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  36. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +157 -2
  38. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
  39. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  40. package/src/__tests__/background-shell-host-bash.test.ts +14 -15
  41. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  42. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  43. package/src/__tests__/btw-routes.test.ts +13 -4
  44. package/src/__tests__/call-controller.test.ts +49 -1
  45. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  46. package/src/__tests__/call-domain.test.ts +0 -2
  47. package/src/__tests__/call-routes-http.test.ts +0 -2
  48. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  49. package/src/__tests__/channel-readiness-service.test.ts +62 -2
  50. package/src/__tests__/checker.test.ts +3 -4
  51. package/src/__tests__/config-loader-backfill.test.ts +461 -147
  52. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  53. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  54. package/src/__tests__/config-schema.test.ts +1 -0
  55. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  56. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
  57. package/src/__tests__/config-watcher.test.ts +142 -71
  58. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  59. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  60. package/src/__tests__/context-search-fanout.test.ts +0 -1
  61. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  62. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  63. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  64. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  65. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  66. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  67. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  68. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  70. package/src/__tests__/conversation-error.test.ts +150 -3
  71. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  72. package/src/__tests__/conversation-lifecycle.test.ts +36 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  74. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  76. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
  78. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  79. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  80. package/src/__tests__/conversation-slash-commands.test.ts +0 -4
  81. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  82. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  83. package/src/__tests__/conversation-store.test.ts +0 -18
  84. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  85. package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
  86. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  87. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  88. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  89. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  90. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  91. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  92. package/src/__tests__/credentials-cli.test.ts +12 -12
  93. package/src/__tests__/cu-unified-flow.test.ts +351 -23
  94. package/src/__tests__/daemon-credential-client.test.ts +101 -19
  95. package/src/__tests__/date-context.test.ts +164 -2
  96. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  97. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  98. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  99. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  100. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  101. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  102. package/src/__tests__/disk-usage.test.ts +150 -0
  103. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  104. package/src/__tests__/events-client-registration.test.ts +52 -0
  105. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  106. package/src/__tests__/file-write-tool.test.ts +4 -10
  107. package/src/__tests__/filing-service.test.ts +3 -4
  108. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  109. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  110. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
  111. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
  112. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  113. package/src/__tests__/heartbeat-service.test.ts +968 -2
  114. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  115. package/src/__tests__/host-app-control-proxy.test.ts +772 -0
  116. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  117. package/src/__tests__/host-bash-proxy.test.ts +439 -47
  118. package/src/__tests__/host-bash-routes.test.ts +459 -0
  119. package/src/__tests__/host-browser-proxy.test.ts +24 -22
  120. package/src/__tests__/host-browser-routes.test.ts +39 -13
  121. package/src/__tests__/host-cu-proxy.test.ts +248 -52
  122. package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
  123. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  124. package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
  125. package/src/__tests__/host-file-proxy.test.ts +301 -45
  126. package/src/__tests__/host-file-read-tool.test.ts +17 -0
  127. package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
  128. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  129. package/src/__tests__/host-proxy-base.test.ts +312 -0
  130. package/src/__tests__/host-shell-tool.test.ts +22 -4
  131. package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
  132. package/src/__tests__/host-transfer-proxy.test.ts +121 -22
  133. package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
  134. package/src/__tests__/http-user-message-parity.test.ts +108 -1
  135. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  136. package/src/__tests__/identity-routes.test.ts +103 -1
  137. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  138. package/src/__tests__/injector-chain.test.ts +18 -6
  139. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  140. package/src/__tests__/inline-command-runner.test.ts +0 -1
  141. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
  142. package/src/__tests__/integration-status.test.ts +85 -5
  143. package/src/__tests__/intent-routing.test.ts +0 -1
  144. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  145. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  146. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  147. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
  148. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  149. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  150. package/src/__tests__/mcp-cli.test.ts +338 -2
  151. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  153. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  154. package/src/__tests__/migration-import-commit-http.test.ts +108 -2
  155. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  156. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  157. package/src/__tests__/oauth-cli.test.ts +0 -2
  158. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  159. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  160. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  161. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  162. package/src/__tests__/openai-provider.test.ts +45 -8
  163. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  164. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  165. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
  166. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  167. package/src/__tests__/platform.test.ts +2 -1
  168. package/src/__tests__/playbook-execution.test.ts +0 -43
  169. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  170. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
  171. package/src/__tests__/process-message-background-slack.test.ts +2 -0
  172. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  173. package/src/__tests__/provider-tool-name.test.ts +23 -0
  174. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  175. package/src/__tests__/relay-server.test.ts +15 -4
  176. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  177. package/src/__tests__/retry-backoff.test.ts +87 -0
  178. package/src/__tests__/runtime-events-sse.test.ts +2 -2
  179. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  180. package/src/__tests__/schedule-retry.test.ts +715 -0
  181. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  182. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  183. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  184. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  185. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
  186. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  187. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  188. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  189. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  190. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  191. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
  192. package/src/__tests__/slack-channel-config.test.ts +9 -14
  193. package/src/__tests__/suggestion-routes.test.ts +46 -0
  194. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  195. package/src/__tests__/system-prompt.test.ts +0 -1
  196. package/src/__tests__/telegram-config.test.ts +0 -1
  197. package/src/__tests__/test-preload.ts +8 -0
  198. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  199. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  200. package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
  201. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  202. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  203. package/src/__tests__/tool-executor.test.ts +0 -1
  204. package/src/__tests__/twilio-config.test.ts +3 -16
  205. package/src/__tests__/twilio-routes.test.ts +3 -5
  206. package/src/__tests__/twilio-validation.test.ts +93 -0
  207. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
  208. package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
  209. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  210. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  211. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  212. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  213. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  214. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  215. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  216. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  217. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  218. package/src/approvals/guardian-decision-primitive.ts +13 -0
  219. package/src/approvals/guardian-request-resolvers.ts +16 -17
  220. package/src/backup/__tests__/paths.test.ts +0 -22
  221. package/src/backup/__tests__/restore.test.ts +51 -151
  222. package/src/backup/paths.ts +2 -18
  223. package/src/backup/restore.ts +107 -231
  224. package/src/backup/snapshot-lock.ts +2 -27
  225. package/src/bundler/app-bundler.ts +51 -3
  226. package/src/bundler/compiler-tools.ts +3 -2
  227. package/src/calls/call-conversation-messages.ts +46 -10
  228. package/src/calls/relay-server.ts +4 -44
  229. package/src/calls/twilio-config.ts +2 -17
  230. package/src/calls/twilio-rest.ts +33 -105
  231. package/src/calls/twilio-routes.ts +11 -12
  232. package/src/channels/types.ts +8 -7
  233. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  234. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  235. package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
  236. package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
  237. package/src/cli/commands/backup.ts +6 -331
  238. package/src/cli/commands/bash.ts +35 -108
  239. package/src/cli/commands/clients.ts +36 -37
  240. package/src/cli/commands/contacts.ts +137 -25
  241. package/src/cli/commands/conversations.ts +2 -5
  242. package/src/cli/commands/credentials.ts +71 -7
  243. package/src/cli/commands/domain.ts +66 -15
  244. package/src/cli/commands/gateway.ts +183 -0
  245. package/src/cli/commands/keys.ts +9 -6
  246. package/src/cli/commands/mcp.ts +116 -156
  247. package/src/cli/commands/memory-v2.ts +303 -7
  248. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  249. package/src/cli/commands/oauth/connect.ts +127 -1
  250. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
  251. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
  252. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
  253. package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
  254. package/src/cli/commands/platform/disconnect.ts +5 -4
  255. package/src/cli/commands/platform/index.ts +16 -25
  256. package/src/cli/commands/status.ts +57 -0
  257. package/src/cli/lib/daemon-credential-client.ts +110 -28
  258. package/src/cli/program.ts +6 -2
  259. package/src/config/assistant-feature-flags.ts +79 -12
  260. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  261. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  262. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  263. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  264. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  265. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  266. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  267. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  268. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  269. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  270. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  271. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  272. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  273. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  274. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  275. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  276. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  277. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  278. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  279. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  280. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  281. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  282. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  283. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  284. package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
  285. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  286. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  287. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
  288. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  289. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  290. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  291. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  292. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  293. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  294. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  295. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  296. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  297. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  298. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  299. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  300. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  301. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  302. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  303. package/src/config/bundled-tool-registry.ts +21 -0
  304. package/src/config/env-registry.ts +0 -2
  305. package/src/config/env.ts +19 -20
  306. package/src/config/feature-flag-registry.json +47 -135
  307. package/src/config/loader.ts +197 -104
  308. package/src/config/sanitize-for-transfer.ts +2 -0
  309. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  310. package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
  311. package/src/config/schemas/call-site-catalog.ts +14 -0
  312. package/src/config/schemas/calls.ts +0 -9
  313. package/src/config/schemas/channels.ts +0 -5
  314. package/src/config/schemas/heartbeat.ts +64 -1
  315. package/src/config/schemas/ingress.ts +10 -6
  316. package/src/config/schemas/llm.ts +7 -10
  317. package/src/config/schemas/memory-lifecycle.ts +90 -24
  318. package/src/config/schemas/memory-v2.ts +121 -13
  319. package/src/config/schemas/platform.ts +49 -3
  320. package/src/config/schemas/services.ts +29 -15
  321. package/src/config/schemas/skills.ts +0 -6
  322. package/src/config/seed-inference-profiles.ts +230 -33
  323. package/src/contacts/contact-store.ts +0 -55
  324. package/src/contacts/contacts-write.ts +0 -27
  325. package/src/context/window-manager.ts +1 -2
  326. package/src/credential-execution/feature-gates.ts +10 -10
  327. package/src/credential-execution/process-manager.ts +12 -41
  328. package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
  329. package/src/daemon/assistant-attachments.ts +4 -4
  330. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  331. package/src/daemon/config-watcher.ts +89 -60
  332. package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
  333. package/src/daemon/conversation-agent-loop.ts +202 -61
  334. package/src/daemon/conversation-error.ts +87 -15
  335. package/src/daemon/conversation-lifecycle.ts +9 -4
  336. package/src/daemon/conversation-process.ts +24 -11
  337. package/src/daemon/conversation-runtime-assembly.ts +28 -2
  338. package/src/daemon/conversation-store.ts +2 -2
  339. package/src/daemon/conversation-surfaces.ts +305 -4
  340. package/src/daemon/conversation-tool-setup.ts +66 -62
  341. package/src/daemon/conversation.ts +38 -24
  342. package/src/daemon/date-context.ts +71 -22
  343. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  344. package/src/daemon/disk-pressure-guard.ts +343 -0
  345. package/src/daemon/disk-pressure-policy.ts +163 -0
  346. package/src/daemon/doordash-steps.ts +1 -1
  347. package/src/daemon/handlers/shared.ts +4 -2
  348. package/src/daemon/handlers/skills.ts +3 -4
  349. package/src/daemon/host-app-control-proxy.ts +389 -0
  350. package/src/daemon/host-bash-proxy.ts +117 -82
  351. package/src/daemon/host-browser-proxy.ts +67 -82
  352. package/src/daemon/host-cu-proxy.ts +127 -86
  353. package/src/daemon/host-file-proxy.ts +129 -69
  354. package/src/daemon/host-proxy-base.ts +294 -0
  355. package/src/daemon/host-proxy-preactivation.ts +82 -0
  356. package/src/daemon/host-transfer-proxy.ts +338 -129
  357. package/src/daemon/lifecycle.ts +194 -145
  358. package/src/daemon/meet-host-supervisor.ts +4 -4
  359. package/src/daemon/meet-manifest-loader.ts +0 -1
  360. package/src/daemon/memory-v2-startup.ts +14 -4
  361. package/src/daemon/message-protocol.ts +6 -8
  362. package/src/daemon/message-types/contacts.ts +23 -1
  363. package/src/daemon/message-types/conversations.ts +15 -8
  364. package/src/daemon/message-types/disk-pressure.ts +9 -0
  365. package/src/daemon/message-types/host-app-control.ts +150 -0
  366. package/src/daemon/message-types/host-bash.ts +4 -0
  367. package/src/daemon/message-types/host-cu.ts +2 -0
  368. package/src/daemon/message-types/host-file.ts +4 -0
  369. package/src/daemon/message-types/host-transfer.ts +3 -0
  370. package/src/daemon/message-types/messages.ts +3 -0
  371. package/src/daemon/message-types/schedules.ts +8 -3
  372. package/src/daemon/message-types/skills.ts +2 -2
  373. package/src/daemon/process-message.ts +18 -1
  374. package/src/daemon/profiler-run-store.ts +5 -5
  375. package/src/daemon/shutdown-handlers.ts +0 -3
  376. package/src/daemon/tool-setup-types.ts +51 -0
  377. package/src/daemon/tool-side-effects.ts +1 -1
  378. package/src/documents/document-store.ts +85 -0
  379. package/src/events/tool-audit-listener.ts +2 -1
  380. package/src/filing/filing-service.ts +30 -5
  381. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
  382. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
  383. package/src/heartbeat/heartbeat-run-store.ts +249 -0
  384. package/src/heartbeat/heartbeat-service.ts +459 -54
  385. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  386. package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
  387. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  388. package/src/home/feed-scheduler.ts +18 -0
  389. package/src/home/post-connect-feed.ts +68 -0
  390. package/src/home/relationship-state-writer.ts +17 -92
  391. package/src/home/suggested-prompts.ts +46 -10
  392. package/src/inbound/platform-callback-registration.ts +8 -15
  393. package/src/inbound/public-ingress-urls.ts +32 -34
  394. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  395. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  396. package/src/ipc/assistant-server.ts +70 -3
  397. package/src/ipc/cli-client.ts +32 -1
  398. package/src/ipc/gateway-client.ts +37 -3
  399. package/src/live-voice/live-voice-archive.ts +4 -4
  400. package/src/live-voice/live-voice-metrics.ts +10 -10
  401. package/src/live-voice/protocol.ts +5 -7
  402. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  403. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  404. package/src/mcp/mcp-auth-state.ts +133 -0
  405. package/src/mcp/mcp-oauth-provider.ts +19 -0
  406. package/src/media/image-service.ts +1 -7
  407. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  408. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  409. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  412. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  413. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  414. package/src/memory/admin.ts +5 -9
  415. package/src/memory/anisotropy.test.ts +247 -0
  416. package/src/memory/anisotropy.ts +443 -0
  417. package/src/memory/auto-analysis-constants.ts +17 -0
  418. package/src/memory/auto-analysis-guard.ts +5 -15
  419. package/src/memory/canonical-guardian-store.ts +7 -7
  420. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  421. package/src/memory/context-search/agent-protocol.ts +6 -6
  422. package/src/memory/context-search/agent-runner.ts +51 -9
  423. package/src/memory/context-search/sources/conversations.ts +2 -11
  424. package/src/memory/context-search/sources/memory-v2.ts +22 -9
  425. package/src/memory/context-search/sources/memory.ts +0 -1
  426. package/src/memory/context-search/types.ts +0 -1
  427. package/src/memory/conversation-crud.ts +5 -13
  428. package/src/memory/conversation-key-store.ts +2 -15
  429. package/src/memory/db-init.ts +6 -0
  430. package/src/memory/embedding-backend.ts +9 -21
  431. package/src/memory/embedding-runtime-manager.ts +119 -5
  432. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
  433. package/src/memory/graph/conversation-graph-memory.ts +43 -78
  434. package/src/memory/graph/extraction.ts +1 -3
  435. package/src/memory/graph/graph-search.test.ts +10 -67
  436. package/src/memory/graph/graph-search.ts +9 -20
  437. package/src/memory/graph/retriever.test.ts +6 -0
  438. package/src/memory/graph/retriever.ts +34 -10
  439. package/src/memory/graph/tools.ts +1 -1
  440. package/src/memory/indexer.ts +54 -45
  441. package/src/memory/job-handlers/backfill.ts +2 -11
  442. package/src/memory/job-handlers/cleanup.ts +43 -0
  443. package/src/memory/job-handlers/embedding.ts +6 -8
  444. package/src/memory/job-handlers/summarization.ts +2 -7
  445. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  446. package/src/memory/jobs/embed-concept-page.ts +28 -2
  447. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  448. package/src/memory/jobs-store.ts +114 -22
  449. package/src/memory/jobs-worker.ts +193 -106
  450. package/src/memory/memory-v2-activation-log-store.ts +33 -15
  451. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  452. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  453. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  454. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  455. package/src/memory/migrations/index.ts +6 -0
  456. package/src/memory/migrations/registry.ts +8 -0
  457. package/src/memory/pkb/pkb-search.test.ts +6 -0
  458. package/src/memory/pkb/pkb-search.ts +7 -0
  459. package/src/memory/qdrant-client.ts +49 -32
  460. package/src/memory/rerank-local.ts +374 -0
  461. package/src/memory/schema/infrastructure.ts +15 -0
  462. package/src/memory/search/semantic.ts +13 -67
  463. package/src/memory/sparse-tokenize.ts +49 -0
  464. package/src/memory/trace-event-store.ts +1 -17
  465. package/src/memory/v2/__tests__/activation.test.ts +387 -344
  466. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  467. package/src/memory/v2/__tests__/injection.test.ts +181 -169
  468. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  469. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  470. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  471. package/src/memory/v2/__tests__/sim.test.ts +154 -188
  472. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  473. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  474. package/src/memory/v2/__tests__/static-context.test.ts +76 -2
  475. package/src/memory/v2/activation.ts +213 -239
  476. package/src/memory/v2/consolidation-job.ts +65 -17
  477. package/src/memory/v2/constants.ts +7 -0
  478. package/src/memory/v2/injection.ts +123 -103
  479. package/src/memory/v2/prompts/consolidation.ts +348 -92
  480. package/src/memory/v2/qdrant.ts +198 -1
  481. package/src/memory/v2/reranker.ts +177 -0
  482. package/src/memory/v2/sim.ts +113 -77
  483. package/src/memory/v2/skill-content.ts +4 -3
  484. package/src/memory/v2/skill-store.ts +91 -53
  485. package/src/memory/v2/sparse-bm25.ts +245 -0
  486. package/src/memory/v2/static-context.ts +28 -5
  487. package/src/memory/v2/types.ts +10 -10
  488. package/src/messaging/providers/gmail/types.ts +0 -49
  489. package/src/messaging/providers/slack/adapter.ts +1 -31
  490. package/src/messaging/providers/slack/types.ts +0 -32
  491. package/src/notifications/README.md +10 -10
  492. package/src/notifications/broadcaster.ts +1 -1
  493. package/src/notifications/copy-composer.ts +13 -0
  494. package/src/notifications/guardian-question-mode.ts +5 -5
  495. package/src/notifications/signal.ts +4 -0
  496. package/src/oauth/AGENTS.md +3 -1
  497. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  498. package/src/oauth/connect-orchestrator.ts +6 -0
  499. package/src/oauth/connection-resolver.test.ts +66 -1
  500. package/src/oauth/connection-resolver.ts +55 -1
  501. package/src/oauth/credential-token-resolver.ts +1 -3
  502. package/src/oauth/manual-token-connection.ts +0 -4
  503. package/src/oauth/oauth-connect-state.ts +77 -0
  504. package/src/oauth/seed-providers.ts +58 -1
  505. package/src/outbound-proxy/index.ts +1 -37
  506. package/src/outbound-proxy/logging.ts +1 -1
  507. package/src/outbound-proxy/policy.ts +6 -5
  508. package/src/outbound-proxy/router.ts +2 -1
  509. package/src/permissions/approval-policy.test.ts +6 -275
  510. package/src/permissions/approval-policy.ts +0 -51
  511. package/src/permissions/checker.test.ts +0 -1
  512. package/src/permissions/checker.ts +3 -17
  513. package/src/permissions/gateway-threshold-reader.ts +2 -0
  514. package/src/permissions/prompter.ts +34 -1
  515. package/src/permissions/secret-prompter.ts +6 -2
  516. package/src/plugins/defaults/injectors.ts +35 -2
  517. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  518. package/src/plugins/types.ts +7 -0
  519. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  520. package/src/proactive-artifact/decision.test.ts +226 -0
  521. package/src/proactive-artifact/decision.ts +165 -0
  522. package/src/proactive-artifact/index.ts +7 -0
  523. package/src/proactive-artifact/job.test.ts +867 -0
  524. package/src/proactive-artifact/job.ts +352 -0
  525. package/src/proactive-artifact/message-copy.ts +41 -0
  526. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  527. package/src/proactive-artifact/trigger-state.ts +119 -0
  528. package/src/prompts/bootstrap-cleanup.ts +27 -0
  529. package/src/prompts/normalize-onboarding.ts +80 -0
  530. package/src/prompts/persona-resolver.ts +101 -9
  531. package/src/prompts/system-prompt.ts +23 -24
  532. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  533. package/src/prompts/templates/SOUL.md +13 -1
  534. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  535. package/src/providers/model-intents.ts +7 -0
  536. package/src/providers/openrouter/client.ts +8 -0
  537. package/src/providers/retry.ts +50 -0
  538. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  539. package/src/providers/types.ts +1 -0
  540. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  541. package/src/runtime/agent-wake.ts +238 -100
  542. package/src/runtime/assistant-event-hub.ts +151 -99
  543. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  544. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  545. package/src/runtime/auth/middleware.ts +0 -96
  546. package/src/runtime/auth/route-policy.ts +32 -0
  547. package/src/runtime/auth/same-actor.ts +216 -0
  548. package/src/runtime/btw-sidechain.ts +2 -3
  549. package/src/runtime/channel-invite-transport.ts +2 -48
  550. package/src/runtime/channel-invite-transports/email.ts +1 -1
  551. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  552. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  553. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  554. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  555. package/src/runtime/channel-invite-types.ts +54 -0
  556. package/src/runtime/channel-readiness-service.ts +32 -13
  557. package/src/runtime/channel-retry-sweep.ts +65 -1
  558. package/src/runtime/guardian-reply-router.ts +10 -0
  559. package/src/runtime/http-server.ts +3 -329
  560. package/src/runtime/http-types.ts +0 -5
  561. package/src/runtime/local-actor-identity.ts +52 -11
  562. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  563. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  564. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  565. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
  566. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  567. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  568. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  569. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  570. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  571. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
  572. package/src/runtime/migrations/migration-transport.ts +7 -7
  573. package/src/runtime/migrations/vbundle-builder.ts +327 -60
  574. package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
  575. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  576. package/src/runtime/migrations/vbundle-importer.ts +245 -68
  577. package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
  578. package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
  579. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  580. package/src/runtime/migrations/vbundle-validator.ts +114 -0
  581. package/src/runtime/pending-interactions.ts +43 -9
  582. package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
  583. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  584. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
  585. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  586. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  587. package/src/runtime/routes/approval-interception-types.ts +13 -0
  588. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  589. package/src/runtime/routes/backup-routes.ts +15 -38
  590. package/src/runtime/routes/btw-routes.ts +14 -37
  591. package/src/runtime/routes/client-routes.ts +21 -2
  592. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  593. package/src/runtime/routes/contact-routes.ts +0 -25
  594. package/src/runtime/routes/conversation-query-routes.ts +36 -1
  595. package/src/runtime/routes/conversation-routes.ts +65 -39
  596. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  597. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  598. package/src/runtime/routes/document-pdf-renderer.ts +169 -0
  599. package/src/runtime/routes/documents-routes.ts +32 -75
  600. package/src/runtime/routes/errors.ts +19 -4
  601. package/src/runtime/routes/events-routes.ts +38 -0
  602. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  603. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  604. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  605. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  606. package/src/runtime/routes/host-bash-routes.ts +56 -6
  607. package/src/runtime/routes/host-browser-routes.ts +108 -13
  608. package/src/runtime/routes/host-cu-routes.ts +66 -9
  609. package/src/runtime/routes/host-file-routes.ts +54 -5
  610. package/src/runtime/routes/host-transfer-routes.ts +122 -19
  611. package/src/runtime/routes/http-adapter.ts +1 -0
  612. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  613. package/src/runtime/routes/identity-routes.ts +21 -180
  614. package/src/runtime/routes/inbound-message-handler.ts +78 -21
  615. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
  616. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  617. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  618. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  619. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  620. package/src/runtime/routes/index.ts +14 -0
  621. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  622. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  623. package/src/runtime/routes/memory-item-routes.ts +10 -12
  624. package/src/runtime/routes/memory-v2-routes.ts +474 -1
  625. package/src/runtime/routes/migration-routes.ts +96 -0
  626. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  627. package/src/runtime/routes/schedule-routes.ts +7 -0
  628. package/src/runtime/verification-outbound-actions.ts +4 -4
  629. package/src/runtime/verification-templates.ts +4 -7
  630. package/src/schedule/integration-status.ts +66 -2
  631. package/src/schedule/recurrence-engine.ts +4 -1
  632. package/src/schedule/retry-backoff.ts +18 -0
  633. package/src/schedule/retry-policy.ts +82 -0
  634. package/src/schedule/run-script.ts +37 -5
  635. package/src/schedule/schedule-recovery.ts +64 -0
  636. package/src/schedule/schedule-store.ts +106 -2
  637. package/src/schedule/scheduler-types.ts +25 -0
  638. package/src/schedule/scheduler.ts +83 -39
  639. package/src/security/encrypted-store.ts +2 -0
  640. package/src/security/oauth-callback-registry.ts +8 -0
  641. package/src/security/secure-keys.ts +55 -0
  642. package/src/sequence/analytics.ts +5 -5
  643. package/src/sequence/engine.ts +1 -1
  644. package/src/skills/catalog-files.ts +2 -8
  645. package/src/skills/include-graph.ts +5 -5
  646. package/src/skills/remote-skill-policy.ts +10 -16
  647. package/src/skills/skill-file-provider.ts +1 -1
  648. package/src/skills/skill-file-types.ts +13 -0
  649. package/src/skills/skillssh-audit-types.ts +28 -0
  650. package/src/skills/skillssh-registry.ts +8 -21
  651. package/src/subagent/index.ts +1 -7
  652. package/src/subagent/manager.ts +1 -15
  653. package/src/tasks/task-runner.ts +0 -1
  654. package/src/tasks/task-store.ts +0 -3
  655. package/src/telemetry/types.ts +2 -0
  656. package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
  657. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  658. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  659. package/src/tools/apps/executors.ts +56 -69
  660. package/src/tools/background-tool-registry.ts +17 -3
  661. package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
  662. package/src/tools/browser/browser-execution.ts +2 -2
  663. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
  664. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  665. package/src/tools/browser/cdp-client/factory.ts +23 -24
  666. package/src/tools/browser/cdp-client/index.ts +1 -14
  667. package/src/tools/computer-use/definitions.ts +42 -20
  668. package/src/tools/executor.ts +2 -0
  669. package/src/tools/host-filesystem/edit.test.ts +151 -0
  670. package/src/tools/host-filesystem/edit.ts +68 -0
  671. package/src/tools/host-filesystem/read.test.ts +129 -0
  672. package/src/tools/host-filesystem/read.ts +68 -0
  673. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  674. package/src/tools/host-filesystem/transfer.ts +78 -3
  675. package/src/tools/host-filesystem/write.test.ts +134 -0
  676. package/src/tools/host-filesystem/write.ts +68 -0
  677. package/src/tools/host-terminal/host-shell.ts +66 -1
  678. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  679. package/src/tools/memory/register.test.ts +12 -9
  680. package/src/tools/memory/register.ts +1 -2
  681. package/src/tools/provider-tool-name.ts +28 -0
  682. package/src/tools/registry.ts +30 -9
  683. package/src/tools/schedule/create.ts +6 -0
  684. package/src/tools/schedule/list.ts +2 -0
  685. package/src/tools/schedule/update.ts +10 -0
  686. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  687. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  688. package/src/tools/skills/load.ts +0 -32
  689. package/src/tools/terminal/shell.ts +9 -1
  690. package/src/tools/tool-approval-handler.ts +32 -11
  691. package/src/tools/types.ts +28 -2
  692. package/src/tts/provider-catalog.ts +3 -5
  693. package/src/usage/pricing.ts +1 -1
  694. package/src/util/disk-usage.ts +138 -0
  695. package/src/util/platform.ts +21 -11
  696. package/src/util/process-liveness.ts +26 -0
  697. package/src/workspace/hatched-date.ts +86 -0
  698. package/src/workspace/heartbeat-service.ts +19 -0
  699. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  700. package/src/workspace/migrations/006-services-config.ts +8 -5
  701. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  702. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  703. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  704. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  705. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  706. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  707. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
  708. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  709. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
  710. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  711. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  712. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  713. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  714. package/src/workspace/migrations/AGENTS.md +1 -1
  715. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  716. package/src/workspace/migrations/registry.ts +8 -0
  717. package/src/workspace/migrations/utils.ts +21 -0
  718. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  719. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
  720. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
  721. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
  722. package/src/__tests__/twilio-rest.test.ts +0 -34
  723. package/src/backup/__tests__/backup-key.test.ts +0 -152
  724. package/src/backup/__tests__/backup-worker.test.ts +0 -782
  725. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  726. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  727. package/src/backup/backup-key.ts +0 -137
  728. package/src/backup/backup-worker.ts +0 -472
  729. package/src/backup/offsite-writer.ts +0 -222
  730. package/src/backup/stream-crypt.ts +0 -263
  731. package/src/daemon/message-types/pairing.ts +0 -58
  732. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  733. package/src/memory/v2/skill-qdrant.ts +0 -395
  734. package/src/outbound-proxy/config.ts +0 -20
  735. package/src/outbound-proxy/health.ts +0 -18
  736. package/src/outbound-proxy/types.ts +0 -150
  737. package/src/runtime/capability-tokens.ts +0 -190
  738. package/src/signals/bash.ts +0 -198
  739. package/src/signals/mcp-reload.ts +0 -18
@@ -1,116 +1,56 @@
1
1
  /**
2
- * High-level helpers for restoring and verifying backup snapshots produced
3
- * by the backup pipeline.
2
+ * High-level helpers for restoring and verifying backup snapshots.
4
3
  *
5
- * A snapshot is one of:
6
- * - A plaintext `.vbundle` file (gzipped tar see `vbundle-builder.ts`).
7
- * - An encrypted `.vbundle.enc` file produced by `stream-crypt.encryptFile`.
4
+ * Only plaintext `.vbundle` files are supported directly. Encrypted
5
+ * `.vbundle.enc` files must be restored through the gateway, which owns the
6
+ * backup encryption key (ATL-397).
8
7
  *
9
- * The encryption status is detected purely from the file extension:
10
- * - `.vbundle.enc` encrypted (decryption key required)
11
- * - `.vbundle` → plaintext
12
- *
13
- * For encrypted snapshots, this module decrypts to a temporary file under the
14
- * OS temp directory, runs validation, and then either commits the import or
15
- * just reports validation status. The temp file is always cleaned up — on
16
- * success and on failure — via a `try { ... } finally { unlink }` block.
17
- *
18
- * Restore is intentionally a thin wrapper around the existing
19
- * `commitImport` flow in `runtime/migrations/vbundle-importer.ts`. That
20
- * function handles bundle validation, workspace clearing, per-file
21
- * backup-before-overwrite, and writing files to disk.
8
+ * Restore is a thin wrapper around `commitImport` in
9
+ * `runtime/migrations/vbundle-importer.ts`, which handles bundle validation,
10
+ * workspace clearing, per-file backup-before-overwrite, and writing files.
22
11
  *
23
12
  * `restoreFromSnapshot` closes the live SQLite singleton via `resetDb()`
24
- * immediately before the commit step so the daemon's DB handle is released
25
- * before `assistant.db` is overwritten on disk. This mirrors the pattern in
26
- * `handleMigrationImport` and ensures both the HTTP restore path and any
27
- * in-process CLI caller get the reset for free. Tests can inject a fake via
28
- * `opts.resetDbImpl`.
29
- *
30
- * `commitImport` does NOT invalidate cached config. Callers are responsible
31
- * for calling `invalidateConfigCache()` AFTER a successful restore so the
32
- * daemon re-reads the restored `config.json` instead of serving stale
33
- * in-process caches. A daemon restart is the simplest recovery path.
13
+ * before the commit step so the daemon's DB handle is released before
14
+ * `assistant.db` is overwritten on disk.
34
15
  *
35
16
  * Credentials are intentionally excluded from backups — they live in the OS
36
- * keychain / CES and are not restored by this path. Users re-authenticate
37
- * integrations after a restore.
17
+ * keychain / CES and are not restored by this path.
38
18
  */
39
19
 
40
- import { randomUUID } from "node:crypto";
41
- import { readFile, unlink } from "node:fs/promises";
42
- import { tmpdir } from "node:os";
43
- import { join } from "node:path";
20
+ import { readFile } from "node:fs/promises";
44
21
 
45
22
  import { resetDb } from "../memory/db-connection.js";
46
23
  import type { PathResolver } from "../runtime/migrations/vbundle-import-analyzer.js";
24
+ import {
25
+ evaluateRuntimeCompatibility,
26
+ formatRuntimeCompatibilityMessage,
27
+ } from "../runtime/migrations/vbundle-import-policy.js";
47
28
  import { commitImport } from "../runtime/migrations/vbundle-importer.js";
48
29
  import type { ManifestType } from "../runtime/migrations/vbundle-validator.js";
49
30
  import { validateVBundle } from "../runtime/migrations/vbundle-validator.js";
50
- import { decryptFile } from "./stream-crypt.js";
31
+ import { APP_VERSION } from "../version.js";
51
32
 
52
33
  // ---------------------------------------------------------------------------
53
34
  // Public types
54
35
  // ---------------------------------------------------------------------------
55
36
 
56
- /**
57
- * Optional injection point for the underlying commit function. Tests pass a
58
- * fake here to avoid running the destructive `commitImport` flow against the
59
- * live workspace. Production callers should leave this unset so the real
60
- * importer is used.
61
- */
62
37
  type CommitImpl = typeof commitImport;
63
38
 
64
39
  interface RestoreOptions {
65
- /** AES-256 decryption key. Required for `.vbundle.enc` snapshots. */
66
- key?: Buffer;
67
- /**
68
- * Resolver that maps archive paths (e.g. `workspace/config.json`) to
69
- * absolute disk paths. Required by the underlying `commitImport` flow.
70
- */
71
40
  pathResolver: PathResolver;
72
- /**
73
- * Absolute path to the workspace directory. When set and the bundle
74
- * contains `workspace/` entries, `commitImport` clears the workspace
75
- * before writing to ensure an exact-match restore.
76
- */
77
41
  workspaceDir?: string;
78
- /**
79
- * Optional override for the underlying commit function. Tests inject a
80
- * fake to avoid mutating disk; production callers should leave this unset.
81
- */
82
42
  commitImpl?: CommitImpl;
83
- /**
84
- * Optional override for the DB-reset hook. Invoked immediately before
85
- * `commitImpl` so the live SQLite singleton is closed before
86
- * `assistant.db` is overwritten. Tests inject a spy; production callers
87
- * should leave this unset so the real `resetDb` is used.
88
- */
89
43
  resetDbImpl?: () => void;
90
44
  }
91
45
 
92
46
  export interface RestoreResult {
93
- /** Manifest from the bundle that was restored. */
94
47
  manifest: ManifestType;
95
- /** Number of files written (or skipped) by the underlying commit. */
96
48
  restoredFiles: number;
97
49
  }
98
50
 
99
- interface VerifyOptions {
100
- /** AES-256 decryption key. Required for `.vbundle.enc` snapshots. */
101
- key?: Buffer;
102
- }
103
-
104
51
  export interface VerifyResult {
105
- /** True iff the bundle decrypts (when applicable) and validates. */
106
52
  valid: boolean;
107
- /** Manifest from the bundle when `valid` is true. */
108
53
  manifest?: ManifestType;
109
- /**
110
- * Human-readable error message when `valid` is false. Populated for
111
- * validation failures, decryption failures, and missing-file errors.
112
- * Always undefined when `valid` is true.
113
- */
114
54
  error?: string;
115
55
  }
116
56
 
@@ -118,201 +58,137 @@ export interface VerifyResult {
118
58
  // Internal helpers
119
59
  // ---------------------------------------------------------------------------
120
60
 
121
- /** Returns true if the snapshot path indicates an encrypted bundle. */
122
61
  function isEncryptedSnapshot(snapshotPath: string): boolean {
123
62
  return snapshotPath.endsWith(".vbundle.enc");
124
63
  }
125
64
 
126
- /** Build a unique temp path for a decrypted bundle. */
127
- function makeDecryptedTempPath(): string {
128
- return join(tmpdir(), `vellum-restore-${randomUUID()}.vbundle`);
129
- }
130
-
131
- /**
132
- * Resolve `snapshotPath` to a path that holds plaintext `.vbundle` bytes.
133
- *
134
- * For plaintext snapshots, this just returns `{ path: snapshotPath }`. For
135
- * encrypted snapshots, it decrypts to a fresh temp file and returns
136
- * `{ path: tmpPath, tmpPath }` so the caller can clean up afterwards.
137
- *
138
- * Throws when an encrypted bundle has no key, when `decryptFile` fails
139
- * (bad key, tampered ciphertext, truncated file), or on any I/O error.
140
- */
141
- async function materializePlaintext(
142
- snapshotPath: string,
143
- key: Buffer | undefined,
144
- ): Promise<{ path: string; tmpPath: string | null }> {
145
- if (!isEncryptedSnapshot(snapshotPath)) {
146
- return { path: snapshotPath, tmpPath: null };
147
- }
148
-
149
- if (!key) {
150
- throw new Error("Encrypted snapshot requires a decryption key");
151
- }
152
-
153
- const tmpPath = makeDecryptedTempPath();
154
- await decryptFile(snapshotPath, tmpPath, key);
155
- return { path: tmpPath, tmpPath };
156
- }
157
-
158
- /** Best-effort temp file cleanup — swallows ENOENT and other errors. */
159
- async function safeUnlink(path: string | null): Promise<void> {
160
- if (!path) return;
161
- try {
162
- await unlink(path);
163
- } catch {
164
- // Best-effort — temp file may already be gone.
165
- }
166
- }
167
-
168
65
  // ---------------------------------------------------------------------------
169
66
  // Public API
170
67
  // ---------------------------------------------------------------------------
171
68
 
172
69
  /**
173
- * Restore a backup snapshot into the workspace.
174
- *
175
- * Auto-detects encryption from the file extension. Encrypted snapshots
176
- * (`.vbundle.enc`) decrypt to a temp file under `tmpdir()` before
177
- * validation; the temp file is unlinked in a `finally` block so it never
178
- * lingers, even on validation or commit failure.
70
+ * Restore a plaintext backup snapshot into the workspace.
179
71
  *
180
- * The actual restore is delegated to `commitImport`, which owns the
181
- * backup-before-overwrite, workspace-clearing, and integrity-check logic.
182
- * Tests can pass `opts.commitImpl` to substitute a fake without mutating
183
- * the live workspace.
72
+ * Encrypted `.vbundle.enc` snapshots are rejected use the gateway's
73
+ * restore endpoint for those.
184
74
  */
185
75
  export async function restoreFromSnapshot(
186
76
  snapshotPath: string,
187
77
  opts: RestoreOptions,
188
78
  ): Promise<RestoreResult> {
79
+ if (isEncryptedSnapshot(snapshotPath)) {
80
+ throw new Error(
81
+ "Encrypted snapshot restore must go through the gateway, which owns the backup key. " +
82
+ "Use the gateway's restore endpoint instead.",
83
+ );
84
+ }
85
+
189
86
  const {
190
- key,
191
87
  pathResolver,
192
88
  workspaceDir,
193
89
  commitImpl = commitImport,
194
90
  resetDbImpl = resetDb,
195
91
  } = opts;
196
92
 
197
- let tmpPath: string | null = null;
198
- try {
199
- const materialized = await materializePlaintext(snapshotPath, key);
200
- tmpPath = materialized.tmpPath;
201
-
202
- // Read plaintext bytes for validation + commit. validateVBundle takes
203
- // raw bytes (Uint8Array) — file paths are not part of its API.
204
- const fileData = await readFile(materialized.path);
93
+ const fileData = await readFile(snapshotPath);
205
94
 
206
- const validation = validateVBundle(fileData);
207
- if (!validation.is_valid || !validation.manifest || !validation.entries) {
208
- const summary = validation.errors
209
- .map((e) => `${e.code}: ${e.message}`)
210
- .join("; ");
211
- throw new Error(`Snapshot failed validation: ${summary}`);
212
- }
95
+ const validation = validateVBundle(fileData);
96
+ if (!validation.is_valid || !validation.manifest || !validation.entries) {
97
+ const summary = validation.errors
98
+ .map((e) => `${e.code}: ${e.message}`)
99
+ .join("; ");
100
+ throw new Error(`Snapshot failed validation: ${summary}`);
101
+ }
213
102
 
214
- // Close the live SQLite singleton before overwriting assistant.db on
215
- // disk otherwise the daemon keeps a handle to the old inode and
216
- // subsequent writes can corrupt the restored state. Mirrors the
217
- // pattern in `handleMigrationImport`. The singleton will be lazily
218
- // reopened on the next getDb() call.
219
- resetDbImpl();
103
+ // Pre-check runtime-version compat before the DB close/reopen cycle.
104
+ // commitImport runs the same gate as defense-in-depth for callers that
105
+ // don't pre-check; we run it here too so an incompatible bundle short-
106
+ // circuits before resetDbImpl().
107
+ const compatResult = evaluateRuntimeCompatibility(
108
+ validation.manifest.compatibility,
109
+ APP_VERSION,
110
+ );
111
+ if (!compatResult.ok) {
112
+ throw new Error(
113
+ `Snapshot restore failed: ${formatRuntimeCompatibilityMessage(
114
+ compatResult.bundle_compat,
115
+ compatResult.runtime_version,
116
+ )}`,
117
+ );
118
+ }
220
119
 
221
- const commitResult = commitImpl({
222
- archiveData: fileData,
223
- pathResolver,
224
- preValidatedManifest: validation.manifest,
225
- preValidatedEntries: validation.entries,
226
- workspaceDir,
227
- });
120
+ resetDbImpl();
228
121
 
229
- if (!commitResult.ok) {
230
- // Surface a single error message regardless of which discriminated
231
- // branch failed — callers in the backup CLI just want a message.
232
- let message: string;
233
- switch (commitResult.reason) {
234
- case "validation_failed":
235
- message = commitResult.errors
236
- .map((e) => `${e.code}: ${e.message}`)
237
- .join("; ");
238
- break;
239
- case "extraction_failed":
240
- case "write_failed":
241
- message = commitResult.message;
242
- break;
243
- }
244
- throw new Error(`Snapshot restore failed: ${message}`);
122
+ const commitResult = commitImpl({
123
+ archiveData: fileData,
124
+ pathResolver,
125
+ preValidatedManifest: validation.manifest,
126
+ preValidatedEntries: validation.entries,
127
+ workspaceDir,
128
+ });
129
+
130
+ if (!commitResult.ok) {
131
+ let message: string;
132
+ switch (commitResult.reason) {
133
+ case "validation_failed":
134
+ message = commitResult.errors
135
+ .map((e) => `${e.code}: ${e.message}`)
136
+ .join("; ");
137
+ break;
138
+ case "extraction_failed":
139
+ case "write_failed":
140
+ message = commitResult.message;
141
+ break;
142
+ case "version_incompatible":
143
+ message = formatRuntimeCompatibilityMessage(
144
+ commitResult.bundle_compat,
145
+ commitResult.runtime_version,
146
+ );
147
+ break;
245
148
  }
246
-
247
- return {
248
- manifest: commitResult.report.manifest,
249
- restoredFiles: commitResult.report.summary.total_files,
250
- };
251
- } finally {
252
- await safeUnlink(tmpPath);
149
+ throw new Error(`Snapshot restore failed: ${message}`);
253
150
  }
151
+
152
+ return {
153
+ manifest: commitResult.report.manifest,
154
+ restoredFiles: commitResult.report.summary.total_files,
155
+ };
254
156
  }
255
157
 
256
158
  /**
257
159
  * Verify a backup snapshot without restoring it.
258
160
  *
259
- * Auto-detects encryption from the file extension and decrypts to a temp
260
- * file when needed (cleaned up in a `finally` block). Runs the same
261
- * `validateVBundle` checks the importer would run, but never touches the
262
- * workspace.
263
- *
264
- * Does NOT throw on validation or decryption failure — those are returned
265
- * as `{ valid: false, error: ... }`. Only the missing-key precondition
266
- * for encrypted bundles throws, since that is a programmer error.
161
+ * Only plaintext `.vbundle` files are supported. Encrypted snapshots must be
162
+ * verified through the gateway.
267
163
  */
268
164
  export async function verifySnapshot(
269
165
  snapshotPath: string,
270
- opts: VerifyOptions,
271
166
  ): Promise<VerifyResult> {
272
- const { key } = opts;
273
-
274
- // Encrypted bundles must have a key — this is a precondition error,
275
- // not a validation failure, so we throw rather than return.
276
- if (isEncryptedSnapshot(snapshotPath) && !key) {
277
- throw new Error("Encrypted snapshot requires a decryption key");
167
+ if (isEncryptedSnapshot(snapshotPath)) {
168
+ return {
169
+ valid: false,
170
+ error:
171
+ "Encrypted snapshot verification must go through the gateway, which owns the backup key.",
172
+ };
278
173
  }
279
174
 
280
- let tmpPath: string | null = null;
175
+ let fileData: Uint8Array;
281
176
  try {
282
- let plaintextPath: string;
283
- try {
284
- const materialized = await materializePlaintext(snapshotPath, key);
285
- tmpPath = materialized.tmpPath;
286
- plaintextPath = materialized.path;
287
- } catch (err) {
288
- // Decryption / I/O failure — surface as a soft error so verification
289
- // callers (e.g. snapshot list health checks) get a uniform shape.
290
- return {
291
- valid: false,
292
- error: err instanceof Error ? err.message : String(err),
293
- };
294
- }
295
-
296
- let fileData: Uint8Array;
297
- try {
298
- fileData = await readFile(plaintextPath);
299
- } catch (err) {
300
- return {
301
- valid: false,
302
- error: err instanceof Error ? err.message : String(err),
303
- };
304
- }
305
-
306
- const validation = validateVBundle(fileData);
307
- if (!validation.is_valid || !validation.manifest) {
308
- const summary = validation.errors
309
- .map((e) => `${e.code}: ${e.message}`)
310
- .join("; ");
311
- return { valid: false, error: summary };
312
- }
177
+ fileData = await readFile(snapshotPath);
178
+ } catch (err) {
179
+ return {
180
+ valid: false,
181
+ error: err instanceof Error ? err.message : String(err),
182
+ };
183
+ }
313
184
 
314
- return { valid: true, manifest: validation.manifest };
315
- } finally {
316
- await safeUnlink(tmpPath);
185
+ const validation = validateVBundle(fileData);
186
+ if (!validation.is_valid || !validation.manifest) {
187
+ const summary = validation.errors
188
+ .map((e) => `${e.code}: ${e.message}`)
189
+ .join("; ");
190
+ return { valid: false, error: summary };
317
191
  }
192
+
193
+ return { valid: true, manifest: validation.manifest };
318
194
  }
@@ -32,10 +32,10 @@ import {
32
32
  writeSync,
33
33
  } from "node:fs";
34
34
  import { dirname, join } from "node:path";
35
- import { kill } from "node:process";
36
35
  import { setTimeout as sleep } from "node:timers/promises";
37
36
 
38
37
  import { getLogger } from "../util/logger.js";
38
+ import { isProcessAlive } from "../util/process-liveness.js";
39
39
  import { getLocalBackupsDir } from "./paths.js";
40
40
 
41
41
  const log = getLogger("snapshot-lock");
@@ -88,29 +88,6 @@ export function getSnapshotLockPath(): string {
88
88
  return join(dirname(getLocalBackupsDir()), ".snapshot.lock");
89
89
  }
90
90
 
91
- /**
92
- * Check whether a PID refers to a live process. Uses `kill(pid, 0)`, which
93
- * does not send any signal — it just probes for existence and permission.
94
- *
95
- * Returns `false` for obviously invalid PIDs (<= 0) and for any error that
96
- * indicates the process is gone. Returns `true` for ESRCH-negative results
97
- * (meaning a process exists) and for EPERM (process exists but is owned by
98
- * another user — still a live process, still should not be taken over).
99
- */
100
- function isProcessAlive(pid: number): boolean {
101
- if (!Number.isInteger(pid) || pid <= 0) return false;
102
- try {
103
- kill(pid, 0);
104
- return true;
105
- } catch (err) {
106
- const code = (err as NodeJS.ErrnoException).code;
107
- // EPERM means the PID exists but we cannot signal it — treat as alive so
108
- // we don't accidentally take over another user's lock.
109
- if (code === "EPERM") return true;
110
- return false;
111
- }
112
- }
113
-
114
91
  /**
115
92
  * Try to atomically create the lock file with mode `0o600` and the current
116
93
  * PID as its contents. Returns `true` on success, `false` if the file
@@ -348,9 +325,7 @@ export async function acquireSnapshotLock(
348
325
  }
349
326
 
350
327
  if (isProcessAlive(holder.pid)) {
351
- throw new Error(
352
- `snapshot in progress (locked by pid ${holder.pid})`,
353
- );
328
+ throw new Error(`snapshot in progress (locked by pid ${holder.pid})`);
354
329
  }
355
330
 
356
331
  // --- Step 3: stale takeover via rename-aside ---
@@ -17,6 +17,7 @@ import JSZip from "jszip";
17
17
  import { getApp, getAppDirPath, isMultifileApp } from "../memory/app-store.js";
18
18
  import { computeContentId } from "../util/content-id.js";
19
19
  import { getLogger } from "../util/logger.js";
20
+ import { APP_VERSION } from "../version.js";
20
21
  import { compileApp } from "./app-compiler.js";
21
22
  import type { SigningCallback } from "./bundle-signer.js";
22
23
  import { signBundle } from "./bundle-signer.js";
@@ -25,7 +26,6 @@ import { serializeManifest } from "./manifest.js";
25
26
 
26
27
  const bundlerLog = getLogger("app-bundler");
27
28
 
28
- import { APP_VERSION } from "../version.js";
29
29
  const PACKAGE_VERSION = APP_VERSION;
30
30
 
31
31
  const MAX_BUNDLE_SIZE_BYTES = 25 * 1024 * 1024; // 25 MB
@@ -37,6 +37,45 @@ export interface BundleResult {
37
37
  iconImageBase64?: string;
38
38
  }
39
39
 
40
+ function isDefaultMainScaffold(source: string): boolean {
41
+ const normalized = source.replace(/\s+/g, " ").trim();
42
+ return (
43
+ normalized.startsWith(
44
+ `import { render } from 'preact'; function App() { return <div>{"Hello, `,
45
+ ) &&
46
+ normalized.endsWith(
47
+ `!"}</div>; } render(<App />, document.getElementById('app')!);`,
48
+ )
49
+ );
50
+ }
51
+
52
+ function assertMultifileSourceReady(
53
+ app: { name: string },
54
+ appDir: string,
55
+ ): void {
56
+ const srcIndexPath = join(appDir, "src", "index.html");
57
+ const srcMainPath = join(appDir, "src", "main.tsx");
58
+ const missing = [
59
+ !existsSync(srcIndexPath) ? "src/index.html" : null,
60
+ !existsSync(srcMainPath) ? "src/main.tsx" : null,
61
+ ].filter((value): value is string => value !== null);
62
+
63
+ if (missing.length > 0) {
64
+ throw new Error(
65
+ `App "${app.name}" is a multi-file TSX app but is missing ${missing.join(
66
+ " and ",
67
+ )}. Write source files under src/ and call app_refresh before sharing.`,
68
+ );
69
+ }
70
+
71
+ const mainSource = readFileSync(srcMainPath, "utf-8");
72
+ if (isDefaultMainScaffold(mainSource)) {
73
+ throw new Error(
74
+ `App "${app.name}" still has the default src/main.tsx scaffold. Write the real multi-file TSX source and call app_refresh before sharing.`,
75
+ );
76
+ }
77
+ }
78
+
40
79
  /**
41
80
  * Package an app into a .vellum zip archive.
42
81
  *
@@ -82,6 +121,8 @@ export async function packageApp(
82
121
  const appDir = getAppDirPath(appId);
83
122
 
84
123
  if (multifile) {
124
+ assertMultifileSourceReady(app, appDir);
125
+
85
126
  // Multi-file TSX app: compile src/ -> dist/
86
127
  const compileResult = await compileApp(appDir);
87
128
  if (!compileResult.ok) {
@@ -97,8 +138,15 @@ export async function packageApp(
97
138
  }
98
139
 
99
140
  const distDir = join(appDir, "dist");
100
- const indexHtml = await readFile(join(distDir, "index.html"), "utf-8");
101
- const mainJs = await readFile(join(distDir, "main.js"));
141
+ const distIndexPath = join(distDir, "index.html");
142
+ const distMainPath = join(distDir, "main.js");
143
+ if (!existsSync(distIndexPath) || !existsSync(distMainPath)) {
144
+ throw new Error(
145
+ `Compilation for app "${app.name}" did not produce dist/index.html and dist/main.js. Check src/index.html and src/main.tsx, then call app_refresh.`,
146
+ );
147
+ }
148
+ const indexHtml = await readFile(distIndexPath, "utf-8");
149
+ const mainJs = await readFile(distMainPath);
102
150
 
103
151
  compiledFiles.push({ name: "index.html", data: Buffer.from(indexHtml) });
104
152
  compiledFiles.push({ name: "main.js", data: mainJs });
@@ -15,10 +15,11 @@ import {
15
15
  rmSync,
16
16
  writeFileSync,
17
17
  } from "node:fs";
18
- import { arch, homedir, platform } from "node:os";
18
+ import { arch, platform } from "node:os";
19
19
  import { join } from "node:path";
20
20
 
21
21
  import { getLogger } from "../util/logger.js";
22
+ import { getWorkspaceDir } from "../util/platform.js";
22
23
  import { PromiseGuard } from "../util/promise-guard.js";
23
24
 
24
25
  const log = getLogger("compiler-tools");
@@ -44,7 +45,7 @@ interface VersionManifest {
44
45
  }
45
46
 
46
47
  function getToolsDir(): string {
47
- return join(homedir(), ".vellum", "workspace", "compiler-tools");
48
+ return join(getWorkspaceDir(), "compiler-tools");
48
49
  }
49
50
 
50
51
  const installGuard = new PromiseGuard<void>();
@@ -6,6 +6,21 @@
6
6
  import { addMessage } from "../memory/conversation-crud.js";
7
7
  import { getCallEvents, getCallSession } from "./call-store.js";
8
8
 
9
+ function buildCallSummaryLabel(
10
+ status: string | undefined,
11
+ duration: number | null,
12
+ eventCount: number,
13
+ ): string {
14
+ const statusLabel =
15
+ status === "failed"
16
+ ? "Call failed"
17
+ : status === "cancelled"
18
+ ? "Call cancelled"
19
+ : "Call completed";
20
+ const durationStr = duration != null ? ` (${duration}s)` : "";
21
+ return `**${statusLabel}**${durationStr}. ${eventCount} event(s) recorded.`;
22
+ }
23
+
9
24
  export function buildCallCompletionMessage(callSessionId: string): string {
10
25
  const callSession = getCallSession(callSessionId);
11
26
  const events = getCallEvents(callSessionId);
@@ -13,25 +28,46 @@ export function buildCallCompletionMessage(callSessionId: string): string {
13
28
  callSession?.endedAt && callSession?.startedAt
14
29
  ? Math.round((callSession.endedAt - callSession.startedAt) / 1000)
15
30
  : null;
16
- const durationStr = duration != null ? ` (${duration}s)` : "";
17
- const statusLabel =
18
- callSession?.status === "failed"
19
- ? "Call failed"
20
- : callSession?.status === "cancelled"
21
- ? "Call cancelled"
22
- : "Call completed";
23
- return `**${statusLabel}**${durationStr}. ${events.length} event(s) recorded.`;
31
+ return buildCallSummaryLabel(callSession?.status, duration, events.length);
24
32
  }
25
33
 
26
34
  export async function persistCallCompletionMessage(
27
35
  conversationId: string,
28
36
  callSessionId: string,
29
37
  ): Promise<string> {
30
- const summaryText = buildCallCompletionMessage(callSessionId);
38
+ const callSession = getCallSession(callSessionId);
39
+ const events = getCallEvents(callSessionId);
40
+ const duration =
41
+ callSession?.endedAt && callSession?.startedAt
42
+ ? Math.round((callSession.endedAt - callSession.startedAt) / 1000)
43
+ : null;
44
+ const summaryText = buildCallSummaryLabel(
45
+ callSession?.status,
46
+ duration,
47
+ events.length,
48
+ );
49
+
31
50
  await addMessage(
32
51
  conversationId,
33
52
  "assistant",
34
- JSON.stringify([{ type: "text", text: summaryText }]),
53
+ JSON.stringify([
54
+ {
55
+ type: "ui_surface",
56
+ surfaceType: "call_summary",
57
+ surfaceId: crypto.randomUUID(),
58
+ completed: true,
59
+ data: {
60
+ summaryText,
61
+ status: callSession?.status ?? "completed",
62
+ duration,
63
+ events: events.map((e) => ({
64
+ eventType: e.eventType,
65
+ payloadJson: e.payloadJson,
66
+ createdAt: e.createdAt,
67
+ })),
68
+ },
69
+ },
70
+ ]),
35
71
  {
36
72
  userMessageChannel: "phone",
37
73
  assistantMessageChannel: "phone",