@vellumai/assistant 0.5.16 → 0.6.1

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 (592) hide show
  1. package/AGENTS.md +4 -0
  2. package/ARCHITECTURE.md +69 -16
  3. package/Dockerfile +2 -5
  4. package/bun.lock +6 -2
  5. package/docker-entrypoint.sh +32 -1
  6. package/docs/architecture/integrations.md +1 -1
  7. package/docs/architecture/memory.md +21 -24
  8. package/knip.json +2 -1
  9. package/openapi.yaml +1198 -83
  10. package/package.json +5 -1
  11. package/src/__tests__/actor-token-service.test.ts +68 -0
  12. package/src/__tests__/agent-loop.test.ts +0 -32
  13. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  14. package/src/__tests__/anthropic-provider.test.ts +217 -98
  15. package/src/__tests__/app-compiler.test.ts +120 -0
  16. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  17. package/src/__tests__/app-executors.test.ts +47 -1
  18. package/src/__tests__/app-source-watcher.test.ts +159 -0
  19. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  20. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  21. package/src/__tests__/call-domain.test.ts +2 -6
  22. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  23. package/src/__tests__/call-recovery.test.ts +2 -6
  24. package/src/__tests__/call-routes-http.test.ts +2 -6
  25. package/src/__tests__/call-store.test.ts +2 -6
  26. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  27. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  28. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  29. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  30. package/src/__tests__/checker.test.ts +63 -9
  31. package/src/__tests__/clawhub.test.ts +54 -24
  32. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  33. package/src/__tests__/config-schema.test.ts +6 -1
  34. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  35. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  36. package/src/__tests__/contacts-tools.test.ts +31 -0
  37. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  38. package/src/__tests__/context-token-estimator.test.ts +175 -10
  39. package/src/__tests__/conversation-agent-loop-overflow.test.ts +13 -6
  40. package/src/__tests__/conversation-agent-loop.test.ts +13 -51
  41. package/src/__tests__/conversation-attachments.test.ts +2 -6
  42. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  43. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  44. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  45. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  46. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  47. package/src/__tests__/conversation-error.test.ts +33 -2
  48. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  49. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  50. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  51. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  52. package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
  53. package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
  54. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  55. package/src/__tests__/conversation-store.test.ts +2 -6
  56. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
  57. package/src/__tests__/conversation-usage.test.ts +2 -6
  58. package/src/__tests__/conversation-wipe.test.ts +13 -414
  59. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
  60. package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
  61. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  62. package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
  63. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  64. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  65. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  66. package/src/__tests__/date-context.test.ts +76 -210
  67. package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
  68. package/src/__tests__/file-list-tool.test.ts +219 -0
  69. package/src/__tests__/first-greeting.test.ts +1 -1
  70. package/src/__tests__/followup-tools.test.ts +2 -6
  71. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  72. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  73. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  74. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  75. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  76. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  77. package/src/__tests__/guardian-action-store.test.ts +2 -6
  78. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  79. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  80. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  81. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  82. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  83. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  84. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  85. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  86. package/src/__tests__/heartbeat-service.test.ts +180 -3
  87. package/src/__tests__/identity-routes.test.ts +328 -0
  88. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  89. package/src/__tests__/injection-block.test.ts +178 -0
  90. package/src/__tests__/install-meta.test.ts +506 -0
  91. package/src/__tests__/install-skill-routing.test.ts +293 -0
  92. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  93. package/src/__tests__/invite-routes-http.test.ts +2 -6
  94. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +17 -28
  95. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  96. package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
  97. package/src/__tests__/llm-context-normalization.test.ts +18 -18
  98. package/src/__tests__/llm-context-route-provider.test.ts +103 -6
  99. package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
  100. package/src/__tests__/llm-usage-store.test.ts +2 -6
  101. package/src/__tests__/log-export-workspace.test.ts +74 -111
  102. package/src/__tests__/managed-store.test.ts +38 -11
  103. package/src/__tests__/mcp-abort-signal.test.ts +5 -0
  104. package/src/__tests__/mcp-client-auth.test.ts +5 -0
  105. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  106. package/src/__tests__/memory-recall-log-store.test.ts +134 -6
  107. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  108. package/src/__tests__/migration-export-streaming.test.ts +304 -0
  109. package/src/__tests__/migration-import-commit-http.test.ts +11 -10
  110. package/src/__tests__/mock-fetch.ts +87 -0
  111. package/src/__tests__/non-member-access-request.test.ts +2 -6
  112. package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
  113. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  114. package/src/__tests__/oauth-cli.test.ts +364 -2
  115. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  116. package/src/__tests__/onboarding-template-contract.test.ts +62 -14
  117. package/src/__tests__/outlook-attachments.test.ts +301 -0
  118. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  119. package/src/__tests__/outlook-categories.test.ts +212 -0
  120. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  121. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  122. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  123. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  124. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  125. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  126. package/src/__tests__/outlook-trash.test.ts +77 -0
  127. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  128. package/src/__tests__/parser.test.ts +32 -0
  129. package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
  130. package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
  131. package/src/__tests__/permission-mode-sse.test.ts +418 -0
  132. package/src/__tests__/permission-mode-store.test.ts +277 -0
  133. package/src/__tests__/permission-mode.test.ts +101 -0
  134. package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
  135. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  136. package/src/__tests__/playbook-execution.test.ts +76 -80
  137. package/src/__tests__/playbook-tools.test.ts +5 -7
  138. package/src/__tests__/profiler-routes.test.ts +502 -0
  139. package/src/__tests__/profiler-run-store.test.ts +441 -0
  140. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  141. package/src/__tests__/proxy-approval-callback.test.ts +4 -75
  142. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  143. package/src/__tests__/registry.test.ts +3 -3
  144. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  145. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  146. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  147. package/src/__tests__/sandbox-host-parity.test.ts +5 -4
  148. package/src/__tests__/schedule-store.test.ts +2 -6
  149. package/src/__tests__/schedule-tools.test.ts +2 -6
  150. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  151. package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
  152. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  153. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  154. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
  155. package/src/__tests__/search-skills-unified.test.ts +422 -0
  156. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  157. package/src/__tests__/send-endpoint-busy.test.ts +44 -9
  158. package/src/__tests__/sequence-store.test.ts +2 -6
  159. package/src/__tests__/server-history-render.test.ts +2 -6
  160. package/src/__tests__/set-permission-mode.test.ts +274 -0
  161. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  162. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  163. package/src/__tests__/skill-load-feature-flag.test.ts +23 -11
  164. package/src/__tests__/skill-memory.test.ts +2 -741
  165. package/src/__tests__/skills-uninstall.test.ts +2 -2
  166. package/src/__tests__/skills.test.ts +1 -1
  167. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  168. package/src/__tests__/strip-memory-injections.test.ts +187 -0
  169. package/src/__tests__/subagent-detail.test.ts +84 -0
  170. package/src/__tests__/subagent-disposal.test.ts +308 -0
  171. package/src/__tests__/subagent-manager-notify.test.ts +19 -10
  172. package/src/__tests__/subagent-notify-parent.test.ts +390 -0
  173. package/src/__tests__/subagent-role-registry.test.ts +108 -0
  174. package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
  175. package/src/__tests__/subagent-tools.test.ts +464 -4
  176. package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
  177. package/src/__tests__/task-compiler.test.ts +2 -6
  178. package/src/__tests__/task-management-tools.test.ts +2 -6
  179. package/src/__tests__/task-memory-cleanup.test.ts +185 -241
  180. package/src/__tests__/task-runner.test.ts +2 -6
  181. package/src/__tests__/task-scheduler.test.ts +2 -6
  182. package/src/__tests__/terminal-tools.test.ts +17 -27
  183. package/src/__tests__/test-preload.ts +7 -0
  184. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  185. package/src/__tests__/tool-executor.test.ts +4 -26
  186. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  187. package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
  188. package/src/__tests__/top-level-renderer.test.ts +10 -13
  189. package/src/__tests__/trust-store.test.ts +1 -1
  190. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  191. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +118 -8
  192. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  193. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  194. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  195. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  196. package/src/__tests__/usage-routes.test.ts +2 -6
  197. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  198. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  199. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  200. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  201. package/src/__tests__/volume-security-guard.test.ts +2 -0
  202. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  203. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  204. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  205. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  206. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
  207. package/src/__tests__/workspace-policy.test.ts +1 -1
  208. package/src/agent/attachments.ts +7 -2
  209. package/src/agent/image-optimize.ts +165 -0
  210. package/src/agent/loop.ts +7 -15
  211. package/src/approvals/guardian-request-resolvers.ts +24 -0
  212. package/src/avatar/traits-png-sync.ts +3 -3
  213. package/src/bundler/app-compiler.ts +179 -2
  214. package/src/bundler/package-resolver.ts +3 -5
  215. package/src/cli/__tests__/notifications.test.ts +1 -2
  216. package/src/cli/__tests__/run-assistant-command.ts +29 -0
  217. package/src/cli/commands/__tests__/email-download.test.ts +245 -0
  218. package/src/cli/commands/__tests__/email-list.test.ts +192 -0
  219. package/src/cli/commands/__tests__/email-register.test.ts +186 -0
  220. package/src/cli/commands/__tests__/email-send.test.ts +291 -0
  221. package/src/cli/commands/__tests__/email-status.test.ts +181 -0
  222. package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
  223. package/src/cli/commands/__tests__/routes.test.ts +562 -0
  224. package/src/cli/commands/avatar.ts +3 -3
  225. package/src/cli/commands/config.ts +26 -13
  226. package/src/cli/commands/conversations.ts +1 -8
  227. package/src/cli/commands/doctor.ts +2 -2
  228. package/src/cli/commands/email.ts +584 -835
  229. package/src/cli/commands/memory.ts +37 -84
  230. package/src/cli/commands/notifications.ts +7 -2
  231. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  232. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  233. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  234. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  235. package/src/cli/commands/oauth/connect.ts +25 -11
  236. package/src/cli/commands/oauth/mode.ts +7 -0
  237. package/src/cli/commands/oauth/shared.ts +39 -3
  238. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  239. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  240. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  241. package/src/cli/commands/platform/index.ts +16 -16
  242. package/src/cli/commands/routes.ts +396 -0
  243. package/src/cli/commands/skills.ts +218 -36
  244. package/src/cli/commands/trust.ts +2 -2
  245. package/src/cli/lib/daemon-credential-client.ts +2 -3
  246. package/src/cli/program.ts +2 -0
  247. package/src/cli.ts +1 -120
  248. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  249. package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
  250. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  251. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  252. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  253. package/src/config/bundled-skills/gmail/SKILL.md +4 -12
  254. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  255. package/src/config/bundled-skills/messaging/SKILL.md +17 -18
  256. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  257. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  258. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  259. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  260. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  261. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  262. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  263. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  264. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  265. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  266. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  267. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  268. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  269. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  270. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  271. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  272. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  273. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  274. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  275. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  276. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  277. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  278. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  279. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  280. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  281. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  282. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  283. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  284. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  285. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  286. package/src/config/bundled-skills/schedule/SKILL.md +22 -2
  287. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  288. package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
  289. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
  290. package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
  291. package/src/config/bundled-skills/slack/SKILL.md +3 -7
  292. package/src/config/bundled-skills/subagent/SKILL.md +43 -3
  293. package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
  294. package/src/config/bundled-tool-registry.ts +56 -4
  295. package/src/config/env-registry.ts +78 -8
  296. package/src/config/feature-flag-registry.json +38 -125
  297. package/src/config/schema.ts +8 -0
  298. package/src/config/schemas/filing.ts +51 -0
  299. package/src/config/schemas/heartbeat.ts +15 -12
  300. package/src/config/schemas/memory-lifecycle.ts +12 -0
  301. package/src/config/schemas/platform.ts +8 -0
  302. package/src/config/schemas/security.ts +14 -0
  303. package/src/config/schemas/timeouts.ts +1 -1
  304. package/src/config/skills.ts +18 -7
  305. package/src/context/token-estimator.ts +25 -18
  306. package/src/context/window-manager.ts +6 -2
  307. package/src/credential-execution/process-manager.ts +3 -1
  308. package/src/daemon/app-source-watcher.ts +93 -0
  309. package/src/daemon/config-watcher.ts +79 -1
  310. package/src/daemon/context-overflow-reducer.ts +46 -2
  311. package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
  312. package/src/daemon/conversation-agent-loop.ts +236 -108
  313. package/src/daemon/conversation-error.ts +31 -8
  314. package/src/daemon/conversation-history.ts +4 -19
  315. package/src/daemon/conversation-lifecycle.ts +36 -9
  316. package/src/daemon/conversation-media-retry.ts +85 -7
  317. package/src/daemon/conversation-notifiers.ts +4 -1
  318. package/src/daemon/conversation-process.ts +13 -7
  319. package/src/daemon/conversation-runtime-assembly.ts +305 -306
  320. package/src/daemon/conversation-tool-setup.ts +44 -14
  321. package/src/daemon/conversation-workspace.ts +1 -2
  322. package/src/daemon/conversation.ts +59 -2
  323. package/src/daemon/daemon-control.ts +8 -2
  324. package/src/daemon/date-context.ts +26 -53
  325. package/src/daemon/first-greeting.ts +1 -1
  326. package/src/daemon/handlers/conversations.ts +4 -7
  327. package/src/daemon/handlers/shared.test.ts +143 -0
  328. package/src/daemon/handlers/shared.ts +85 -17
  329. package/src/daemon/handlers/skills.ts +416 -209
  330. package/src/daemon/lifecycle.ts +212 -131
  331. package/src/daemon/main.ts +5 -1
  332. package/src/daemon/message-types/conversations.ts +29 -7
  333. package/src/daemon/message-types/messages.ts +12 -2
  334. package/src/daemon/message-types/schedules.ts +1 -0
  335. package/src/daemon/message-types/settings.ts +6 -0
  336. package/src/daemon/message-types/skills.ts +97 -36
  337. package/src/daemon/profiler-run-store.ts +557 -0
  338. package/src/daemon/providers-setup.ts +5 -0
  339. package/src/daemon/server.ts +100 -11
  340. package/src/daemon/shutdown-handlers.ts +5 -0
  341. package/src/daemon/tool-side-effects.ts +50 -8
  342. package/src/export/transcript-formatter.ts +148 -0
  343. package/src/filing/filing-service.ts +228 -0
  344. package/src/heartbeat/heartbeat-service.ts +97 -7
  345. package/src/hooks/cli.ts +2 -2
  346. package/src/hooks/runner.ts +15 -38
  347. package/src/inbound/platform-callback-registration.ts +14 -14
  348. package/src/mcp/client.ts +6 -0
  349. package/src/mcp/mcp-oauth-provider.ts +149 -27
  350. package/src/memory/admin.ts +42 -75
  351. package/src/memory/app-store.ts +69 -0
  352. package/src/memory/conversation-bootstrap.ts +3 -1
  353. package/src/memory/conversation-crud.ts +211 -288
  354. package/src/memory/conversation-group-migration.ts +157 -0
  355. package/src/memory/conversation-queries.ts +61 -13
  356. package/src/memory/conversation-title-service.ts +1 -0
  357. package/src/memory/db-init.ts +194 -361
  358. package/src/memory/embed.ts +73 -0
  359. package/src/memory/embedding-backend.ts +8 -14
  360. package/src/memory/embedding-runtime-manager.ts +12 -114
  361. package/src/memory/fingerprint.ts +2 -2
  362. package/src/memory/graph/bootstrap.ts +521 -0
  363. package/src/memory/graph/capability-seed.ts +449 -0
  364. package/src/memory/graph/consolidation.ts +725 -0
  365. package/src/memory/graph/conversation-graph-memory.ts +659 -0
  366. package/src/memory/graph/decay.test.ts +208 -0
  367. package/src/memory/graph/decay.ts +195 -0
  368. package/src/memory/graph/extraction-job.ts +74 -0
  369. package/src/memory/graph/extraction.test.ts +936 -0
  370. package/src/memory/graph/extraction.ts +1297 -0
  371. package/src/memory/graph/graph-memory-state-store.ts +37 -0
  372. package/src/memory/graph/graph-search.ts +280 -0
  373. package/src/memory/graph/image-ref-utils.ts +29 -0
  374. package/src/memory/graph/injection.test.ts +513 -0
  375. package/src/memory/graph/injection.ts +469 -0
  376. package/src/memory/graph/inspect.ts +543 -0
  377. package/src/memory/graph/narrative.ts +267 -0
  378. package/src/memory/graph/pattern-scan.ts +269 -0
  379. package/src/memory/graph/retriever.ts +1111 -0
  380. package/src/memory/graph/scoring.test.ts +548 -0
  381. package/src/memory/graph/scoring.ts +232 -0
  382. package/src/memory/graph/serendipity.ts +65 -0
  383. package/src/memory/graph/store.test.ts +1098 -0
  384. package/src/memory/graph/store.ts +838 -0
  385. package/src/memory/graph/tool-handlers.ts +301 -0
  386. package/src/memory/graph/tools.ts +97 -0
  387. package/src/memory/graph/triggers.test.ts +487 -0
  388. package/src/memory/graph/triggers.ts +223 -0
  389. package/src/memory/graph/types.ts +295 -0
  390. package/src/memory/group-crud.ts +191 -0
  391. package/src/memory/indexer.ts +37 -19
  392. package/src/memory/job-handlers/cleanup.ts +32 -42
  393. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  394. package/src/memory/job-handlers/embedding.ts +5 -31
  395. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  396. package/src/memory/job-handlers/summarization.ts +32 -17
  397. package/src/memory/job-utils.ts +1 -1
  398. package/src/memory/jobs-store.ts +21 -31
  399. package/src/memory/jobs-worker.ts +180 -129
  400. package/src/memory/llm-request-log-store.ts +96 -12
  401. package/src/memory/memory-recall-log-store.ts +49 -5
  402. package/src/memory/message-content.ts +1 -0
  403. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  404. package/src/memory/migrations/203-drop-memory-items-tables.ts +55 -0
  405. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  406. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  407. package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
  408. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
  409. package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
  410. package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
  411. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
  412. package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
  413. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
  414. package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
  415. package/src/memory/migrations/index.ts +12 -0
  416. package/src/memory/migrations/registry.ts +16 -0
  417. package/src/memory/qdrant-client.ts +44 -17
  418. package/src/memory/schema/conversations.ts +14 -0
  419. package/src/memory/schema/index.ts +1 -0
  420. package/src/memory/schema/infrastructure.ts +8 -1
  421. package/src/memory/schema/memory-core.ts +0 -51
  422. package/src/memory/schema/memory-graph.ts +154 -0
  423. package/src/memory/search/semantic.ts +47 -91
  424. package/src/memory/task-memory-cleanup.ts +58 -61
  425. package/src/messaging/providers/outlook/adapter.ts +8 -1
  426. package/src/messaging/providers/outlook/client.ts +299 -0
  427. package/src/messaging/providers/outlook/types.ts +118 -0
  428. package/src/notifications/adapters/macos.ts +1 -0
  429. package/src/notifications/copy-composer.ts +95 -0
  430. package/src/notifications/decision-engine.ts +35 -0
  431. package/src/notifications/signal.ts +16 -0
  432. package/src/oauth/seed-providers.ts +2 -1
  433. package/src/permissions/checker.ts +36 -4
  434. package/src/permissions/defaults.ts +4 -4
  435. package/src/permissions/permission-mode-store.ts +180 -0
  436. package/src/permissions/permission-mode.ts +31 -0
  437. package/src/permissions/workspace-policy.ts +10 -1
  438. package/src/playbooks/playbook-compiler.ts +19 -18
  439. package/src/playbooks/types.ts +4 -3
  440. package/src/prompts/system-prompt.ts +62 -36
  441. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
  442. package/src/prompts/templates/BOOTSTRAP.md +70 -165
  443. package/src/prompts/templates/HEARTBEAT.md +3 -1
  444. package/src/prompts/templates/SOUL.md +25 -4
  445. package/src/prompts/templates/UPDATES.md +8 -0
  446. package/src/providers/anthropic/client.ts +136 -220
  447. package/src/providers/gemini/client.ts +1 -1
  448. package/src/providers/openai/client.ts +1 -1
  449. package/src/providers/registry.ts +1 -1
  450. package/src/providers/retry.ts +19 -3
  451. package/src/runtime/actor-trust-resolver.ts +5 -1
  452. package/src/runtime/auth/route-policy.ts +30 -0
  453. package/src/runtime/guardian-reply-router.ts +5 -1
  454. package/src/runtime/http-server.ts +55 -5
  455. package/src/runtime/http-types.ts +12 -1
  456. package/src/runtime/middleware/auth.ts +20 -0
  457. package/src/runtime/migrations/vbundle-builder.ts +389 -3
  458. package/src/runtime/migrations/vbundle-importer.ts +8 -6
  459. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
  460. package/src/runtime/routes/app-management-routes.ts +1 -11
  461. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
  462. package/src/runtime/routes/archive-utils.ts +29 -0
  463. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  464. package/src/runtime/routes/attachment-routes.ts +106 -16
  465. package/src/runtime/routes/avatar-routes.ts +2 -9
  466. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  467. package/src/runtime/routes/btw-routes.ts +22 -1
  468. package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
  469. package/src/runtime/routes/conversation-management-routes.ts +3 -14
  470. package/src/runtime/routes/conversation-query-routes.ts +49 -3
  471. package/src/runtime/routes/conversation-routes.ts +264 -44
  472. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  473. package/src/runtime/routes/debug-routes.ts +1 -1
  474. package/src/runtime/routes/global-search-routes.ts +21 -19
  475. package/src/runtime/routes/group-routes.ts +207 -0
  476. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  477. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  478. package/src/runtime/routes/heartbeat-routes.ts +4 -10
  479. package/src/runtime/routes/identity-routes.ts +53 -18
  480. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  481. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  482. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  483. package/src/runtime/routes/llm-context-normalization.ts +14 -10
  484. package/src/runtime/routes/log-export-routes.ts +23 -275
  485. package/src/runtime/routes/memory-item-routes.test.ts +170 -247
  486. package/src/runtime/routes/memory-item-routes.ts +341 -388
  487. package/src/runtime/routes/migration-routes.ts +18 -7
  488. package/src/runtime/routes/profiler-routes.ts +350 -0
  489. package/src/runtime/routes/schedule-routes.ts +28 -11
  490. package/src/runtime/routes/settings-routes.ts +95 -8
  491. package/src/runtime/routes/skills-routes.ts +103 -37
  492. package/src/runtime/routes/subagents-routes.ts +28 -7
  493. package/src/runtime/routes/user-route-dispatcher.ts +223 -0
  494. package/src/runtime/routes/user-routes.ts +41 -0
  495. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  496. package/src/runtime/routes/workspace-routes.ts +0 -1
  497. package/src/schedule/schedule-store.ts +30 -0
  498. package/src/schedule/scheduler.ts +52 -18
  499. package/src/security/oauth2.ts +1 -1
  500. package/src/security/secure-keys.ts +4 -8
  501. package/src/shared/provider-env-vars.ts +19 -0
  502. package/src/skills/catalog-cache.ts +5 -0
  503. package/src/skills/catalog-install.ts +25 -16
  504. package/src/skills/clawhub.ts +134 -154
  505. package/src/skills/install-meta.ts +208 -0
  506. package/src/skills/managed-store.ts +29 -18
  507. package/src/skills/skill-memory.ts +12 -229
  508. package/src/skills/skillssh-registry.ts +19 -17
  509. package/src/subagent/index.ts +13 -3
  510. package/src/subagent/manager.ts +308 -29
  511. package/src/subagent/types.ts +68 -0
  512. package/src/tasks/task-runner.ts +7 -5
  513. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  514. package/src/tools/apps/executors.ts +29 -4
  515. package/src/tools/browser/runtime-check.ts +3 -1
  516. package/src/tools/filesystem/list.ts +93 -0
  517. package/src/tools/memory/register.ts +63 -46
  518. package/src/tools/permission-checker.ts +85 -1
  519. package/src/tools/registry.ts +4 -0
  520. package/src/tools/schedule/create.ts +3 -0
  521. package/src/tools/schedule/list.ts +1 -0
  522. package/src/tools/schedule/update.ts +6 -0
  523. package/src/tools/shared/filesystem/errors.ts +5 -0
  524. package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
  525. package/src/tools/shared/filesystem/image-read.ts +22 -85
  526. package/src/tools/shared/filesystem/types.ts +17 -0
  527. package/src/tools/shared/shell-output.ts +31 -2
  528. package/src/tools/subagent/abort.ts +12 -2
  529. package/src/tools/subagent/message.ts +9 -2
  530. package/src/tools/subagent/notify-parent.ts +79 -0
  531. package/src/tools/subagent/read.ts +29 -8
  532. package/src/tools/subagent/resolve.ts +21 -0
  533. package/src/tools/subagent/spawn.ts +2 -0
  534. package/src/tools/subagent/status.ts +11 -1
  535. package/src/tools/system/avatar-generator.ts +3 -3
  536. package/src/tools/system/register.ts +23 -0
  537. package/src/tools/system/set-permission-mode.ts +103 -0
  538. package/src/tools/terminal/parser.ts +30 -5
  539. package/src/tools/terminal/safe-env.ts +17 -1
  540. package/src/tools/tool-manifest.ts +9 -3
  541. package/src/tools/types.ts +2 -0
  542. package/src/util/browser.ts +25 -10
  543. package/src/util/bun-runtime.ts +172 -0
  544. package/src/util/logger.ts +1 -1
  545. package/src/util/platform.ts +50 -17
  546. package/src/watcher/providers/outlook-calendar.ts +343 -0
  547. package/src/watcher/providers/outlook.ts +198 -0
  548. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
  549. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
  550. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  551. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  552. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  553. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
  554. package/src/workspace/migrations/029-seed-pkb.ts +84 -0
  555. package/src/workspace/migrations/registry.ts +10 -0
  556. package/src/workspace/top-level-renderer.ts +5 -9
  557. package/src/__tests__/cli-memory.test.ts +0 -372
  558. package/src/__tests__/clipboard.test.ts +0 -88
  559. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  560. package/src/__tests__/journal-context.test.ts +0 -268
  561. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  562. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  563. package/src/__tests__/memory-query-builder.test.ts +0 -59
  564. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  565. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  566. package/src/__tests__/memory-regressions.test.ts +0 -3696
  567. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  568. package/src/cli/cli-memory.ts +0 -176
  569. package/src/daemon/conversation-memory.ts +0 -207
  570. package/src/memory/conversation-starters-cadence.ts +0 -74
  571. package/src/memory/items-extractor.ts +0 -860
  572. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  573. package/src/memory/job-handlers/extraction.ts +0 -40
  574. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  575. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  576. package/src/memory/journal-memory.ts +0 -224
  577. package/src/memory/query-builder.ts +0 -47
  578. package/src/memory/query-expansion.ts +0 -83
  579. package/src/memory/retriever.test.ts +0 -1592
  580. package/src/memory/retriever.ts +0 -1331
  581. package/src/memory/search/formatting.test.ts +0 -140
  582. package/src/memory/search/formatting.ts +0 -262
  583. package/src/memory/search/mmr.ts +0 -139
  584. package/src/memory/search/ranking.ts +0 -15
  585. package/src/memory/search/staleness.ts +0 -40
  586. package/src/memory/search/tier-classifier.ts +0 -18
  587. package/src/memory/search/types.ts +0 -121
  588. package/src/prompts/journal-context.ts +0 -154
  589. package/src/tools/memory/definitions.ts +0 -69
  590. package/src/tools/memory/handlers.test.ts +0 -562
  591. package/src/tools/memory/handlers.ts +0 -434
  592. package/src/util/clipboard.ts +0 -34
