@vellumai/assistant 0.5.16 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. package/ARCHITECTURE.md +1 -1
  2. package/Dockerfile +0 -3
  3. package/knip.json +2 -1
  4. package/openapi.yaml +660 -80
  5. package/package.json +1 -1
  6. package/src/__tests__/actor-token-service.test.ts +68 -0
  7. package/src/__tests__/agent-loop.test.ts +0 -32
  8. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  9. package/src/__tests__/anthropic-provider.test.ts +57 -3
  10. package/src/__tests__/app-compiler.test.ts +120 -0
  11. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  12. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  13. package/src/__tests__/call-domain.test.ts +2 -6
  14. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  15. package/src/__tests__/call-recovery.test.ts +2 -6
  16. package/src/__tests__/call-routes-http.test.ts +2 -6
  17. package/src/__tests__/call-store.test.ts +2 -6
  18. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  19. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  20. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  21. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  22. package/src/__tests__/checker.test.ts +25 -3
  23. package/src/__tests__/clawhub.test.ts +54 -24
  24. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  25. package/src/__tests__/cli-memory.test.ts +74 -69
  26. package/src/__tests__/config-schema.test.ts +1 -1
  27. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  28. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  29. package/src/__tests__/contacts-tools.test.ts +31 -0
  30. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  31. package/src/__tests__/context-token-estimator.test.ts +175 -10
  32. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  33. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  34. package/src/__tests__/conversation-attachments.test.ts +2 -6
  35. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  36. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  37. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  38. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  39. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  40. package/src/__tests__/conversation-error.test.ts +33 -2
  41. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  42. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  43. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  44. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  45. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  46. package/src/__tests__/conversation-store.test.ts +2 -6
  47. package/src/__tests__/conversation-usage.test.ts +2 -6
  48. package/src/__tests__/conversation-wipe.test.ts +11 -408
  49. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  50. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  51. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  52. package/src/__tests__/followup-tools.test.ts +2 -6
  53. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  54. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  55. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  56. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  57. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  58. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  59. package/src/__tests__/guardian-action-store.test.ts +2 -6
  60. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  61. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  62. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  63. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  64. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  65. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  66. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  67. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  68. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  69. package/src/__tests__/injection-block.test.ts +154 -0
  70. package/src/__tests__/install-meta.test.ts +506 -0
  71. package/src/__tests__/install-skill-routing.test.ts +292 -0
  72. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  73. package/src/__tests__/invite-routes-http.test.ts +2 -6
  74. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  75. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  76. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  77. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  78. package/src/__tests__/llm-usage-store.test.ts +2 -6
  79. package/src/__tests__/log-export-workspace.test.ts +2 -6
  80. package/src/__tests__/managed-store.test.ts +38 -11
  81. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  82. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  83. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  84. package/src/__tests__/non-member-access-request.test.ts +2 -6
  85. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  86. package/src/__tests__/oauth-cli.test.ts +364 -2
  87. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  88. package/src/__tests__/outlook-attachments.test.ts +301 -0
  89. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  90. package/src/__tests__/outlook-categories.test.ts +212 -0
  91. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  92. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  93. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  94. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  95. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  96. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  97. package/src/__tests__/outlook-trash.test.ts +77 -0
  98. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  99. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  100. package/src/__tests__/playbook-execution.test.ts +76 -80
  101. package/src/__tests__/playbook-tools.test.ts +5 -7
  102. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  103. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  104. package/src/__tests__/registry.test.ts +2 -2
  105. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  106. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  107. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  108. package/src/__tests__/schedule-store.test.ts +2 -6
  109. package/src/__tests__/schedule-tools.test.ts +2 -6
  110. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  111. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  112. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  113. package/src/__tests__/search-skills-unified.test.ts +421 -0
  114. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  115. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  116. package/src/__tests__/sequence-store.test.ts +2 -6
  117. package/src/__tests__/server-history-render.test.ts +2 -6
  118. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  119. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  120. package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
  121. package/src/__tests__/skill-memory.test.ts +140 -98
  122. package/src/__tests__/skills-uninstall.test.ts +2 -2
  123. package/src/__tests__/skills.test.ts +1 -1
  124. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  125. package/src/__tests__/task-compiler.test.ts +2 -6
  126. package/src/__tests__/task-management-tools.test.ts +2 -6
  127. package/src/__tests__/task-memory-cleanup.test.ts +173 -229
  128. package/src/__tests__/task-runner.test.ts +2 -6
  129. package/src/__tests__/task-scheduler.test.ts +2 -6
  130. package/src/__tests__/test-preload.ts +3 -0
  131. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  132. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  133. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  134. package/src/__tests__/trust-store.test.ts +1 -1
  135. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  136. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
  137. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  138. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  139. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  140. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  141. package/src/__tests__/usage-routes.test.ts +2 -6
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  143. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  145. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  146. package/src/__tests__/volume-security-guard.test.ts +2 -0
  147. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  148. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  149. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  150. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  151. package/src/__tests__/workspace-policy.test.ts +1 -1
  152. package/src/agent/attachments.ts +7 -2
  153. package/src/agent/image-optimize.ts +165 -0
  154. package/src/agent/loop.ts +1 -15
  155. package/src/bundler/app-compiler.ts +179 -2
  156. package/src/bundler/package-resolver.ts +3 -5
  157. package/src/cli/__tests__/notifications.test.ts +1 -2
  158. package/src/cli/cli-memory.ts +67 -64
  159. package/src/cli/commands/avatar.ts +3 -3
  160. package/src/cli/commands/config.ts +26 -13
  161. package/src/cli/commands/doctor.ts +2 -2
  162. package/src/cli/commands/memory.ts +41 -55
  163. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  164. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  165. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  166. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  167. package/src/cli/commands/oauth/connect.ts +11 -6
  168. package/src/cli/commands/oauth/mode.ts +7 -0
  169. package/src/cli/commands/oauth/shared.ts +39 -3
  170. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  171. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  172. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  173. package/src/cli/commands/platform/index.ts +16 -16
  174. package/src/cli/commands/skills.ts +88 -16
  175. package/src/cli/commands/trust.ts +2 -2
  176. package/src/cli/lib/daemon-credential-client.ts +2 -3
  177. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  178. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  179. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  180. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  181. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  182. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  183. package/src/config/bundled-skills/messaging/SKILL.md +10 -18
  184. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  185. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  186. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  187. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  188. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  189. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  190. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  191. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  192. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  193. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  194. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  195. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  196. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  197. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  198. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  199. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  200. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  201. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  202. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  203. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  204. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  205. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  206. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  207. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  208. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  209. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  210. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  211. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  212. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  213. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  214. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  215. package/src/config/bundled-tool-registry.ts +56 -4
  216. package/src/config/env-registry.ts +15 -8
  217. package/src/config/feature-flag-registry.json +21 -124
  218. package/src/config/schemas/platform.ts +8 -0
  219. package/src/config/schemas/timeouts.ts +1 -1
  220. package/src/config/skills.ts +18 -7
  221. package/src/context/token-estimator.ts +25 -18
  222. package/src/context/window-manager.ts +6 -2
  223. package/src/credential-execution/process-manager.ts +3 -1
  224. package/src/daemon/context-overflow-reducer.ts +46 -2
  225. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  226. package/src/daemon/conversation-agent-loop.ts +96 -61
  227. package/src/daemon/conversation-error.ts +31 -8
  228. package/src/daemon/conversation-lifecycle.ts +33 -0
  229. package/src/daemon/conversation-media-retry.ts +85 -7
  230. package/src/daemon/conversation-notifiers.ts +4 -1
  231. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  232. package/src/daemon/conversation.ts +41 -2
  233. package/src/daemon/daemon-control.ts +8 -2
  234. package/src/daemon/handlers/shared.ts +22 -12
  235. package/src/daemon/handlers/skills.ts +416 -202
  236. package/src/daemon/lifecycle.ts +40 -1
  237. package/src/daemon/main.ts +5 -1
  238. package/src/daemon/message-types/conversations.ts +4 -1
  239. package/src/daemon/message-types/messages.ts +3 -1
  240. package/src/daemon/message-types/skills.ts +97 -36
  241. package/src/daemon/providers-setup.ts +5 -0
  242. package/src/daemon/server.ts +11 -2
  243. package/src/daemon/tool-side-effects.ts +27 -5
  244. package/src/heartbeat/heartbeat-service.ts +1 -0
  245. package/src/hooks/cli.ts +2 -2
  246. package/src/hooks/runner.ts +15 -38
  247. package/src/inbound/platform-callback-registration.ts +14 -14
  248. package/src/memory/admin.ts +11 -45
  249. package/src/memory/conversation-bootstrap.ts +2 -0
  250. package/src/memory/conversation-crud.ts +242 -348
  251. package/src/memory/conversation-group-migration.ts +157 -0
  252. package/src/memory/conversation-queries.ts +4 -2
  253. package/src/memory/db-init.ts +30 -3
  254. package/src/memory/embed.ts +73 -0
  255. package/src/memory/embedding-backend.ts +8 -14
  256. package/src/memory/embedding-runtime-manager.ts +12 -114
  257. package/src/memory/fingerprint.ts +2 -2
  258. package/src/memory/graph/bootstrap.ts +512 -0
  259. package/src/memory/graph/capability-seed.ts +297 -0
  260. package/src/memory/graph/consolidation.ts +691 -0
  261. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  262. package/src/memory/graph/decay.test.ts +208 -0
  263. package/src/memory/graph/decay.ts +195 -0
  264. package/src/memory/graph/extraction-job.ts +69 -0
  265. package/src/memory/graph/extraction.test.ts +936 -0
  266. package/src/memory/graph/extraction.ts +1254 -0
  267. package/src/memory/graph/graph-search.ts +266 -0
  268. package/src/memory/graph/image-ref-utils.ts +29 -0
  269. package/src/memory/graph/injection.test.ts +513 -0
  270. package/src/memory/graph/injection.ts +439 -0
  271. package/src/memory/graph/inspect.ts +534 -0
  272. package/src/memory/graph/narrative.ts +267 -0
  273. package/src/memory/graph/pattern-scan.ts +269 -0
  274. package/src/memory/graph/retriever.ts +1008 -0
  275. package/src/memory/graph/scoring.test.ts +548 -0
  276. package/src/memory/graph/scoring.ts +232 -0
  277. package/src/memory/graph/serendipity.ts +65 -0
  278. package/src/memory/graph/store.test.ts +1050 -0
  279. package/src/memory/graph/store.ts +699 -0
  280. package/src/memory/graph/tool-handlers.ts +426 -0
  281. package/src/memory/graph/tools.ts +141 -0
  282. package/src/memory/graph/triggers.test.ts +487 -0
  283. package/src/memory/graph/triggers.ts +223 -0
  284. package/src/memory/graph/types.ts +271 -0
  285. package/src/memory/group-crud.ts +191 -0
  286. package/src/memory/indexer.ts +37 -19
  287. package/src/memory/job-handlers/cleanup.ts +0 -53
  288. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  289. package/src/memory/job-handlers/embedding.ts +5 -31
  290. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  291. package/src/memory/job-handlers/summarization.ts +32 -17
  292. package/src/memory/job-utils.ts +1 -1
  293. package/src/memory/jobs-store.ts +50 -70
  294. package/src/memory/jobs-worker.ts +147 -112
  295. package/src/memory/message-content.ts +1 -0
  296. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  297. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  298. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  299. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  300. package/src/memory/migrations/index.ts +4 -0
  301. package/src/memory/migrations/registry.ts +8 -0
  302. package/src/memory/qdrant-client.ts +44 -17
  303. package/src/memory/schema/index.ts +1 -0
  304. package/src/memory/schema/memory-graph.ts +139 -0
  305. package/src/memory/search/semantic.ts +47 -91
  306. package/src/memory/task-memory-cleanup.ts +28 -50
  307. package/src/messaging/providers/outlook/adapter.ts +8 -1
  308. package/src/messaging/providers/outlook/client.ts +299 -0
  309. package/src/messaging/providers/outlook/types.ts +118 -0
  310. package/src/notifications/adapters/macos.ts +1 -0
  311. package/src/notifications/copy-composer.ts +9 -0
  312. package/src/notifications/signal.ts +16 -0
  313. package/src/oauth/seed-providers.ts +2 -1
  314. package/src/permissions/checker.ts +24 -3
  315. package/src/permissions/defaults.ts +4 -4
  316. package/src/permissions/workspace-policy.ts +1 -1
  317. package/src/playbooks/playbook-compiler.ts +19 -18
  318. package/src/playbooks/types.ts +4 -3
  319. package/src/prompts/system-prompt.ts +3 -29
  320. package/src/providers/anthropic/client.ts +47 -19
  321. package/src/providers/gemini/client.ts +1 -1
  322. package/src/providers/openai/client.ts +1 -1
  323. package/src/providers/registry.ts +1 -1
  324. package/src/providers/retry.ts +19 -3
  325. package/src/runtime/actor-trust-resolver.ts +5 -1
  326. package/src/runtime/auth/route-policy.ts +7 -0
  327. package/src/runtime/guardian-reply-router.ts +5 -1
  328. package/src/runtime/http-server.ts +23 -3
  329. package/src/runtime/middleware/auth.ts +20 -0
  330. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  331. package/src/runtime/routes/attachment-routes.ts +106 -16
  332. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  333. package/src/runtime/routes/btw-routes.ts +8 -0
  334. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  335. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  336. package/src/runtime/routes/debug-routes.ts +1 -1
  337. package/src/runtime/routes/global-search-routes.ts +21 -19
  338. package/src/runtime/routes/group-routes.ts +207 -0
  339. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  340. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  341. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  342. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  343. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  344. package/src/runtime/routes/memory-item-routes.test.ts +2 -14
  345. package/src/runtime/routes/memory-item-routes.ts +341 -388
  346. package/src/runtime/routes/schedule-routes.ts +2 -0
  347. package/src/runtime/routes/skills-routes.ts +103 -37
  348. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  349. package/src/schedule/scheduler.ts +8 -1
  350. package/src/security/oauth2.ts +1 -1
  351. package/src/security/secure-keys.ts +4 -8
  352. package/src/shared/provider-env-vars.ts +19 -0
  353. package/src/skills/catalog-cache.ts +5 -0
  354. package/src/skills/catalog-install.ts +15 -14
  355. package/src/skills/clawhub.ts +134 -154
  356. package/src/skills/install-meta.ts +208 -0
  357. package/src/skills/managed-store.ts +27 -16
  358. package/src/skills/skill-memory.ts +152 -77
  359. package/src/skills/skillssh-registry.ts +19 -17
  360. package/src/tasks/task-runner.ts +3 -1
  361. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  362. package/src/tools/browser/runtime-check.ts +3 -1
  363. package/src/tools/memory/register.ts +63 -46
  364. package/src/tools/permission-checker.ts +7 -1
  365. package/src/tools/shared/filesystem/image-read.ts +22 -85
  366. package/src/tools/terminal/safe-env.ts +1 -0
  367. package/src/tools/tool-manifest.ts +3 -3
  368. package/src/util/browser.ts +25 -10
  369. package/src/util/bun-runtime.ts +172 -0
  370. package/src/watcher/providers/outlook-calendar.ts +343 -0
  371. package/src/watcher/providers/outlook.ts +198 -0
  372. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  373. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  374. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  375. package/src/workspace/migrations/registry.ts +6 -0
  376. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  377. package/src/__tests__/journal-context.test.ts +0 -268
  378. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  379. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  380. package/src/__tests__/memory-query-builder.test.ts +0 -59
  381. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  382. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  383. package/src/__tests__/memory-regressions.test.ts +0 -3696
  384. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  385. package/src/daemon/conversation-memory.ts +0 -207
  386. package/src/memory/conversation-starters-cadence.ts +0 -74
  387. package/src/memory/items-extractor.ts +0 -860
  388. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  389. package/src/memory/job-handlers/extraction.ts +0 -40
  390. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  391. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  392. package/src/memory/journal-memory.ts +0 -224
  393. package/src/memory/query-builder.ts +0 -47
  394. package/src/memory/query-expansion.ts +0 -83
  395. package/src/memory/retriever.test.ts +0 -1592
  396. package/src/memory/retriever.ts +0 -1331
  397. package/src/memory/search/formatting.test.ts +0 -140
  398. package/src/memory/search/formatting.ts +0 -262
  399. package/src/memory/search/mmr.ts +0 -139
  400. package/src/memory/search/ranking.ts +0 -15
  401. package/src/memory/search/staleness.ts +0 -40
  402. package/src/memory/search/tier-classifier.ts +0 -18
  403. package/src/memory/search/types.ts +0 -121
  404. package/src/prompts/journal-context.ts +0 -154
  405. package/src/tools/memory/definitions.ts +0 -69
  406. package/src/tools/memory/handlers.test.ts +0 -562
  407. package/src/tools/memory/handlers.ts +0 -434
