@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
@@ -229,6 +229,7 @@ async function handleRunScheduleNow(
229
229
  );
230
230
  const fallbackConversation = bootstrapConversation({
231
231
  source: "schedule",
232
+ groupId: "system:scheduled",
232
233
  origin: "schedule",
233
234
  systemHint: `Schedule (manual): ${schedule.name}`,
234
235
  });
@@ -241,6 +242,7 @@ async function handleRunScheduleNow(
241
242
  // Regular message-based schedule
242
243
  const conversation = bootstrapConversation({
243
244
  source: "schedule",
245
+ groupId: "system:scheduled",
244
246
  origin: "schedule",
245
247
  systemHint: `Schedule (manual): ${schedule.name}`,
246
248
  });
@@ -39,6 +39,85 @@ export interface SkillRouteDeps {
39
39
  getSkillContext: () => SkillOperationContext;
40
40
  }
41
41
 
42
+ const slimSkillBase = {
43
+ id: z.string(),
44
+ name: z.string(),
45
+ description: z.string(),
46
+ emoji: z.string().optional(),
47
+ kind: z.enum(["bundled", "installed", "catalog"]),
48
+ status: z.enum(["enabled", "disabled", "available"]),
49
+ };
50
+
51
+ const slimSkillSchema = z.discriminatedUnion("origin", [
52
+ z.object({ ...slimSkillBase, origin: z.literal("vellum") }),
53
+ z.object({
54
+ ...slimSkillBase,
55
+ origin: z.literal("clawhub"),
56
+ slug: z.string(),
57
+ author: z.string(),
58
+ stars: z.number(),
59
+ installs: z.number(),
60
+ reports: z.number(),
61
+ publishedAt: z.string().optional(),
62
+ }),
63
+ z.object({
64
+ ...slimSkillBase,
65
+ origin: z.literal("skillssh"),
66
+ slug: z.string(),
67
+ sourceRepo: z.string(),
68
+ installs: z.number(),
69
+ }),
70
+ z.object({ ...slimSkillBase, origin: z.literal("custom") }),
71
+ ]);
72
+
73
+ const skillDetailSchema = z.discriminatedUnion("origin", [
74
+ z.object({ ...slimSkillBase, origin: z.literal("vellum") }),
75
+ z.object({
76
+ ...slimSkillBase,
77
+ origin: z.literal("clawhub"),
78
+ slug: z.string(),
79
+ author: z.string(),
80
+ stars: z.number(),
81
+ installs: z.number(),
82
+ reports: z.number(),
83
+ publishedAt: z.string().optional(),
84
+ owner: z
85
+ .object({
86
+ handle: z.string(),
87
+ displayName: z.string(),
88
+ image: z.string().optional(),
89
+ })
90
+ .nullable()
91
+ .optional(),
92
+ stats: z
93
+ .object({
94
+ stars: z.number(),
95
+ installs: z.number(),
96
+ downloads: z.number(),
97
+ versions: z.number(),
98
+ })
99
+ .nullable()
100
+ .optional(),
101
+ latestVersion: z
102
+ .object({
103
+ version: z.string(),
104
+ changelog: z.string().optional(),
105
+ })
106
+ .nullable()
107
+ .optional(),
108
+ createdAt: z.number().nullable().optional(),
109
+ updatedAt: z.number().nullable().optional(),
110
+ }),
111
+ z.object({
112
+ ...slimSkillBase,
113
+ origin: z.literal("skillssh"),
114
+ slug: z.string(),
115
+ sourceRepo: z.string(),
116
+ installs: z.number(),
117
+ }),
118
+ z.object({ ...slimSkillBase, origin: z.literal("custom") }),
119
+ ]);
120
+
42
121
  export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
43
122
  const ctx = () => deps.getSkillContext();
44
123
 
@@ -60,34 +139,7 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
60
139
  },
61
140
  ],
62
141
  responseBody: z.object({
63
- skills: z
64
- .array(
65
- z.object({
66
- id: z.string(),
67
- name: z.string(),
68
- description: z.string(),
69
- emoji: z.string().optional(),
70
- homepage: z.string().optional(),
71
- source: z.enum([
72
- "bundled",
73
- "managed",
74
- "workspace",
75
- "clawhub",
76
- "extra",
77
- "catalog",
78
- ]),
79
- state: z.enum(["enabled", "disabled"]),
80
- installStatus: z.enum(["bundled", "installed", "available"]),
81
- updateAvailable: z.boolean(),
82
- provenance: z.object({
83
- kind: z.enum(["first-party", "third-party", "local"]),
84
- provider: z.string().optional(),
85
- originId: z.string().optional(),
86
- sourceUrl: z.string().optional(),
87
- }),
88
- }),
89
- )
90
- .describe("Skill objects"),
142
+ skills: z.array(slimSkillSchema).describe("Skill objects"),
91
143
  }),