@@ -7,7 +7,6 @@ import {
7
7
  getMemorySystemStatus,
8
8
  queryMemory,
9
9
  requestMemoryBackfill,
10
- requestMemoryCleanup,
11
10
  requestMemoryRebuildIndex,
12
11
  requestReextract,
13
12
  } from "../../memory/admin.js";
@@ -36,7 +35,7 @@ Key concepts:
36
35
  Examples:
37
36
  $ assistant memory status
38
37
  $ assistant memory query "What is the project deadline?"
39
- $ assistant memory backfill`,
38
+ $ assistant memory backfill`
40
39
  );
41
40
 
42
41
  memory
@@ -52,15 +51,13 @@ Fields shown:
52
51
  degraded mode (e.g. missing embedding backend)
53
52
  embedding backend The provider/model pair used for vector embeddings (or "none")
54
53
  segments Total conversation segments indexed
55
- items Total distilled fact items stored
54
+ graph nodes Total memory graph nodes stored
56
55
  summaries Total compressed conversation summaries
57
56
  embeddings Total vector embeddings computed
58
- cleanup backlogs Number of superseded items pending cleanup
59
- cleanup throughput Number of cleanup operations completed in the last 24 hours
60
57
  jobs Status of background jobs (backfill, cleanup, rebuild-index)