@@ -82,7 +82,10 @@ import {
82
82
  setCesClient,
83
83
  setCesReconnect,
84
84
  } from "../security/secure-keys.js";
85
- import { seedCatalogSkillMemories } from "../skills/skill-memory.js";
85
+ import {
86
+ seedCatalogSkillMemories,
87
+ seedUninstalledCatalogSkillMemories,
88
+ } from "../skills/skill-memory.js";
86
89
  import { UsageTelemetryReporter } from "../telemetry/usage-telemetry-reporter.js";
87
90
  import { getDeviceId } from "../util/device-id.js";
88
91
  import { getLogger, initLogger } from "../util/logger.js";
@@ -650,11 +653,47 @@ export async function runDaemon(): Promise<void> {
650
653
  log.warn({ err }, "Catalog skill memory seeding failed — continuing");
651
654
  }
652
655
 
656
+ // Seed memories for catalog skills not yet installed so they're
657
+ // discoverable via memory injection and can be auto-installed.
658
+ void seedUninstalledCatalogSkillMemories().catch((err) =>
659
+ log.warn(
660
+ { err },
661
+ "Uninstalled catalog skill memory seeding failed — continuing",
662
+ ),
663
+ );
664
+
653
665
  try {
654
666
  seedCliCommandMemories();
655
667
  } catch (err) {
656
668
  log.warn({ err }, "CLI command memory seeding failed — continuing");
657
669
  }