92
144
  handler: async ({ url }) => {
93
145
  const include = url.searchParams.get("include");
@@ -201,16 +253,23 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
201
253
  url: z.string().describe("Skill URL"),
202
254
  spec: z.string().describe("Skill spec"),
203
255
  version: z.string(),
256
+ origin: z
257
+ .enum(["clawhub", "skillssh"])
258
+ .optional()
259
+ .describe(
260
+ "Which registry to install from. When omitted, the install flow auto-detects based on slug format.",
261
+ ),
204
262
  }),
205
263
  responseBody: z.object({
206
264
  ok: z.boolean(),
207
265
  }),
208
- handler: async ({ req }) => {
266
+ handler: async ({ req, authContext }) => {
209
267
  const body = (await req.json()) as {
210
268
  slug?: string;
211
269
  url?: string;
212
270
  spec?: string;
213
271
  version?: string;
272
+ origin?: "clawhub" | "skillssh";
214
273
  };
215
274
  const slug = body.slug ?? body.url ?? body.spec;
216
275
  if (!slug || typeof slug !== "string") {
@@ -220,8 +279,9 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
220
279
  400,
221
280
  );
222
281
  }
282
+ const contactId = authContext.actorPrincipalId ?? undefined;
223
283
  const result = await installSkill(
224
- { slug, version: body.version },
284
+ { slug, version: body.version, origin: body.origin, contactId },
225
285
  ctx(),
226
286
  );
227
287
  if (!result.success) {
@@ -265,7 +325,9 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
265
325
  },
266
326
  ],
267
327
  responseBody: z.object({
268
- data: z.object({}).passthrough().describe("Search results"),
328
+ skills: z
329
+ .array(slimSkillSchema)
330
+ .describe("Skill objects matching the search query"),
269
331
  }),
270
332
  handler: async ({ url }) => {
271
333
  const query = url.searchParams.get("q") ?? "";
@@ -276,7 +338,7 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
276
338
  if (!result.success) {
277
339
  return httpError("INTERNAL_ERROR", result.error, 500);
278
340
  }
279
- return Response.json({ data: result.data });
341
+ return Response.json({ skills: result.skills });
280
342
  },
281
343
  },
282
344
 
@@ -323,7 +385,7 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
323
385
  responseBody: z.object({
324
386
  ok: z.boolean(),
325
387
  }),