61
58
 
62
59
  Examples:
63
- $ assistant memory status`,
60
+ $ assistant memory status`
64
61
  )
65
62
  .action(async () => {
66
63
  initializeDb();
@@ -74,15 +71,9 @@ Examples:
74
71
  log.info("Embedding backend: none");
75
72
  }
76
73
  log.info(`Segments: ${status.counts.segments.toLocaleString()}`);
77
- log.info(`Items: ${status.counts.items.toLocaleString()}`);
74
+ log.info(`Graph nodes: ${status.counts.graphNodes.toLocaleString()}`);
78
75
  log.info(`Summaries: ${status.counts.summaries.toLocaleString()}`);
79
76
  log.info(`Embeddings: ${status.counts.embeddings.toLocaleString()}`);
80
- log.info(
81
- `Cleanup backlog (superseded items): ${status.cleanup.supersededBacklog.toLocaleString()}`,
82
- );
83
- log.info(
84
- `Cleanup throughput 24h (superseded items): ${status.cleanup.supersededCompleted24h.toLocaleString()}`,
85
- );
86
77
  log.info("Jobs:");
87
78
  for (const [key, value] of Object.entries(status.jobs)) {
88
79
  log.info(` ${key}: ${value}`);
@@ -106,7 +97,7 @@ useful after bulk imports or if the incremental state has become inconsistent.
106
97
 
107
98
  Examples:
108
99
  $ assistant memory backfill
109
- $ assistant memory backfill --force`,
100
+ $ assistant memory backfill --force`
110
101
  )
111
102
  .action((opts: { force?: boolean }) => {
112
103
  initializeDb();
@@ -114,40 +105,6 @@ Examples:
114
105
  log.info(`Queued backfill job: ${jobId}`);
115
106
  });
116
107
 
117
- memory
118
- .command("cleanup")
119
- .description("Queue cleanup jobs for stale superseded items")
120
- .option(
121
- "--retention-ms <ms>",
122
- "Optional retention threshold in milliseconds",
123
- )
124
- .addHelpText(
125
- "after",
126
- `
127
- Queues a background cleanup job to remove memory items that have been
128
- superseded by newer, corrected facts past the retention threshold.
129
-
130
- The optional --retention-ms flag sets the minimum age (in milliseconds) a
131
- record must have before it is eligible for cleanup. If omitted, the system
132
- default retention period is used.
133
-
134
- Examples:
135
- $ assistant memory cleanup
136
- $ assistant memory cleanup --retention-ms 86400000`,
137
- )
138
- .action((opts: { retentionMs?: string }) => {
139
- initializeDb();
140
- const retentionMs = opts.retentionMs
141
- ? Number.parseInt(opts.retentionMs, 10)
142
- : undefined;
143
- const jobs = requestMemoryCleanup(
144
- Number.isFinite(retentionMs) ? retentionMs : undefined,
145
- );
146
- log.info(
147
- `Queued cleanup_stale_superseded_items job: ${jobs.staleSupersededItemsJobId}`,
148
- );
149
- });
150
-
151
108
  memory
152
109
  .command("cleanup-segments")
153
110
  .description("Remove short segments that waste retrieval budget")
@@ -156,7 +113,7 @@ Examples:
156
113
  "after",
157
114
  `
158
115
  Removes segments shorter than the minimum character threshold from both
159
- SQLite and Qdrant. Short fragments (e.g. "Collar Touched") burn embedding
116
+ SQLite and Qdrant. Short fragments (e.g. "OK sounds good") burn embedding
160
117
  budget, retrieval slots, and injection tokens without adding value.
161
118
 
162
119
  New segments are already filtered at creation time. This command cleans up
@@ -164,19 +121,21 @@ existing short segments that were stored before the filter was added.
164
121
 
165
122
  Examples:
166
123
  $ assistant memory cleanup-segments
167
- $ assistant memory cleanup-segments --dry-run`,
124
+ $ assistant memory cleanup-segments --dry-run`
168
125
  )
169
126
  .action(async (opts: { dryRun?: boolean }) => {
170
127
  initializeDb();
171
128
  const result = await cleanupShortSegments({ dryRun: opts.dryRun });
172
129
  if (opts.dryRun) {
173
130
  log.info(
174
- `Dry run: ${result.dryRunCount} short segment(s) would be removed.`,
131
+ `Dry run: ${result.dryRunCount} short segment(s) would be removed.`
175
132
  );
176
133
  } else {
177
134
  log.info(`Removed ${result.removed} short segment(s).`);
178
135
  if (result.failed > 0) {
179
- log.warn(`${result.failed} segment(s) skipped — Qdrant deletion failed. Re-run when Qdrant is available.`);
136
+ log.warn(
137
+ `${result.failed} segment(s) skipped — Qdrant deletion failed. Re-run when Qdrant is available.`
138
+ );
180
139
  }
181
140
  }
182
141
  });
@@ -184,7 +143,7 @@ Examples:
184
143
  memory
185
144
  .command("query <text>")
186
145
  .description(
187
- "Run a memory recall query and print the injected memory payload",
146
+ "Run a memory recall query and print the injected memory payload"
188
147
  )
189
148
  .option("-c, --conversation <id>", "Optional conversation ID")
190
149
  .addHelpText(
@@ -205,7 +164,7 @@ context-aware recall. If omitted, the most recent conversation is used.
205
164
  Examples:
206
165
  $ assistant memory query "What is the project deadline?"
207
166
  $ assistant memory query "preferred communication style" --conversation conv_abc123
208
- $ assistant memory query "API rate limits"`,
167
+ $ assistant memory query "API rate limits"`
209
168
  )
210
169
  .action(async (text: string, opts?: { conversation?: string }) => {
211
170
  initializeDb();
@@ -215,18 +174,21 @@ Examples:
215
174
  conversationId = latest?.id ?? "";
216
175
  }
217
176
  const result = await queryMemory(text, conversationId ?? "");
218
- if (result.degraded) {
219
- log.info(`Memory degraded: ${result.reason ?? "unknown reason"}`);
220
- }
221
- log.info(`Semantic hits: ${result.semanticHits}`);
222
- log.info(`Merged count: ${result.mergedCount}`);
223
- log.info(`Injected tokens: ${result.injectedTokens}`);
224
- log.info(`Latency: ${result.latencyMs}ms`);
225
- if (result.injectedText.length > 0) {
177
+ log.info(`Results: ${result.results.length}`);
178
+ log.info(`Mode: ${result.mode}`);
179
+ if (result.results.length > 0) {
226
180
  log.info("");
227
- log.info(result.injectedText);
181
+ for (const r of result.results) {
182
+ log.info(
183
+ `[${r.type}] (confidence: ${r.confidence.toFixed(
184
+ 2
185
+ )}, score: ${r.score.toFixed(3)})`
186
+ );
187
+ log.info(r.content);
188
+ log.info("");
189
+ }
228
190
  } else {
229
- log.info("No memory injected.");
191
+ log.info("No results found.");
230
192
  }
231
193
  });
232
194
 
@@ -246,7 +208,7 @@ status" to monitor job progress.
246
208
 
247
209
  Examples:
248
210
  $ assistant memory rebuild-index
249
- $ assistant memory status`,
211
+ $ assistant memory status`
250
212
  )
251
213
  .action(() => {
252
214
  initializeDb();
@@ -257,18 +219,15 @@ Examples:
257
219
  memory
258
220
  .command("re-extract")
259
221
  .description(
260
- "Re-extract memories from conversations using the latest extraction prompt",
222
+ "Re-extract memories from conversations using the latest extraction prompt"
261
223
  )
262
224
  .option(
263
225
  "-c, --conversation <id>",
264
226
  "Target a specific conversation by ID (repeatable)",
265
227
  (val: string, prev: string[]) => [...prev, val],
266
- [] as string[],
267
- )
268
- .option(
269
- "-t, --top <n>",
270
- "Auto-select top N conversations by message count",
228
+ [] as string[]
271
229
  )
230
+ .option("-t, --top <n>", "Auto-select top N conversations by message count")
272
231
  .option("--dry-run", "Show what would be re-extracted without doing it")
273
232
  .addHelpText(
274
233
  "after",
@@ -278,7 +237,7 @@ extraction prompt. This is useful after updating the extraction prompt
278
237
  (e.g. importance scoring rework) to re-score and re-extract memories
279
238
  from historically important conversations.
280
239
 
281
- The command resets extraction checkpoints so the batch extraction handler
240
+ The command resets extraction checkpoints so the graph extraction handler
282
241
  re-processes all messages. Existing memories are provided as supersession
283
242
  context — the new extraction can supersede old flat-fact memories with
284
243
  richer, properly-scored replacements.
@@ -289,14 +248,10 @@ background worker).
289
248
  Examples:
290
249
  $ assistant memory re-extract --top 20
291
250
  $ assistant memory re-extract --conversation conv_abc123
292
- $ assistant memory re-extract --top 10 --dry-run`,
251
+ $ assistant memory re-extract --top 10 --dry-run`
293
252
  )
294
253
  .action(
295
- (opts: {
296
- conversation?: string[];
297
- top?: string;
298
- dryRun?: boolean;
299
- }) => {
254
+ (opts: { conversation?: string[]; top?: string; dryRun?: boolean }) => {
300
255
  initializeDb();
301
256
 
302
257
  const targets = [];
@@ -333,7 +288,7 @@ Examples:
333
288
 
334
289
  if (targets.length === 0) {
335
290
  log.info(
336
- "No targets specified. Use --conversation <id> or --top <n>.",
291
+ "No targets specified. Use --conversation <id> or --top <n>."
337
292
  );
338
293
  return;
339
294
  }
@@ -342,9 +297,7 @@ Examples:
342
297
  log.info(`\nRe-extraction targets (${targets.length}):`);
343
298
  for (const t of targets) {
344
299
  const title = t.title ?? "(untitled)";
345
- log.info(
346
- ` ${t.conversationId} ${t.messageCount} msgs "${title}"`,
347
- );
300
+ log.info(` ${t.conversationId} ${t.messageCount} msgs "${title}"`);
348
301
  }
349
302
 
350
303
  if (opts.dryRun) {
@@ -354,8 +307,8 @@ Examples:
354
307
 
355
308
  const { jobIds } = requestReextract(targets);
356
309
  log.info(
357
- `\nQueued ${jobIds.length} re-extraction job(s). The assistant will process them in the background.`,
310
+ `\nQueued ${jobIds.length} re-extraction job(s). The assistant will process them in the background.`
358
311
  );
359
- },
312
+ }
360
313
  );
361
314
  }
@@ -10,6 +10,10 @@ import {
10
10
  NOTIFICATION_SOURCE_EVENT_NAMES,
11
11
  } from "../../notifications/signal.js";
12
12
  import type { NotificationChannel } from "../../notifications/types.js";
13
+ import {
14
+ initAuthSigningKey,
15
+ resolveSigningKey,
16
+ } from "../../runtime/auth/token-service.js";
13
17
  import { initializeDb } from "../db.js";
14
18
  import { log } from "../logger.js";
15
19
  import { shouldOutputJson, writeOutput } from "../output.js";
@@ -159,7 +163,7 @@ Examples:
159
163
  visibleInSourceNow: boolean;
160
164
  deadlineAt?: string;
161
165
  preferredChannels?: string;
162
- conversationId?: string;
166
+ sessionId?: string;
163
167
  dedupeKey?: string;
164
168
  },
165
169
  cmd: Command,
@@ -251,8 +255,9 @@ Examples:
251
255
  }
252
256
 
253
257
  initializeDb();
258
+ initAuthSigningKey(resolveSigningKey());
254
259
 
255
- const sourceContextId = opts.conversationId ?? `cli-${Date.now()}`;
260
+ const sourceContextId = opts.sessionId ?? `cli-${Date.now()}`;
256
261
 
257
262
  const result = await emitNotificationSignal({
258
263
  sourceEventName: opts.sourceEventName,
@@ -88,7 +88,7 @@ mock.module("../../../../platform/client.js", () => ({
88
88
  }));
89
89
 
90
90
  mock.module("../../../../util/browser.js", () => ({
91
- openInBrowser: (url: string) => {
91
+ openInHostBrowser: async (url: string) => {
92
92
  mockOpenInBrowserCalls.push(url);
93
93
  },
94
94
  }));
@@ -127,7 +127,7 @@ mock.module("../shared.js", () => ({
127
127
  JSON.stringify({
128
128
  ok: false,
129
129
  error:
130
- "Platform prerequisites not met (not logged in or missing assistant ID)",
130
+ "Not connected to Vellum platform. Run `vellum platform connect` to connect first.",
131
131
  }) + "\n",
132
132
  );
133
133
  return null;
@@ -112,7 +112,7 @@ mock.module("../../../../platform/client.js", () => ({
112
112
  }));
113
113
 
114
114
  mock.module("../../../../util/browser.js", () => ({
115
- openInBrowser: () => {},
115
+ openInHostBrowser: async () => {},
116
116
  }));
117
117
 
118
118
  mock.module("../../../../util/logger.js", () => ({
@@ -162,7 +162,7 @@ mock.module("../shared.js", () => ({
162
162
  JSON.stringify({
163
163
  ok: false,
164
164
  error:
165
- "Platform prerequisites not met (not logged in or missing assistant ID)",
165
+ "Not connected to Vellum platform. Run `vellum platform connect` to connect first.",
166
166
  }) + "\n",
167
167
  );
168
168
  return null;
@@ -34,6 +34,10 @@ let mockSetNestedValueCalls: Array<{
34
34
 
35
35
  let mockConfigServices: Record<string, unknown> = {};
36
36
 
37
+ let mockRequirePlatformConnection: (
38
+ cmd: unknown,
39
+ ) => Promise<boolean> = async () => true;
40
+
37
41
  // ---------------------------------------------------------------------------
38
42
  // Mocks
39
43
  // ---------------------------------------------------------------------------
@@ -120,6 +124,8 @@ mock.module("../shared.js", () => ({
120
124
  isManagedMode: () => false,
121
125
  getManagedServiceConfigKey: (key: string) =>
122
126
  mockGetManagedServiceConfigKey(key),
127
+ requirePlatformConnection: (cmd: unknown) =>
128
+ mockRequirePlatformConnection(cmd),
123
129
  requirePlatformClient: async (_cmd: Command) => {
124
130
  if (
125
131
  !mockPlatformClientResult ||
@@ -130,7 +136,7 @@ mock.module("../shared.js", () => ({
130
136
  JSON.stringify({
131
137
  ok: false,
132
138
  error:
133
- "Platform prerequisites not met (not logged in or missing assistant ID)",
139
+ "Not connected to Vellum platform. Run `vellum platform connect` to connect first.",
134
140
  }) + "\n",
135
141
  );
136
142
  return null;
@@ -244,6 +250,7 @@ describe("assistant oauth mode", () => {
244
250
  mockSaveRawConfigCalls = [];
245
251
  mockSetNestedValueCalls = [];
246
252
  mockConfigServices = {};
253
+ mockRequirePlatformConnection = async () => true;
247
254
  process.exitCode = 0;
248
255
  });
249
256
 
@@ -71,7 +71,7 @@ mock.module("../../../../platform/client.js", () => ({
71
71
  }));
72
72
 
73
73
  mock.module("../../../../util/browser.js", () => ({
74
- openInBrowser: () => {},
74
+ openInHostBrowser: async () => {},
75
75
  }));
76
76
 
77
77
  mock.module("../../../../util/logger.js", () => ({
@@ -107,7 +107,7 @@ mock.module("../shared.js", () => ({
107
107
  JSON.stringify({
108
108
  ok: false,
109
109
  error:
110
- "Platform prerequisites not met (not logged in or missing assistant ID)",
110
+ "Not connected to Vellum platform. Run `vellum platform connect` to connect first.",
111
111
  }) + "\n",
112
112
  );
113
113
  return null;
@@ -2,6 +2,7 @@ import { createServer, type Server } from "node:http";
2
2
 
3
3
  import type { Command } from "commander";
4
4
 
5
+ import { getIsContainerized } from "../../../config/env-registry.js";
5
6
  import { orchestrateOAuthConnect } from "../../../oauth/connect-orchestrator.js";
6
7
  import {
7
8
  getAppByProviderAndClientId,
@@ -9,7 +10,7 @@ import {
9
10
  getProvider,
10
11
  } from "../../../oauth/oauth-store.js";
11
12
  import { renderOAuthCompletionPage } from "../../../security/oauth-completion-page.js";
12
- import { openInBrowser } from "../../../util/browser.js";
13
+ import { openInHostBrowser } from "../../../util/browser.js";
13
14
  import { getSecureKeyViaDaemon } from "../../lib/daemon-credential-client.js";
14
15
  import { getCliLogger } from "../../logger.js";
15
16
  import { shouldOutputJson, writeOutput } from "../../output.js";
@@ -178,15 +179,23 @@ Examples:
178
179
 
179
180
  // When opening the browser, start a local server to show a nice
180
181
  // completion page instead of redirecting to the platform website.
182
+ //
183
+ // In containerized mode the loopback server is unreachable from
184
+ // the host browser, so redirect to the platform's own completion
185
+ // page instead.
181
186
  let redirectServer:
182
187
  | { redirectUrl: string; cleanup: () => void }
183
188
  | undefined;
184
189
  if (opts.browser !== false) {
185
- try {
186
- redirectServer = await startManagedRedirectServer(provider);
187
- body.redirect_after_connect = redirectServer.redirectUrl;
188
- } catch {
189
- // Non-fatal fall back to platform default redirect
190
+ if (getIsContainerized()) {
191
+ body.redirect_after_connect = "/account/oauth/desktop-complete";
192
+ } else {
193
+ try {
194
+ redirectServer = await startManagedRedirectServer(provider);
195
+ body.redirect_after_connect = redirectServer.redirectUrl;
196
+ } catch {
197
+ // Non-fatal — fall back to platform default redirect
198
+ }
190
199
  }
191
200
  }
192
201
 
@@ -199,9 +208,14 @@ Examples:
199
208
 
200
209
  if (!response.ok) {
201
210
  const errorText = await response.text().catch(() => "");
202
- writeError(
203
- `Platform returned HTTP ${response.status}${errorText ? `: ${errorText}` : ""}`,
204
- );
211
+ const baseMsg = `Platform returned HTTP ${response.status}${errorText ? `: ${errorText}` : ""}`;
212
+ if (response.status === 401 || response.status === 403) {
213
+ writeError(
214
+ `${baseMsg}. Your platform session may have expired. Run \`vellum platform connect\` to reconnect.`,
215
+ );
216
+ } else {
217
+ writeError(baseMsg);
218
+ }
205
219
  return;