670
+
671
+ // Seed capability graph nodes (new memory graph system)
672
+ try {
673
+ const { seedSkillGraphNodes, seedCliGraphNodes } =
674
+ await import("../memory/graph/capability-seed.js");
675
+ seedSkillGraphNodes();
676
+ seedCliGraphNodes();
677
+ } catch (err) {
678
+ log.warn({ err }, "Graph capability seeding failed — continuing");
679
+ }
680
+
681
+ // Auto-bootstrap: if the graph has no non-procedural nodes but historical
682
+ // segments exist, enqueue a one-time graph_bootstrap job to populate the
683
+ // graph from conversation history and journal files.
684
+ try {
685
+ const {
686
+ maybeEnqueueGraphBootstrap,
687
+ cleanupStaleItemVectors,
688
+ } = await import("../memory/graph/bootstrap.js");
689
+ maybeEnqueueGraphBootstrap();
690
+ // Fire-and-forget: clean up orphaned Qdrant vectors from dropped memory_items table
691
+ void cleanupStaleItemVectors().catch((err) =>
692
+ log.warn({ err }, "Stale item vector cleanup failed — continuing"),
693
+ );
694
+ } catch (err) {
695
+ log.warn({ err }, "Graph bootstrap check failed — continuing");
696
+ }
658
697
  }