326
- handler: async ({ req }) => {
388
+ handler: async ({ req, authContext }) => {
327
389
  const body = (await req.json()) as CreateSkillParams;
328
390
  if (
329
391
  !body.skillId ||
@@ -337,7 +399,8 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
337
399
  400,
338
400
  );
339
401
  }
340
- const result = await createSkill(body, ctx());
402
+ const contactId = authContext.actorPrincipalId ?? undefined;
403
+ const result = await createSkill({ ...body, contactId }, ctx());
341
404
  if (!result.success) {
342
405
  return httpError("INTERNAL_ERROR", result.error, 500);
343
406
  }
@@ -395,10 +458,13 @@ export function skillRouteDefinitions(deps: SkillRouteDeps): RouteDefinition[] {
395
458
  method: "GET",
396
459
  policyKey: "skills",
397
460
  summary: "Get skill",
398
- description: "Return a single skill by ID.",
461
+ description: "Return a single skill by ID with enriched detail fields.",
399
462
  tags: ["skills"],
400
- handler: ({ params }) => {
401
- const result = getSkill(params.id, ctx());
463
+ responseBody: z.object({
464
+ skill: skillDetailSchema.describe("Skill detail object"),
465
+ }),
466
+ handler: async ({ params }) => {
467
+ const result = await getSkill(params.id, ctx());
402
468
  if ("error" in result) {
403
469
  if (result.status === 404) {
404
470
  return httpError("NOT_FOUND", result.error, 404);
@@ -5,7 +5,7 @@
5
5
  * item falls back to the task-level required tools instead of silently
6
6
  * skipping permission checks.
7
7
  */
8
- import { afterAll, describe, expect, mock, test } from "bun:test";
8
+ import { describe, expect, mock, test } from "bun:test";
9
9
 
10
10
  mock.module("../../util/logger.js", () => ({
11
11
  getLogger: () =>
@@ -19,7 +19,7 @@ mock.module("../../permissions/checker.js", () => ({
19
19
  classifyRisk: async () => "high",
20
20
  }));
21
21
 
22
- import { initializeDb, resetDb } from "../../memory/db.js";
22
+ import { initializeDb } from "../../memory/db.js";
23
23
  import { createTask } from "../../tasks/task-store.js";
24
24
  import { createWorkItem } from "../../work-items/work-item-store.js";
25
25
  import type { RouteContext } from "../http-router.js";
@@ -30,10 +30,6 @@ import {
30
30
 
31
31
  initializeDb();
32
32
 
33
- afterAll(() => {
34
- resetDb();
35
- });
36
-
37
33
  describe("empty required_tools snapshot bypass", () => {
38
34
  test("falls back to task required tools when snapshot requiredTools is empty", async () => {
39
35
  const task = createTask({
@@ -188,7 +188,12 @@ async function runScheduleOnce(
188
188
  );
189
189
  const { runTask } = await import("../tasks/task-runner.js");
190
190
  const result = await runTask(
191
- { taskId, workingDir: process.cwd(), source: "schedule", scheduleJobId: job.id },
191
+ {
192
+ taskId,
193
+ workingDir: process.cwd(),
194
+ source: "schedule",
195
+ scheduleJobId: job.id,
196
+ },
192
197
  processMessage as (
193
198
  conversationId: string,
194
199
  message: string,
@@ -237,6 +242,7 @@ async function runScheduleOnce(
237
242
  const fallbackConversation = bootstrapConversation({
238
243
  source: "schedule",
239
244
  scheduleJobId: job.id,
245
+ groupId: "system:scheduled",
240
246
  origin: "schedule",
241
247
  systemHint: `Schedule: ${job.name}`,
242
248
  });
@@ -255,6 +261,7 @@ async function runScheduleOnce(
255
261
  const conversation = bootstrapConversation({
256
262
  source: "schedule",
257
263
  scheduleJobId: job.id,
264
+ groupId: "system:scheduled",
258
265
  origin: "schedule",
259
266
  systemHint: isOneShot ? `Reminder: ${job.name}` : `Schedule: ${job.name}`,
260
267
  });
@@ -61,7 +61,7 @@ export interface OAuth2TokenResult {
61
61
 
62
62
  export interface OAuth2FlowCallbacks {
63
63
  /** Open a URL in the user's browser (e.g. via `open_url` message). */
64
- openUrl: (url: string) => void;
64
+ openUrl: (url: string) => void | Promise<void>;
65
65
  }
66
66
 
67
67
  export interface OAuth2FlowOptions {
@@ -22,9 +22,9 @@ import type {
22
22
  SecureKeyDeleteResult,
23
23
  } from "@vellumai/credential-storage";
24
24
 
25
- import providerEnvVarsRegistry from "../../../meta/provider-env-vars.json" with { type: "json" };
26
25
  import { getIsContainerized } from "../config/env-registry.js";
27
26
  import type { CesClient } from "../credential-execution/client.js";
27
+ import { PROVIDER_ENV_VAR_NAMES } from "../shared/provider-env-vars.js";
28
28
  import { getLogger } from "../util/logger.js";
29
29
  import { createCesCredentialBackend } from "./ces-credential-client.js";
30
30
  import { CesRpcCredentialBackend } from "./ces-rpc-credential-backend.js";
@@ -395,14 +395,10 @@ export async function deleteSecureKeyAsync(
395
395
  // ---------------------------------------------------------------------------
396
396
 
397
397
  /**
398
- * Env var names keyed by provider. Loaded from the shared registry at
399
- * `meta/provider-env-vars.json`the single source of truth also consumed
400
- * by the CLI and the macOS client.
401
- * Ollama is intentionally omitted from the registry — it doesn't require
402
- * an API key.
398
+ * Env var names keyed by provider.
399
+ * Ollama is intentionally omitted it doesn't require an API key.
403
400
  */
404
- const PROVIDER_ENV_VARS: Record<string, string> =
405
- providerEnvVarsRegistry.providers;
401
+ const PROVIDER_ENV_VARS: Record<string, string> = PROVIDER_ENV_VAR_NAMES;
406
402
 
407
403
  /**
408
404
  * Retrieve a provider API key, checking secure storage first and falling
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Provider API key environment variable names, keyed by provider ID.
3
+ *
4
+ * Keep in sync with:
5
+ * - cli/src/shared/provider-env-vars.ts
6
+ * - meta/provider-env-vars.json (consumed by the macOS client build)
7
+ *
8
+ * Once a consolidated shared package exists in packages/, all three
9
+ * copies can be replaced by a single import.
10
+ */
11
+ export const PROVIDER_ENV_VAR_NAMES: Record<string, string> = {
12
+ anthropic: "ANTHROPIC_API_KEY",
13
+ openai: "OPENAI_API_KEY",
14
+ gemini: "GEMINI_API_KEY",
15
+ fireworks: "FIREWORKS_API_KEY",
16
+ openrouter: "OPENROUTER_API_KEY",
17
+ brave: "BRAVE_API_KEY",
18
+ perplexity: "PERPLEXITY_API_KEY",
19
+ };
@@ -37,6 +37,11 @@ export async function getCatalog(): Promise<CatalogSkill[]> {
37
37
  return catalog;
38
38
  }
39
39
 
40
+ /** Return the cached catalog synchronously, or [] if no cache exists yet. */
41
+ export function getCachedCatalogSync(): CatalogSkill[] {
42
+ return cachedCatalog ?? [];
43
+ }
44
+
40
45
  /** Invalidate the cache (for testing or forced refresh). */
41
46
  export function invalidateCatalogCache(): void {
42
47
  cachedCatalog = null;
@@ -16,6 +16,7 @@ import { gunzipSync } from "node:zlib";
16
16
  import { getPlatformBaseUrl } from "../config/env.js";
17
17
  import { getLogger } from "../util/logger.js";
18
18
  import { getWorkspaceSkillsDir, readPlatformToken } from "../util/platform.js";
19
+ import { computeSkillHash, writeInstallMeta } from "./install-meta.js";
19
20
  import { deleteSkillCapabilityMemory } from "./skill-memory.js";
20
21
 
21
22
  const log = getLogger("catalog-install");
@@ -270,6 +271,7 @@ export async function installSkillLocally(
270
271
  skillId: string,
271
272
  catalogEntry: CatalogSkill,
272
273
  overwrite: boolean,
274
+ contactId?: string,
273
275
  ): Promise<void> {
274
276
  const skillDir = join(getWorkspaceSkillsDir(), skillId);
275
277
  const skillFilePath = join(skillDir, "SKILL.md");
@@ -294,19 +296,18 @@ export async function installSkillLocally(
294
296
  await fetchAndExtractSkill(skillId, skillDir);
295
297
  }
296
298
 
297
- // Write version metadata
298
- if (catalogEntry.version) {
299
- const meta = {
300
- version: catalogEntry.version,
301
- installedAt: new Date().toISOString(),
302
- };
303
- atomicWriteFile(
304
- join(skillDir, "version.json"),
305
- JSON.stringify(meta, null, 2) + "\n",
306
- );
307
- }
299
+ // Write install metadata
300
+ writeInstallMeta(skillDir, {
301
+ origin: "vellum",
302
+ installedAt: new Date().toISOString(),
303
+ ...(catalogEntry.version ? { version: catalogEntry.version } : {}),
304
+ ...(contactId ? { installedBy: contactId } : {}),
305
+ contentHash: computeSkillHash(skillDir) ?? undefined,
306
+ });
308
307
 
309
- // Install npm dependencies if the skill has a package.json
308
+ // Post-install: install dependencies first, then index the skill.
309
+ // Running bun install before upsertSkillsIndex ensures we don't index a
310
+ // skill whose dependencies failed to install.
310
311
  if (existsSync(join(skillDir, "package.json"))) {
311
312
  const bunPath = `${homedir()}/.bun/bin`;
312
313
  execSync("bun install", {
@@ -315,8 +316,6 @@ export async function installSkillLocally(
315
316
  env: { ...process.env, PATH: `${bunPath}:${process.env.PATH}` },
316
317
  });
317
318
  }
318
-
319
- // Register in SKILLS.md only after all steps succeed
320
319
  upsertSkillsIndex(skillId);
321
320
  }
322
321
 
@@ -393,6 +392,8 @@ export async function autoInstallFromCatalog(
393
392
  return false;
394
393
  }
395
394
 
395
+ // installSkillLocally handles dependency installation and SKILLS.md indexing.
396
396
  await installSkillLocally(skillId, entry, false);
397
+
397
398
  return true;
398
399
  }