206
220
  }
207
221
 
@@ -229,7 +243,7 @@ Examples:
229
243
  }
230
244
  const snapshotIds = new Set(snapshotEntries.map((e) => e.id));
231
245
 
232
- openInBrowser(result.connect_url);
246
+ await openInHostBrowser(result.connect_url);
233
247
 
234
248
  if (!jsonMode) {
235
249
  log.info(
@@ -374,7 +388,7 @@ Examples:
374
388
  clientSecret,
375
389
  callbackTransport: opts.callbackTransport,
376
390
  isInteractive: opts.browser !== false,
377
- openUrl: opts.browser !== false ? openInBrowser : undefined,
391
+ openUrl: opts.browser !== false ? openInHostBrowser : undefined,
378
392
  ...(opts.scopes ? { requestedScopes: opts.scopes } : {}),
379
393
  });
380
394
 
@@ -17,6 +17,7 @@ import { shouldOutputJson, writeOutput } from "../../output.js";
17
17
  import {
18
18
  fetchActiveConnections,
19
19
  getManagedServiceConfigKey,
20
+ requirePlatformConnection,
20
21
  } from "./shared.js";
21
22
 
22
23
  /**
@@ -180,6 +181,12 @@ Examples:
180
181
  return;
181
182
  }
182
183
 
184
+ // Require platform connection when switching to managed mode
185
+ if (newMode === "managed") {
186
+ const connected = await requirePlatformConnection(cmd);
187
+ if (!connected) return;
188
+ }
189
+
183
190
  // Read current mode
184
191
  const services: Services = getConfig().services;
185
192
  const currentMode = services[managedKey as keyof Services].mode;
@@ -59,11 +59,20 @@ export async function requirePlatformClient(
59
59
  cmd: Command,
60
60
  ): Promise<VellumPlatformClient | null> {
61
61
  const client = await VellumPlatformClient.create();
62
- if (!client || !client.platformAssistantId) {
62
+ if (!client) {
63
63
  writeOutput(cmd, {
64
64
  ok: false,
65
65
  error:
66
- "Platform prerequisites not met (not logged in or missing assistant ID)",
66
+ "Not connected to Vellum platform. Run `vellum platform connect` to connect first.",
67
+ });
68
+ process.exitCode = 1;
69
+ return null;
70
+ }
71
+ if (!client.platformAssistantId) {
72
+ writeOutput(cmd, {
73
+ ok: false,
74
+ error:
75
+ "Connected to Vellum platform but no assistant ID is configured. Ensure the assistant is registered on the platform.",
67
76
  });
68
77
  process.exitCode = 1;
69
78
  return null;
@@ -71,6 +80,29 @@ export async function requirePlatformClient(
71
80
  return client;
72
81
  }
73
82
 
83
+ /**
84
+ * Verify that the user has connected to the Vellum platform (has stored
85
+ * credentials). Unlike `requirePlatformClient`, this does NOT require a
86
+ * platform assistant ID — it only checks that credentials exist.
87
+ *
88
+ * Writes an error and sets exitCode=1 when the user is not connected.
89
+ */
90
+ export async function requirePlatformConnection(
91
+ cmd: Command,
92
+ ): Promise<boolean> {
93
+ const client = await VellumPlatformClient.create();
94
+ if (!client) {
95
+ writeOutput(cmd, {
96
+ ok: false,
97
+ error:
98
+ "Not connected to Vellum platform. Run `vellum platform connect` to connect first.",
99
+ });
100
+ process.exitCode = 1;
101
+ return false;
102
+ }
103
+ return true;
104
+ }
105
+
74
106
  /**
75
107
  * Fetch active platform connections for a provider. Returns the parsed entries
76
108
  * or writes an error and returns null.
@@ -94,9 +126,13 @@ export async function fetchActiveConnections(
94
126
 
95
127
  if (!response.ok) {
96
128
  if (!options?.silent) {
129
+ const hint =
130
+ response.status === 401 || response.status === 403
131
+ ? `. Your platform session may have expired. Run \`vellum platform connect\` to reconnect.`
132
+ : "";
97
133
  writeOutput(cmd, {
98
134
  ok: false,
99
- error: `Platform returned HTTP ${response.status}`,
135
+ error: `Platform returned HTTP ${response.status}${hint}`,
100
136
  });
101
137
  process.exitCode = 1;
102
138
  }
@@ -30,7 +30,7 @@ mock.module("../../../lib/daemon-credential-client.js", () => ({
30
30
 
31
31
  mock.module("../../../../inbound/platform-callback-registration.js", () => ({
32
32
  resolvePlatformCallbackRegistrationContext: async () => ({
33
- containerized: false,
33
+ isPlatform: false,
34
34
  platformBaseUrl: "",
35
35
  assistantId: "",
36
36
  hasInternalApiKey: false,
@@ -36,7 +36,7 @@ mock.module("../../../../config/env-registry.js", () => ({
36
36
 
37
37
  mock.module("../../../../inbound/platform-callback-registration.js", () => ({
38
38
  resolvePlatformCallbackRegistrationContext: async () => ({
39
- containerized: false,
39
+ isPlatform: false,
40
40
  platformBaseUrl: "",
41
41
  assistantId: "",
42
42
  hasInternalApiKey: false,
@@ -11,7 +11,7 @@ let mockGetSecureKeyViaDaemon: (
11
11
  let mockResolvePlatformCallbackRegistrationContext: () => Promise<
12
12
  Record<string, unknown>
13
13
  > = async () => ({
14
- containerized: false,
14
+ isPlatform: false,
15
15
  platformBaseUrl: "",
16
16
  assistantId: "",
17
17
  hasInternalApiKey: false,
@@ -138,7 +138,7 @@ describe("assistant platform status", () => {
138
138
  beforeEach(() => {
139
139
  mockGetSecureKeyViaDaemon = async () => undefined;
140
140
  mockResolvePlatformCallbackRegistrationContext = async () => ({
141
- containerized: false,
141
+ isPlatform: false,
142
142
  platformBaseUrl: "",
143
143
  assistantId: "",
144
144
  hasInternalApiKey: false,
@@ -158,7 +158,7 @@ describe("assistant platform status", () => {
158
158
 
159
159
  // GIVEN a containerized environment with platform configuration
160
160
  mockResolvePlatformCallbackRegistrationContext = async () => ({
161
- containerized: true,
161
+ isPlatform: true,
162
162
  platformBaseUrl: "https://platform.vellum.ai",
163
163
  assistantId: "asst-abc-123",
164
164
  hasInternalApiKey: true,
@@ -191,7 +191,7 @@ describe("assistant platform status", () => {
191
191
 
192
192
  // AND the output contains the expected status fields
193
193
  const parsed = JSON.parse(stdout);
194
- expect(parsed.containerized).toBe(true);
194
+ expect(parsed.isPlatform).toBe(true);
195
195
  expect(parsed.baseUrl).toBe("https://platform.vellum.ai");
196
196
  expect(parsed.assistantId).toBe("asst-abc-123");
197
197
  expect(parsed.hasInternalApiKey).toBe(true);
@@ -211,7 +211,7 @@ describe("assistant platform status", () => {
211
211
 
212
212
  // GIVEN a disconnected environment with no stored credentials
213
213
  mockResolvePlatformCallbackRegistrationContext = async () => ({
214
- containerized: false,
214
+ isPlatform: false,
215
215
  platformBaseUrl: "",
216
216
  assistantId: "",
217
217
  hasInternalApiKey: false,