659
698
 
660
699
  // Fire-and-forget: Qdrant init runs concurrently with the rest of startup
@@ -1,9 +1,13 @@
1
1
  #!/usr/bin/env bun
2
2
  process.title = "vellum-daemon";
3
3
 
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+
4
7
  import * as Sentry from "@sentry/node";
5
8
 
6
9
  import { getLogger } from "../util/logger.js";
10
+ import { getDataDir } from "../util/platform.js";
7
11
  import { runDaemon } from "./lifecycle.js";
8
12
  import { emitDaemonError } from "./startup-error.js";
9
13
 
@@ -21,7 +25,7 @@ runDaemon().catch(async (err) => {
21
25
  }
22
26
  console.error("Failed to start assistant:", err);
23
27
  console.error(
24
- "Troubleshooting: check if another assistant is already running, verify ~/.vellum/ permissions, and review logs at ~/.vellum/workspace/data/logs/",
28
+ `Troubleshooting: check if another assistant is already running, verify ${join(homedir(), ".vellum")} permissions, and review logs at ${getDataDir()}/logs/`,
25
29
  );
26
30
  // Emit a structured error line as the last line of stderr so consumers
27
31
  // (e.g. the macOS app) can parse it reliably.
@@ -264,8 +264,10 @@ export interface HistoryResponseToolCall {
264
264
  input: Record<string, unknown>;
265
265
  result?: string;
266
266
  isError?: boolean;
267
- /** Base64-encoded image data from tool contentBlocks (e.g. browser_screenshot). */
267
+ /** Base64-encoded image data from tool contentBlocks (e.g. browser_screenshot). @deprecated Use imageDataList. */
268
268
  imageData?: string;
269
+ /** Base64-encoded image data from tool contentBlocks (e.g. browser_screenshot, image generation). */
270
+ imageDataList?: string[];
269
271
  /** Unix ms when the tool started executing. */
270
272
  startedAt?: number;
271
273
  /** Unix ms when the tool completed. */
@@ -370,6 +372,7 @@ export interface ContextCompacted {
370
372
  export type ConversationErrorCode =
371
373
  | "PROVIDER_NETWORK"
372
374
  | "PROVIDER_RATE_LIMIT"
375
+ | "PROVIDER_OVERLOADED"
373
376
  | "PROVIDER_API"
374
377
  | "PROVIDER_BILLING"
375
378
  | "PROVIDER_ORDERING"
@@ -124,8 +124,10 @@ export interface ToolResult {
124
124
  };
125
125
  status?: string;
126
126
  conversationId?: string;
127
- /** Base64-encoded image data extracted from contentBlocks (e.g. browser_screenshot). */
127
+ /** Base64-encoded image data extracted from contentBlocks (e.g. browser_screenshot). @deprecated Use imageDataList. */
128
128
  imageData?: string;
129
+ /** Base64-encoded image data extracted from contentBlocks (e.g. browser_screenshot, image generation). */
130
+ imageDataList?: string[];
129
131
  /** The tool_use block ID for client-side correlation. */
130
132
  toolUseId?: string;
131
133
  }
@@ -76,33 +76,50 @@ export interface SkillsCreateRequest {
76
76
 
77
77
  // === Server → Client ===
78
78
 
79
+ /** Fields shared by all skill origins. */
80
+ interface SlimSkillBase {
81
+ id: string;
82
+ name: string;
83
+ description: string;
84
+ emoji?: string;
85
+ kind: "bundled" | "installed" | "catalog";
86
+ status: "enabled" | "disabled" | "available";
87
+ }
88
+
89
+ interface VellumSlimSkill extends SlimSkillBase {
90
+ origin: "vellum";
91
+ }
92
+
93
+ interface ClawhubSlimSkill extends SlimSkillBase {
94
+ origin: "clawhub";
95
+ slug: string;
96
+ author: string;
97
+ stars: number;
98
+ installs: number;
99
+ reports: number;
100
+ publishedAt?: string;
101
+ }
102
+
103
+ interface SkillsshSlimSkill extends SlimSkillBase {
104
+ origin: "skillssh";
105
+ slug: string;
106
+ sourceRepo: string;
107
+ installs: number;
108
+ }
109
+
110
+ interface CustomSlimSkill extends SlimSkillBase {
111
+ origin: "custom";
112
+ }
113
+
114
+ export type SlimSkillResponse =
115
+ | VellumSlimSkill
116
+ | ClawhubSlimSkill
117
+ | SkillsshSlimSkill
118
+ | CustomSlimSkill;
119
+
79
120
  export interface SkillsListResponse {
80
121
  type: "skills_list_response";
81
- skills: Array<{
82
- id: string;
83
- name: string;
84
- description: string;
85
- emoji?: string;
86
- homepage?: string;
87
- source: "bundled" | "managed" | "workspace" | "clawhub" | "extra";
88
- state: "enabled" | "disabled";
89
- installedVersion?: string;
90
- latestVersion?: string;
91
- updateAvailable: boolean;
92
- clawhub?: {
93
- author: string;
94
- stars: number;
95
- installs: number;
96
- reports: number;
97
- publishedAt: string;
98
- };
99
- provenance?: {
100
- kind: "first-party" | "third-party" | "local";
101
- provider?: string;
102
- originId?: string;
103
- sourceUrl?: string;
104
- };
105
- }>;
122
+ skills: SlimSkillResponse[];
106
123
  }
107
124
 
108
125
  export interface SkillStateChanged {
@@ -111,15 +128,7 @@ export interface SkillStateChanged {
111
128
  state: "enabled" | "disabled" | "installed" | "uninstalled";
112
129
  }
113
130
 
114
- export interface SkillsOperationResponse {
115
- type: "skills_operation_response";
116
- operation: string;
117
- success: boolean;
118
- error?: string;
119
- data?: unknown;
120
- }
121
-
122
- export interface SkillDetailResponse {
131
+ export interface SkillBodyResponse {
123
132
  type: "skill_detail_response";
124
133
  skillId: string;
125
134
  body: string;
@@ -127,6 +136,59 @@ export interface SkillDetailResponse {
127
136
  error?: string;
128
137
  }
129
138
 
139
+ // ─── Detail endpoint response (HTTP API) ──────────────────────────────────
140
+
141
+ interface SkillDetailBase {
142
+ id: string;
143
+ name: string;
144
+ description: string;
145
+ emoji?: string;
146
+ kind: "bundled" | "installed" | "catalog";
147
+ status: "enabled" | "disabled" | "available";
148
+ }
149
+
150
+ interface VellumSkillDetail extends SkillDetailBase {
151
+ origin: "vellum";
152
+ }
153
+
154
+ interface ClawhubSkillDetail extends SkillDetailBase {
155
+ origin: "clawhub";
156
+ slug: string;
157
+ author: string;
158
+ stars: number;
159
+ installs: number;
160
+ reports: number;
161
+ publishedAt?: string;
162
+ // Enrichment fields (from clawhubInspect):
163
+ owner?: { handle: string; displayName: string; image?: string } | null;
164
+ stats?: {
165
+ stars: number;
166
+ installs: number;
167
+ downloads: number;
168
+ versions: number;
169
+ } | null;
170
+ latestVersion?: { version: string; changelog?: string } | null;
171
+ createdAt?: number | null;
172
+ updatedAt?: number | null;
173
+ }
174
+
175
+ interface SkillsshSkillDetail extends SkillDetailBase {
176
+ origin: "skillssh";
177
+ slug: string;
178
+ sourceRepo: string;
179
+ installs: number;
180
+ }
181
+
182
+ interface CustomSkillDetail extends SkillDetailBase {
183
+ origin: "custom";
184
+ }
185
+
186
+ export type SkillDetailResponse =
187
+ | VellumSkillDetail
188
+ | ClawhubSkillDetail
189
+ | SkillsshSkillDetail
190
+ | CustomSkillDetail;
191
+
130
192
  export interface SkillsDraftResponse {
131
193
  type: "skills_draft_response";
132
194
  success: boolean;
@@ -181,8 +243,7 @@ export type _SkillsClientMessages =
181
243
 
182
244
  export type _SkillsServerMessages =
183
245
  | SkillsListResponse
184
- | SkillDetailResponse
246
+ | SkillBodyResponse
185
247
  | SkillStateChanged
186
- | SkillsOperationResponse
187
248
  | SkillsInspectResponse
188
249
  | SkillsDraftResponse;
@@ -25,6 +25,8 @@ import { githubProvider } from "../watcher/providers/github.js";
25
25
  import { gmailProvider } from "../watcher/providers/gmail.js";
26
26
  import { googleCalendarProvider } from "../watcher/providers/google-calendar.js";
27
27
  import { linearProvider } from "../watcher/providers/linear.js";
28
+ import { outlookProvider } from "../watcher/providers/outlook.js";
29
+ import { outlookCalendarProvider } from "../watcher/providers/outlook-calendar.js";
28
30
  const log = getLogger("lifecycle");
29
31
 
30
32
  export async function initializeProvidersAndTools(
@@ -135,6 +137,9 @@ export function registerWatcherProviders(): void {
135
137
  registerWatcherProvider(googleCalendarProvider);
136
138
  registerWatcherProvider(githubProvider);
137
139
  registerWatcherProvider(linearProvider);
140
+ registerWatcherProvider(outlookProvider);
141
+ registerWatcherProvider(outlookCalendarProvider);
142
+
138
143
  initWatcherEngine();
139
144
  }
140
145
 
@@ -625,9 +625,18 @@ export class DaemonServer {
625
625
  if (conversation.isProcessing()) {
626
626
  // Hydrate file data now — the queue path won't re-read from
627
627
  // the attachment store, so base64 content must be inline.
628
- for (const att of resolvedAttachments) {
628
+ for (let i = resolvedAttachments.length - 1; i >= 0; i--) {
629
+ const att = resolvedAttachments[i];
629
630
  if (att.filePath && !att.data) {
630
- att.data = readFileSync(att.filePath).toString("base64");
631
+ try {
632
+ att.data = readFileSync(att.filePath).toString("base64");
633
+ } catch (err) {
634
+ log.warn(
635
+ { err, path: att.filePath },
636
+ "Failed to read queued signal attachment, skipping",
637
+ );
638
+ resolvedAttachments.splice(i, 1);
639
+ }
631
640
  }
632
641
  }
633
642
  const requestId = crypto.randomUUID();
@@ -10,6 +10,7 @@
10
10
  import { compileApp } from "../bundler/app-compiler.js";
11
11
  import { generateAppIcon } from "../media/app-icon-generator.js";
12
12
  import { getApp, getAppDirPath, isMultifileApp } from "../memory/app-store.js";
13
+ import { findActiveSession } from "../runtime/channel-verification-service.js";
13
14
  import { deliverVerificationSlack } from "../runtime/verification-outbound-actions.js";
14
15
  import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
15
16
  import type { ToolExecutionResult } from "../tools/types.js";
@@ -222,18 +223,39 @@ registerHook("bash", (_name, input, result) => {
222
223
  type PendingDm = { userId: string; text: string; assistantId: string };
223
224
  type Parsed = { _pendingSlackDm?: PendingDm };
224
225
 
225
- const dispatch = (parsed: Parsed) => {
226
+ // Returns "delivered" when DM was sent, "rejected" when _pendingSlackDm
227
+ // was found but failed validation, or null when the field was absent.
228
+ const dispatch = (parsed: Parsed): "delivered" | "rejected" | null => {
226
229
  if (parsed._pendingSlackDm) {
227
230
  const { userId, text, assistantId } = parsed._pendingSlackDm;
231
+
232
+ // Validate that an active Slack verification session exists and
233
+ // that the destination matches the userId in the parsed payload.
234
+ const session = findActiveSession("slack");
235
+ if (!session) {
236
+ log.warn(
237
+ { userId, assistantId },
238
+ "Bash hook: no active Slack verification session — ignoring _pendingSlackDm",
239
+ );
240
+ return "rejected";
241
+ }
242
+ if (session.destinationAddress !== userId) {
243
+ log.warn(
244
+ { userId, expected: session.destinationAddress, assistantId },
245
+ "Bash hook: Slack DM userId does not match active session destination — ignoring",
246
+ );
247
+ return "rejected";
248
+ }
249
+
228
250
  deliverVerificationSlack(userId, text, assistantId);
229
- return true;
251
+ return "delivered";
230
252
  }
231
- return false;
253
+ return null;
232
254
  };
233
255
 
234
256
  // Try full content first (handles pretty-printed single-object JSON)
235
257
  try {
236
- if (dispatch(JSON.parse(result.content.trim()) as Parsed)) return;
258
+ if (dispatch(JSON.parse(result.content.trim()) as Parsed) !== null) return;
237
259
  } catch {
238
260
  // Not a single JSON object — fall back to line-by-line for
239
261
  // multi-object output (e.g. cancel + create chained with &&).
@@ -242,7 +264,7 @@ registerHook("bash", (_name, input, result) => {
242
264
  const trimmed = line.trim();
243
265
  if (!trimmed.startsWith("{")) continue;
244
266
  try {
245
- if (dispatch(JSON.parse(trimmed) as Parsed)) return;
267
+ if (dispatch(JSON.parse(trimmed) as Parsed) === "delivered") return;
246
268
  } catch {
247
269
  continue;
248
270
  }
@@ -178,6 +178,7 @@ export class HeartbeatService {
178
178
  const conversation = bootstrapConversation({
179
179
  conversationType: "background",
180
180
  source: "heartbeat",
181
+ groupId: "system:background",
181
182
  origin: "heartbeat",
182
183
  systemHint: "Heartbeat",
183
184
  });
package/src/hooks/cli.ts CHANGED
@@ -20,7 +20,7 @@ export function registerHooksCommand(program: Command): void {
20
20
  Hooks are user-installed scripts that run in response to assistant lifecycle
21
21
  events (e.g. tool invocations, message sends). Each hook is a directory
22
22
  containing a hook.json manifest and a script file. Hooks are stored in
23
- ~/.vellum/hooks/ and must be explicitly enabled after installation.
23
+ $VELLUM_WORKSPACE_DIR/hooks/ and must be explicitly enabled after installation.
24
24
 
25
25
  Examples:
26
26
  $ assistant hooks list
@@ -136,7 +136,7 @@ Arguments:
136
136
  The manifest must have name, script, description, version, and at
137
137
  least one valid event.
138
138
 
139
- Copies the hook directory into ~/.vellum/hooks/<name>/ and registers it as
139
+ Copies the hook directory into $VELLUM_WORKSPACE_DIR/hooks/<name>/ and registers it as
140
140
  disabled by default. Run 'assistant hooks enable <name>' to activate.
141
141
 
142
142
  Examples:
@@ -1,42 +1,19 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { homedir } from "node:os";
3
- import { basename, extname, join } from "node:path";
3
+ import { extname, join } from "node:path";
4
4
 
5
- import { pathExists } from "../util/fs.js";
5
+ import { ensureBun } from "../util/bun-runtime.js";
6
6
  import { getWorkspaceDir } from "../util/platform.js";
7
7
  import { getHookSettings } from "./config.js";
8
8
  import type { DiscoveredHook, HookEventData } from "./types.js";
9
9
 
10
- /**
11
- * Resolve a usable bun runtime path. When the daemon runs under plain bun
12
- * (dev mode), `process.execPath` is the bun CLI and works directly. When the
13
- * daemon is a `bun build --compile` binary, `process.execPath` points to the
14
- * compiled binary itself -- spawning it with `['run', script]` would re-launch
15
- * the daemon. In that case we locate bun via PATH or at `~/.bun/bin/bun`.
16
- */
17
- function resolveBunPath(): string {
18
- const execBasename = basename(process.execPath);
19
- if (execBasename === "bun" || execBasename === "bun.exe") {
20
- return process.execPath;
21
- }
22
-
23
- // Compiled-binary mode -- find a standalone bun runtime.
24
- const found = Bun.which("bun");
25
- if (found) return found;
26
-
27
- const fallback = join(homedir(), ".bun", "bin", "bun");
28
- if (pathExists(fallback)) return fallback;
29
-
30
- throw new Error(
31
- "Cannot find a bun runtime to execute .ts hooks. " +
32
- "Install bun (https://bun.sh) or ensure it is on your PATH.",
33
- );
34
- }
35
-
36
- function getSpawnArgs(scriptPath: string): { command: string; args: string[] } {
10
+ async function getSpawnArgs(
11
+ scriptPath: string,
12
+ ): Promise<{ command: string; args: string[] }> {
37
13
  const ext = extname(scriptPath);
38
14
  if (ext === ".ts") {
39
- return { command: resolveBunPath(), args: ["run", scriptPath] };
15
+ const bunPath = await ensureBun();
16
+ return { command: bunPath, args: ["run", scriptPath] };
40
17
  }
41
18
  return { command: scriptPath, args: [] };
42
19
  }
@@ -54,15 +31,15 @@ export async function runHookScript(
54
31
  ): Promise<HookRunResult> {
55
32
  const timeoutMs = options?.timeoutMs ?? 5000;
56
33
 
34
+ let spawnResult: { command: string; args: string[] };
35
+ try {
36
+ spawnResult = await getSpawnArgs(hook.scriptPath);
37
+ } catch (err) {
38
+ return { exitCode: null, stdout: "", stderr: (err as Error).message };
39
+ }
40
+ const { command, args } = spawnResult;
41
+
57
42
  return new Promise<HookRunResult>((resolve) => {
58
- let spawnResult: { command: string; args: string[] };
59
- try {
60
- spawnResult = getSpawnArgs(hook.scriptPath);
61
- } catch (err) {
62
- resolve({ exitCode: null, stdout: "", stderr: (err as Error).message });
63
- return;
64
- }
65
- const { command, args } = spawnResult;
66
43
  const child = spawn(command, args, {
67
44
  cwd: hook.dir,
68
45
  env: {
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Platform callback route registration for containerized deployments.
2
+ * Platform callback route registration for platform-managed deployments.
3
3
  *
4
- * When the assistant daemon runs inside a container (IS_CONTAINERIZED=true)
4
+ * When the assistant daemon runs as a platform-managed instance (IS_PLATFORM=true)
5
5
  * with a configured VELLUM_PLATFORM_URL and PLATFORM_ASSISTANT_ID, external
6
6
  * service callbacks (Twilio webhooks, OAuth redirects, Telegram webhooks, etc.)
7
7
  * must route through the platform's gateway proxy instead of hitting the
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * This module registers callback routes with the platform's internal
11
11
  * gateway endpoint so the platform knows how to forward inbound provider
12
- * webhooks to the correct containerized assistant instance.
12
+ * webhooks to the correct platform-managed assistant instance.
13
13
  *
14
14
  * The platform endpoint is:
15
15
  * POST {VELLUM_PLATFORM_URL}/v1/internal/gateway/callback-routes/register/
@@ -23,7 +23,7 @@ import {
23
23
  getPlatformBaseUrl,
24
24
  getPlatformInternalApiKey,
25
25
  } from "../config/env.js";
26
- import { getIsContainerized } from "../config/env-registry.js";
26
+ import { getIsPlatform } from "../config/env-registry.js";
27
27
  import { credentialKey } from "../security/credential-key.js";
28
28
  import { getSecureKeyAsync } from "../security/secure-keys.js";
29
29
  import { getLogger } from "../util/logger.js";
@@ -31,7 +31,7 @@ import { getLogger } from "../util/logger.js";
31
31
  const log = getLogger("platform-callback-registration");
32
32
 
33
33
  export interface PlatformCallbackRegistrationContext {
34
- containerized: boolean;
34
+ isPlatform: boolean;
35
35
  platformBaseUrl: string;
36
36
  assistantId: string;
37
37
  hasInternalApiKey: boolean;
@@ -42,21 +42,21 @@ export interface PlatformCallbackRegistrationContext {
42
42
 
43
43
  /**
44
44
  * Whether the daemon should register callback routes with the platform.
45
- * True when IS_CONTAINERIZED, VELLUM_PLATFORM_URL, and PLATFORM_ASSISTANT_ID
45
+ * True when IS_PLATFORM, VELLUM_PLATFORM_URL, and PLATFORM_ASSISTANT_ID
46
46
  * are all set. Intentionally does **not** require the managed proxy API key
47
47
  * so that callback-only flows (OAuth transport, Telegram/Twilio callback
48
48
  * registration) work during partial bootstrap before the key is injected.
49
49
  */
50
50
  export function shouldUsePlatformCallbacks(): boolean {
51
51
  return (
52
- getIsContainerized() &&
52
+ getIsPlatform() &&
53
53
  !!getPlatformBaseUrl() &&
54
54
  !!getPlatformAssistantId()
55
55
  );
56
56
  }
57
57
 
58
58
  export async function resolvePlatformCallbackRegistrationContext(): Promise<PlatformCallbackRegistrationContext> {
59
- const containerized = getIsContainerized();
59
+ const platform = getIsPlatform();
60
60
  const [storedBaseUrlRaw, storedAssistantIdRaw, storedAssistantApiKeyRaw] =
61
61
  await Promise.all([
62
62
  getSecureKeyAsync(credentialKey("vellum", "platform_base_url")),
@@ -80,14 +80,14 @@ export async function resolvePlatformCallbackRegistrationContext(): Promise<Plat
80
80
  : null;
81
81
 
82
82
  return {
83
- containerized,
83
+ isPlatform: platform,
84
84
  platformBaseUrl,
85
85
  assistantId,
86
86
  hasInternalApiKey: internalApiKey.length > 0,
87
87
  hasAssistantApiKey: assistantApiKey.length > 0,
88
88
  authHeader,
89
89
  enabled:
90
- containerized &&
90
+ platform &&
91
91
  platformBaseUrl.length > 0 &&
92
92
  assistantId.length > 0 &&
93
93
  authHeader !== null,
@@ -119,7 +119,7 @@ export async function registerCallbackRoute(
119
119
  const context = await resolvePlatformCallbackRegistrationContext();
120
120
  if (!context.enabled || !context.authHeader) {
121
121
  throw new Error(
122
- "Platform callbacks not available — missing containerized platform registration context",
122
+ "Platform callbacks not available — missing platform registration context",
123
123
  );
124
124
  }
125
125
 
@@ -166,7 +166,7 @@ export async function registerCallbackRoute(
166
166
  }
167
167
 
168
168
  /**
169
- * Resolve a callback URL, registering with the platform when containerized.
169
+ * Resolve a callback URL, registering with the platform when platform-managed.
170
170
  *
171
171
  * When platform callbacks are enabled, registers the route and returns the
172
172
  * platform's stable callback URL (optionally with query parameters appended).
@@ -176,7 +176,7 @@ export async function registerCallbackRoute(
176
176
  * string) rather than an eagerly-evaluated string. This is critical because
177
177
  * the direct URL builders (e.g. `getTwilioVoiceWebhookUrl`) call
178
178
  * `getPublicBaseUrl()` which throws when no public ingress URL is configured.
179
- * In containerized environments that rely solely on platform callbacks, the
179
+ * In platform-managed environments that rely solely on platform callbacks, the
180
180
  * direct URL is never needed — deferring evaluation avoids the throw.
181
181
  *
182
182
  * @param directUrl - Lazy supplier for the direct callback URL.
@@ -204,7 +204,7 @@ export async function resolveCallbackUrl(
204
204
  }
205
205
  return url;
206
206
  } catch (err) {
207
- // In managed/containerized mode there is no local-ingress fallback and
207
+ // In platform-managed mode there is no local-ingress fallback and
208
208
  // ngrok is not applicable. Surface a clear error so callers (and the
209
209
  // user) understand this is a platform-side issue, not a tunnel problem.
210
210
  const detail = err instanceof Error ? err.message : String(err);