@vellumai/assistant 0.5.13 → 0.5.15

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 (425) hide show
  1. package/.env.example +1 -6
  2. package/AGENTS.md +4 -0
  3. package/ARCHITECTURE.md +0 -1
  4. package/bunfig.toml +1 -0
  5. package/docs/architecture/memory.md +3 -3
  6. package/openapi.yaml +127 -22
  7. package/package.json +1 -1
  8. package/src/__tests__/access-request-decision.test.ts +2 -32
  9. package/src/__tests__/actor-token-service.test.ts +1 -31
  10. package/src/__tests__/anthropic-provider.test.ts +53 -40
  11. package/src/__tests__/app-git-history.test.ts +9 -17
  12. package/src/__tests__/app-git-service.test.ts +14 -20
  13. package/src/__tests__/app-store-dir-names.test.ts +10 -20
  14. package/src/__tests__/approval-cascade.test.ts +2 -19
  15. package/src/__tests__/approval-primitive.test.ts +2 -27
  16. package/src/__tests__/approval-routes-http.test.ts +2 -30
  17. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -28
  18. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -45
  19. package/src/__tests__/attachments-store.test.ts +5 -32
  20. package/src/__tests__/audit-log-rotation.test.ts +5 -36
  21. package/src/__tests__/avatar-e2e.test.ts +1 -9
  22. package/src/__tests__/avatar-generator.test.ts +1 -7
  23. package/src/__tests__/browser-fill-credential.test.ts +0 -4
  24. package/src/__tests__/browser-manager.test.ts +0 -6
  25. package/src/__tests__/call-controller.test.ts +1 -22
  26. package/src/__tests__/call-conversation-messages.test.ts +0 -21
  27. package/src/__tests__/call-domain.test.ts +0 -25
  28. package/src/__tests__/call-pointer-messages.test.ts +0 -21
  29. package/src/__tests__/call-recovery.test.ts +0 -22
  30. package/src/__tests__/call-routes-http.test.ts +0 -24
  31. package/src/__tests__/call-store.test.ts +0 -21
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -24
  33. package/src/__tests__/canonical-guardian-store.test.ts +48 -21
  34. package/src/__tests__/channel-approval-routes.test.ts +6 -26
  35. package/src/__tests__/channel-approvals.test.ts +1 -38
  36. package/src/__tests__/channel-delivery-store.test.ts +0 -21
  37. package/src/__tests__/channel-guardian.test.ts +0 -26
  38. package/src/__tests__/channel-reply-delivery.test.ts +5 -0
  39. package/src/__tests__/channel-retry-sweep.test.ts +0 -21
  40. package/src/__tests__/checker.test.ts +26 -61
  41. package/src/__tests__/clawhub.test.ts +9 -25
  42. package/src/__tests__/cli-command-risk-guard.test.ts +0 -18
  43. package/src/__tests__/config-loader-backfill.test.ts +9 -28
  44. package/src/__tests__/config-schema-cmd.test.ts +5 -25
  45. package/src/__tests__/config-schema.test.ts +21 -40
  46. package/src/__tests__/config-watcher.test.ts +4 -91
  47. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -21
  48. package/src/__tests__/contacts-tools.test.ts +0 -21
  49. package/src/__tests__/context-memory-e2e.test.ts +0 -21
  50. package/src/__tests__/context-window-manager.test.ts +130 -3
  51. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -4
  52. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -4
  53. package/src/__tests__/conversation-agent-loop.test.ts +0 -4
  54. package/src/__tests__/conversation-attachments.test.ts +1 -24
  55. package/src/__tests__/conversation-attention-store.test.ts +0 -21
  56. package/src/__tests__/conversation-attention-telegram.test.ts +0 -22
  57. package/src/__tests__/conversation-clear-safety.test.ts +0 -22
  58. package/src/__tests__/conversation-confirmation-signals.test.ts +2 -21
  59. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -24
  60. package/src/__tests__/conversation-disk-view-integration.test.ts +1 -23
  61. package/src/__tests__/conversation-disk-view.test.ts +5 -27
  62. package/src/__tests__/conversation-error.test.ts +1 -1
  63. package/src/__tests__/conversation-fork-crud.test.ts +1 -33
  64. package/src/__tests__/conversation-fork-route.test.ts +0 -27
  65. package/src/__tests__/conversation-history-web-search.test.ts +23 -16
  66. package/src/__tests__/conversation-init.benchmark.test.ts +22 -43
  67. package/src/__tests__/conversation-key-store-disk-view.test.ts +8 -34
  68. package/src/__tests__/conversation-load-history-repair.test.ts +0 -4
  69. package/src/__tests__/conversation-pre-run-repair.test.ts +0 -4
  70. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -4
  71. package/src/__tests__/conversation-queue.test.ts +8 -8
  72. package/src/__tests__/conversation-routes-disk-view.test.ts +13 -51
  73. package/src/__tests__/conversation-runtime-assembly.test.ts +64 -38
  74. package/src/__tests__/conversation-slash-commands.test.ts +5 -0
  75. package/src/__tests__/conversation-slash-queue.test.ts +0 -4
  76. package/src/__tests__/conversation-slash-unknown.test.ts +0 -4
  77. package/src/__tests__/conversation-speed-override.test.ts +326 -0
  78. package/src/__tests__/conversation-starter-routes.test.ts +0 -23
  79. package/src/__tests__/conversation-store.test.ts +0 -21
  80. package/src/__tests__/conversation-unread-route.test.ts +0 -24
  81. package/src/__tests__/conversation-usage.test.ts +56 -21
  82. package/src/__tests__/conversation-wipe.test.ts +0 -21
  83. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
  84. package/src/__tests__/conversation-workspace-injection.test.ts +0 -4
  85. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -4
  86. package/src/__tests__/credential-execution-shell-lockdown.test.ts +8 -5
  87. package/src/__tests__/credential-vault-unit.test.ts +9 -428
  88. package/src/__tests__/credentials-cli.test.ts +10 -10
  89. package/src/__tests__/daemon-assistant-events.test.ts +0 -19
  90. package/src/__tests__/date-context.test.ts +77 -97
  91. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +7 -24
  92. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +29 -42
  93. package/src/__tests__/delete-managed-skill-tool.test.ts +2 -10
  94. package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -26
  95. package/src/__tests__/docker-signing-key-bootstrap.test.ts +61 -15
  96. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -36
  97. package/src/__tests__/email-cli.test.ts +6 -6
  98. package/src/__tests__/ephemeral-permissions.test.ts +5 -17
  99. package/src/__tests__/first-greeting.test.ts +4 -32
  100. package/src/__tests__/followup-tools.test.ts +0 -21
  101. package/src/__tests__/gateway-only-enforcement.test.ts +0 -20
  102. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -23
  103. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -23
  104. package/src/__tests__/guardian-action-followup-store.test.ts +0 -21
  105. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -21
  106. package/src/__tests__/guardian-action-late-reply.test.ts +0 -21
  107. package/src/__tests__/guardian-action-store.test.ts +0 -21
  108. package/src/__tests__/guardian-action-sweep.test.ts +0 -21
  109. package/src/__tests__/guardian-binding-drift-heal.test.ts +0 -23
  110. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +172 -22
  111. package/src/__tests__/guardian-dispatch.test.ts +0 -21
  112. package/src/__tests__/guardian-grant-minting.test.ts +0 -22
  113. package/src/__tests__/guardian-outbound-http.test.ts +0 -22
  114. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -23
  115. package/src/__tests__/guardian-routing-invariants.test.ts +0 -22
  116. package/src/__tests__/guardian-routing-state.test.ts +0 -22
  117. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -24
  118. package/src/__tests__/headless-browser-interactions.test.ts +0 -4
  119. package/src/__tests__/headless-browser-navigate.test.ts +0 -4
  120. package/src/__tests__/headless-browser-read-tools.test.ts +0 -4
  121. package/src/__tests__/headless-browser-snapshot.test.ts +0 -4
  122. package/src/__tests__/heartbeat-service.test.ts +99 -26
  123. package/src/__tests__/hooks-blocking.test.ts +3 -3
  124. package/src/__tests__/hooks-config.test.ts +7 -7
  125. package/src/__tests__/hooks-discovery.test.ts +3 -3
  126. package/src/__tests__/hooks-integration.test.ts +5 -5
  127. package/src/__tests__/hooks-manager.test.ts +3 -3
  128. package/src/__tests__/hooks-runner.test.ts +5 -23
  129. package/src/__tests__/hooks-settings.test.ts +3 -3
  130. package/src/__tests__/hooks-templates.test.ts +3 -3
  131. package/src/__tests__/http-conversation-lineage.test.ts +0 -27
  132. package/src/__tests__/identity-intro-cache.test.ts +0 -4
  133. package/src/__tests__/inbound-invite-redemption.test.ts +0 -22
  134. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -16
  135. package/src/__tests__/intent-routing.test.ts +2 -55
  136. package/src/__tests__/invite-redemption-service.test.ts +0 -21
  137. package/src/__tests__/invite-routes-http.test.ts +0 -21
  138. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +0 -17
  139. package/src/__tests__/journal-context.test.ts +8 -75
  140. package/src/__tests__/list-messages-attachments.test.ts +0 -22
  141. package/src/__tests__/llm-context-route-provider.test.ts +0 -21
  142. package/src/__tests__/llm-request-log-turn-query.test.ts +46 -28
  143. package/src/__tests__/llm-usage-store.test.ts +0 -21
  144. package/src/__tests__/log-export-workspace.test.ts +1 -1
  145. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -1
  146. package/src/__tests__/managed-store.test.ts +1 -1
  147. package/src/__tests__/mcp-cli.test.ts +7 -10
  148. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -21
  149. package/src/__tests__/memory-jobs-worker-backoff.test.ts +0 -11
  150. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -21
  151. package/src/__tests__/memory-recall-log-store.test.ts +0 -27
  152. package/src/__tests__/memory-recall-quality.test.ts +0 -21
  153. package/src/__tests__/memory-regressions.experimental.test.ts +31 -30
  154. package/src/__tests__/memory-regressions.test.ts +282 -70
  155. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -21
  156. package/src/__tests__/memory-upsert-concurrency.test.ts +0 -21
  157. package/src/__tests__/messaging-send-tool.test.ts +201 -0
  158. package/src/__tests__/migration-cross-version-compatibility.test.ts +18 -13
  159. package/src/__tests__/migration-export-http.test.ts +7 -1
  160. package/src/__tests__/migration-import-commit-http.test.ts +16 -14
  161. package/src/__tests__/migration-import-preflight-http.test.ts +27 -44
  162. package/src/__tests__/migration-validate-http.test.ts +1 -28
  163. package/src/__tests__/native-web-search.test.ts +25 -22
  164. package/src/__tests__/non-member-access-request.test.ts +0 -22
  165. package/src/__tests__/notification-guardian-path.test.ts +0 -21
  166. package/src/__tests__/notification-schedule-dedup.test.ts +1 -25
  167. package/src/__tests__/oauth-apps-routes.test.ts +103 -2
  168. package/src/__tests__/oauth-cli.test.ts +52 -0
  169. package/src/__tests__/oauth-provider-profiles.test.ts +0 -16
  170. package/src/__tests__/oauth-provider-serializer.test.ts +232 -0
  171. package/src/__tests__/oauth-providers-routes.test.ts +257 -0
  172. package/src/__tests__/oauth-store.test.ts +0 -21
  173. package/src/__tests__/onboarding-template-contract.test.ts +2 -2
  174. package/src/__tests__/openai-provider.test.ts +261 -0
  175. package/src/__tests__/pairing-concurrent.test.ts +6 -6
  176. package/src/__tests__/pairing-routes.test.ts +7 -1
  177. package/src/__tests__/path-policy.test.ts +1 -1
  178. package/src/__tests__/platform.test.ts +64 -88
  179. package/src/__tests__/playbook-execution.test.ts +0 -21
  180. package/src/__tests__/playbook-tools.test.ts +0 -21
  181. package/src/__tests__/pricing.test.ts +100 -0
  182. package/src/__tests__/relay-server.test.ts +1 -25
  183. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -24
  184. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -24
  185. package/src/__tests__/runtime-events-sse.test.ts +0 -24
  186. package/src/__tests__/sandbox-diagnostics.test.ts +2 -1
  187. package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -1
  188. package/src/__tests__/schedule-store.test.ts +0 -21
  189. package/src/__tests__/schedule-tools.test.ts +0 -21
  190. package/src/__tests__/scheduler-recurrence.test.ts +0 -21
  191. package/src/__tests__/scoped-approval-grants.test.ts +0 -21
  192. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -21
  193. package/src/__tests__/secret-allowlist.test.ts +1 -1
  194. package/src/__tests__/secret-ingress-channel.test.ts +0 -5
  195. package/src/__tests__/secret-ingress-cli.test.ts +0 -6
  196. package/src/__tests__/secret-ingress-http.test.ts +0 -5
  197. package/src/__tests__/secret-ingress.test.ts +0 -5
  198. package/src/__tests__/send-endpoint-busy.test.ts +0 -24
  199. package/src/__tests__/sequence-store.test.ts +0 -21
  200. package/src/__tests__/server-history-render.test.ts +0 -24
  201. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -4
  202. package/src/__tests__/skill-load-inline-command.test.ts +9 -0
  203. package/src/__tests__/skill-load-inline-includes.test.ts +9 -0
  204. package/src/__tests__/skill-load-tool.test.ts +11 -0
  205. package/src/__tests__/skills-uninstall.test.ts +10 -8
  206. package/src/__tests__/skills.test.ts +1 -1
  207. package/src/__tests__/slack-channel-config.test.ts +1 -1
  208. package/src/__tests__/slack-inbound-verification.test.ts +0 -22
  209. package/src/__tests__/starter-bundle.test.ts +4 -1
  210. package/src/__tests__/suggestion-routes.test.ts +2 -0
  211. package/src/__tests__/system-prompt.test.ts +1 -1
  212. package/src/__tests__/terminal-tools.test.ts +1 -1
  213. package/src/__tests__/test-preload.ts +31 -0
  214. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -1
  215. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
  216. package/src/__tests__/tool-executor.test.ts +0 -20
  217. package/src/__tests__/tool-input-summary.test.ts +124 -0
  218. package/src/__tests__/tool-preview-lifecycle.test.ts +2 -1
  219. package/src/__tests__/trust-store.test.ts +7 -1
  220. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -1
  221. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +1 -1
  222. package/src/__tests__/trusted-contact-multichannel.test.ts +1 -1
  223. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  224. package/src/__tests__/turn-boundary-resolution.test.ts +1 -1
  225. package/src/__tests__/twilio-routes.test.ts +1 -1
  226. package/src/__tests__/update-bulletin.test.ts +1 -1
  227. package/src/__tests__/vbundle-pax-and-symlink.test.ts +1 -1
  228. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -0
  229. package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -1
  230. package/src/__tests__/voice-session-bridge.test.ts +1 -1
  231. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +4 -4
  232. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -1
  233. package/src/__tests__/workspace-migration-down-functions.test.ts +15 -3
  234. package/src/__tests__/workspace-migration-seed-device-id.test.ts +40 -4
  235. package/src/agent/loop.ts +6 -9
  236. package/src/approvals/guardian-decision-primitive.ts +46 -18
  237. package/src/approvals/guardian-request-resolvers.ts +19 -2
  238. package/src/calls/active-call-lease.ts +2 -2
  239. package/src/cli/AGENTS.md +1 -1
  240. package/src/cli/commands/doctor.ts +9 -9
  241. package/src/cli/commands/memory.ts +142 -0
  242. package/src/cli/commands/oauth/__tests__/connect.test.ts +13 -11
  243. package/src/cli/commands/oauth/__tests__/ping.test.ts +1 -1
  244. package/src/cli/commands/oauth/connect.ts +13 -12
  245. package/src/cli/commands/oauth/index.ts +1 -1
  246. package/src/cli/commands/oauth/providers.ts +47 -62
  247. package/src/cli/commands/platform/__tests__/connect.test.ts +72 -46
  248. package/src/cli/commands/platform/__tests__/disconnect.test.ts +54 -1
  249. package/src/cli/commands/platform/__tests__/status.test.ts +36 -0
  250. package/src/cli/commands/platform/connect.ts +17 -7
  251. package/src/cli/commands/platform/disconnect.ts +28 -3
  252. package/src/cli/commands/platform/index.ts +3 -3
  253. package/src/cli.ts +1 -299
  254. package/src/config/assistant-feature-flags.ts +23 -15
  255. package/src/config/bundled-skills/app-builder/TOOLS.json +16 -0
  256. package/src/config/bundled-skills/app-builder/tools/app-create.ts +4 -0
  257. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +5 -1
  258. package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +9 -1
  259. package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +5 -1
  260. package/src/config/bundled-skills/contacts/TOOLS.json +8 -0
  261. package/src/config/bundled-skills/contacts/tools/contact-search.ts +10 -1
  262. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +16 -2
  263. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +1 -0
  264. package/src/config/bundled-skills/messaging/SKILL.md +7 -7
  265. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +37 -0
  266. package/src/config/bundled-skills/slack/SKILL.md +18 -0
  267. package/src/config/env-registry.ts +15 -11
  268. package/src/config/env.ts +1 -11
  269. package/src/config/feature-flag-registry.json +16 -0
  270. package/src/config/schema.ts +4 -0
  271. package/src/config/schemas/heartbeat.ts +6 -1
  272. package/src/config/schemas/inference.ts +14 -3
  273. package/src/config/schemas/memory-processing.ts +16 -8
  274. package/src/config/schemas/memory-retrieval.ts +3 -3
  275. package/src/config/skills.ts +1 -1
  276. package/src/context/window-manager.ts +174 -51
  277. package/src/credential-execution/executable-discovery.ts +2 -2
  278. package/src/daemon/approved-devices-store.ts +2 -2
  279. package/src/daemon/assistant-attachments.ts +2 -0
  280. package/src/daemon/config-watcher.ts +4 -50
  281. package/src/daemon/conversation-agent-loop-handlers.ts +9 -1
  282. package/src/daemon/conversation-agent-loop.ts +12 -0
  283. package/src/daemon/conversation-error.ts +3 -5
  284. package/src/daemon/conversation-history.ts +7 -3
  285. package/src/daemon/conversation-lifecycle.ts +16 -0
  286. package/src/daemon/conversation-messaging.ts +1 -0
  287. package/src/daemon/conversation-notifiers.ts +67 -30
  288. package/src/daemon/conversation-process.ts +161 -2
  289. package/src/daemon/conversation-queue-manager.ts +2 -0
  290. package/src/daemon/conversation-runtime-assembly.ts +33 -11
  291. package/src/daemon/conversation-slash.ts +14 -3
  292. package/src/daemon/conversation-tool-setup.ts +2 -0
  293. package/src/daemon/conversation-usage.ts +32 -4
  294. package/src/daemon/conversation.ts +33 -1
  295. package/src/daemon/daemon-control.ts +32 -16
  296. package/src/daemon/date-context.ts +47 -45
  297. package/src/daemon/dictation-profile-store.ts +2 -2
  298. package/src/daemon/handlers/conversations.ts +19 -0
  299. package/src/daemon/handlers/shared.ts +14 -21
  300. package/src/daemon/lifecycle.ts +5 -7
  301. package/src/daemon/message-types/conversations.ts +2 -0
  302. package/src/daemon/message-types/guardian-actions.ts +3 -17
  303. package/src/daemon/message-types/integrations.ts +11 -1
  304. package/src/daemon/message-types/messages.ts +1 -0
  305. package/src/daemon/pairing-store.ts +2 -79
  306. package/src/daemon/server.ts +154 -8
  307. package/src/daemon/watch-handler.ts +65 -21
  308. package/src/email/guardrails.ts +3 -3
  309. package/src/heartbeat/heartbeat-service.ts +14 -7
  310. package/src/hooks/cli.ts +2 -2
  311. package/src/hooks/config.ts +2 -2
  312. package/src/hooks/discovery.ts +2 -2
  313. package/src/hooks/manager.ts +2 -2
  314. package/src/hooks/runner.ts +5 -2
  315. package/src/hooks/templates.ts +2 -2
  316. package/src/memory/admin.ts +181 -2
  317. package/src/memory/app-git-service.ts +61 -4
  318. package/src/memory/attachments-store.ts +2 -0
  319. package/src/memory/canonical-guardian-store.ts +16 -0
  320. package/src/memory/db-init.ts +8 -0
  321. package/src/memory/embedding-local.ts +5 -2
  322. package/src/memory/indexer.ts +44 -26
  323. package/src/memory/items-extractor.ts +34 -82
  324. package/src/memory/job-handlers/batch-extraction.ts +741 -0
  325. package/src/memory/job-handlers/journal-carry-forward.test.ts +383 -0
  326. package/src/memory/job-handlers/journal-carry-forward.ts +255 -0
  327. package/src/memory/jobs-store.ts +28 -0
  328. package/src/memory/jobs-worker.ts +56 -9
  329. package/src/memory/lifecycle-events-store.ts +4 -2
  330. package/src/memory/llm-request-log-store.ts +40 -2
  331. package/src/memory/llm-usage-store.ts +4 -3
  332. package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +71 -0
  333. package/src/memory/migrations/200-usage-llm-call-count.ts +20 -0
  334. package/src/memory/migrations/index.ts +2 -0
  335. package/src/memory/query-expansion.ts +83 -0
  336. package/src/memory/retriever.test.ts +119 -0
  337. package/src/memory/retriever.ts +513 -105
  338. package/src/memory/schema/guardian.ts +4 -0
  339. package/src/memory/schema/infrastructure.ts +1 -0
  340. package/src/memory/search/formatting.test.ts +140 -0
  341. package/src/memory/search/formatting.ts +143 -198
  342. package/src/memory/search/mmr.ts +136 -0
  343. package/src/memory/search/staleness.ts +0 -15
  344. package/src/memory/search/tier-classifier.ts +10 -21
  345. package/src/memory/search/types.ts +17 -0
  346. package/src/messaging/providers/slack/adapter.ts +51 -5
  347. package/src/notifications/broadcaster.ts +13 -0
  348. package/src/notifications/copy-composer.ts +8 -0
  349. package/src/oauth/connect-orchestrator.ts +1 -1
  350. package/src/oauth/connection-resolver.ts +2 -2
  351. package/src/oauth/provider-serializer.ts +116 -0
  352. package/src/permissions/trust-store.ts +24 -7
  353. package/src/prompts/__tests__/build-cli-reference-section.test.ts +5 -0
  354. package/src/prompts/journal-context.ts +50 -35
  355. package/src/prompts/persona-resolver.ts +1 -1
  356. package/src/prompts/system-prompt.ts +27 -28
  357. package/src/prompts/templates/BOOTSTRAP.md +14 -1
  358. package/src/prompts/templates/HEARTBEAT.md +10 -0
  359. package/src/prompts/templates/NOW.md +19 -25
  360. package/src/prompts/templates/SOUL.md +13 -1
  361. package/src/prompts/templates/UPDATES.md +12 -0
  362. package/src/prompts/update-bulletin.ts +1 -1
  363. package/src/providers/anthropic/client.ts +89 -18
  364. package/src/providers/model-catalog.ts +22 -2
  365. package/src/providers/model-intents.ts +2 -2
  366. package/src/providers/openai/client.ts +40 -1
  367. package/src/providers/retry.ts +23 -4
  368. package/src/providers/types.ts +2 -0
  369. package/src/runtime/assistant-scope.ts +1 -1
  370. package/src/runtime/auth/__tests__/credential-service.test.ts +1 -0
  371. package/src/runtime/auth/route-policy.ts +1 -0
  372. package/src/runtime/auth/token-service.ts +51 -29
  373. package/src/runtime/confirmation-request-guardian-bridge.ts +3 -1
  374. package/src/runtime/guardian-decision-types.ts +16 -10
  375. package/src/runtime/http-server.ts +3 -14
  376. package/src/runtime/http-types.ts +1 -0
  377. package/src/runtime/migrations/vbundle-builder.ts +7 -4
  378. package/src/runtime/migrations/vbundle-import-analyzer.ts +0 -4
  379. package/src/runtime/migrations/vbundle-importer.ts +1 -1
  380. package/src/runtime/routes/conversation-query-routes.ts +40 -8
  381. package/src/runtime/routes/conversation-routes.ts +125 -3
  382. package/src/runtime/routes/guardian-action-routes.ts +9 -3
  383. package/src/runtime/routes/identity-routes.ts +25 -4
  384. package/src/runtime/routes/llm-context-normalization.ts +1 -0
  385. package/src/runtime/routes/log-export-routes.ts +34 -12
  386. package/src/runtime/routes/migration-routes.ts +6 -10
  387. package/src/runtime/routes/oauth-apps.ts +2 -9
  388. package/src/runtime/routes/oauth-providers.ts +60 -0
  389. package/src/runtime/routes/pairing-routes.ts +0 -8
  390. package/src/runtime/routes/settings-routes.ts +0 -1
  391. package/src/runtime/routes/telemetry-routes.ts +16 -4
  392. package/src/security/encrypted-store.ts +2 -2
  393. package/src/security/secret-allowlist.ts +3 -3
  394. package/src/signals/emit-event.ts +42 -0
  395. package/src/signals/user-message.ts +37 -0
  396. package/src/telemetry/usage-telemetry-reporter.test.ts +83 -19
  397. package/src/telemetry/usage-telemetry-reporter.ts +23 -17
  398. package/src/tools/browser/runtime-check.ts +2 -2
  399. package/src/tools/credentials/vault.ts +2 -249
  400. package/src/tools/memory/definitions.ts +1 -1
  401. package/src/tools/memory/handlers.test.ts +50 -8
  402. package/src/tools/memory/handlers.ts +3 -1
  403. package/src/tools/side-effects.ts +1 -6
  404. package/src/tools/terminal/safe-env.ts +3 -2
  405. package/src/tools/terminal/shell.ts +11 -14
  406. package/src/tools/tool-approval-handler.ts +20 -1
  407. package/src/tools/tool-input-summary.ts +66 -0
  408. package/src/tools/types.ts +4 -0
  409. package/src/usage/types.ts +4 -0
  410. package/src/util/device-id.ts +10 -10
  411. package/src/util/platform.ts +71 -33
  412. package/src/util/pricing.ts +19 -6
  413. package/src/util/strip-comment-lines.ts +28 -0
  414. package/src/workspace/git-service.ts +8 -18
  415. package/src/workspace/migrations/003-seed-device-id.ts +6 -4
  416. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +7 -1
  417. package/src/workspace/migrations/017-seed-persona-dirs.ts +2 -4
  418. package/src/workspace/migrations/021-move-signals-to-workspace.ts +84 -0
  419. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +94 -0
  420. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +86 -0
  421. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +126 -0
  422. package/src/workspace/migrations/migrate-to-workspace-volume.ts +3 -6
  423. package/src/workspace/migrations/registry.ts +8 -0
  424. package/src/signals/confirm.ts +0 -82
  425. package/src/signals/trust-rule.ts +0 -174
@@ -48,27 +48,10 @@ mock.module("../tools/registry.js", () => ({
48
48
  // Mock oauth-store to avoid SQLite dependency in unit tests
49
49
  // ---------------------------------------------------------------------------
50
50
 
51
- let mockGetMostRecentAppByProvider: ReturnType<
52
- typeof mock<(key: string) => unknown>
53
- >;
54
- let mockGetAppByProviderAndClientId: ReturnType<
55
- typeof mock<(key: string, clientId: string) => unknown>
56
- >;
57
- let mockGetProvider: ReturnType<typeof mock<(key: string) => unknown>>;
58
-
59
- mock.module("../oauth/oauth-store.js", () => {
60
- mockGetMostRecentAppByProvider = mock(() => undefined);
61
- mockGetAppByProviderAndClientId = mock(() => undefined);
62
- mockGetProvider = mock(() => undefined);
63
- return {
64
- getMostRecentAppByProvider: mockGetMostRecentAppByProvider,
65
- getAppByProviderAndClientId: mockGetAppByProviderAndClientId,
66
- getProvider: mockGetProvider,
67
- listConnections: mock(() => []),
68
- seedProviders: mock(() => {}),
69
- disconnectOAuthProvider: mock(async () => "not-found" as const),
70
- };
71
- });
51
+ mock.module("../oauth/oauth-store.js", () => ({
52
+ disconnectOAuthProvider: mock(async () => "not-found" as const),
53
+ getActiveConnection: mock(() => undefined),
54
+ }));
72
55
 
73
56
  let manualConnectionStore: Record<string, string> = {};
74
57
  let slackChannelConfigCalls: Array<{
@@ -181,36 +164,6 @@ mock.module("../daemon/handlers/config-slack-channel.js", () => ({
181
164
  },
182
165
  }));
183
166
 
184
- // ---------------------------------------------------------------------------
185
- // Mock public ingress URL — not available in unit tests. The connect
186
- // orchestrator dynamically imports this for non-interactive flows.
187
- // ---------------------------------------------------------------------------
188
-
189
- mock.module("../inbound/public-ingress-urls.js", () => ({
190
- getPublicBaseUrl: () => {
191
- throw new Error("No public ingress URL configured");
192
- },
193
- }));
194
-
195
- // ---------------------------------------------------------------------------
196
- // Mock prepareOAuth2Flow — unit tests should not start real loopback HTTP
197
- // servers. The connect orchestrator still runs its own validation logic
198
- // (scope policy, non-interactive ingress checks, etc.) but the actual
199
- // OAuth flow setup is stubbed.
200
- // ---------------------------------------------------------------------------
201
-
202
- mock.module("../security/oauth2.js", () => ({
203
- prepareOAuth2Flow: mock(async () => ({
204
- authUrl: "https://mock-auth-url.example.com/authorize",
205
- state: "mock-state",
206
- completion: new Promise(() => {}),
207
- })),
208
- startOAuth2Flow: mock(async () => ({
209
- grantedScopes: [],
210
- tokens: { access_token: "mock-token" },
211
- })),
212
- }));
213
-
214
167
  // ---------------------------------------------------------------------------
215
168
  // Imports under test
216
169
  // ---------------------------------------------------------------------------
@@ -749,372 +702,7 @@ describe("credential_store tool — prompt action", () => {
749
702
  });
750
703
 
751
704
  // ---------------------------------------------------------------------------
752
- // 4. Vault — oauth2_connect error paths
753
- // ---------------------------------------------------------------------------
754
-
755
- describe("credential_store tool — oauth2_connect error paths", () => {
756
- /** Well-known provider rows returned by the mocked getProvider */
757
- const wellKnownProviders: Record<string, object> = {
758
- google: {
759
- key: "google",
760
- authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
761
- tokenUrl: "https://oauth2.googleapis.com/token",
762
- defaultScopes: JSON.stringify(["https://mail.google.com/"]),
763
- scopePolicy: JSON.stringify({}),
764
- callbackTransport: "loopback",
765
- loopbackPort: 8756,
766
- },
767
- slack: {
768
- key: "slack",
769
- authUrl: "https://slack.com/oauth/v2/authorize",
770
- tokenUrl: "https://slack.com/api/oauth.v2.access",
771
- defaultScopes: JSON.stringify(["channels:read"]),
772
- scopePolicy: JSON.stringify({}),
773
- },
774
- };
775
-
776
- beforeEach(() => {
777
- if (existsSync(TEST_DIR)) rmSync(TEST_DIR, { recursive: true });
778
- mkdirSync(TEST_DIR, { recursive: true });
779
- _setStorePath(STORE_PATH);
780
- _resetBackend();
781
- _setMetadataPath(join(TEST_DIR, "metadata.json"));
782
- // Return well-known provider rows so vault.ts knows google/slack are
783
- // registered, and custom providers return undefined.
784
- mockGetProvider.mockImplementation(
785
- (key: string) => wellKnownProviders[key] ?? undefined,
786
- );
787
- mockGetMostRecentAppByProvider.mockClear();
788
- mockGetMostRecentAppByProvider.mockImplementation(() => undefined);
789
- mockGetAppByProviderAndClientId.mockClear();
790
- mockGetAppByProviderAndClientId.mockImplementation(() => undefined);
791
- });
792
-
793
- afterEach(() => {
794
- _setMetadataPath(null);
795
- _setStorePath(null);
796
- _resetBackend();
797
- mockGetProvider.mockImplementation(() => undefined);
798
- mockGetMostRecentAppByProvider.mockImplementation(() => undefined);
799
- mockGetAppByProviderAndClientId.mockImplementation(() => undefined);
800
- });
801
-
802
- test("requires service parameter", async () => {
803
- const result = await credentialStoreTool.execute(
804
- { action: "oauth2_connect" },
805
- _ctx,
806
- );
807
- expect(result.isError).toBe(true);
808
- expect(result.content).toContain("service is required");
809
- });
810
-
811
- test("rejects unknown service without registered provider", async () => {
812
- const result = await credentialStoreTool.execute(
813
- {
814
- action: "oauth2_connect",
815
- service: "custom-svc",
816
- auth_url: "https://a",
817
- token_url: "https://t",
818
- scopes: ["read"],
819
- },
820
- _ctx,
821
- );
822
- expect(result.isError).toBe(true);
823
- expect(result.content).toContain("no OAuth provider registered");
824
- });
825
-
826
- test("requires client_id", async () => {
827
- mockGetProvider.mockImplementation((key: string) => {
828
- if (key === "custom-svc") {
829
- return {
830
- key: "custom-svc",
831
- authUrl: "https://auth.example.com",
832
- tokenUrl: "https://token.example.com",
833
- defaultScopes: JSON.stringify(["read"]),
834
- scopePolicy: JSON.stringify({}),
835
- };
836
- }
837
- return wellKnownProviders[key] ?? undefined;
838
- });
839
- const result = await credentialStoreTool.execute(
840
- {
841
- action: "oauth2_connect",
842
- service: "custom-svc",
843
- scopes: ["read"],
844
- },
845
- _ctx,
846
- );
847
- expect(result.isError).toBe(true);
848
- expect(result.content).toContain("client_id is required");
849
- });
850
-
851
- test("non-interactive loopback oauth2_connect returns deferred auth URL", async () => {
852
- // After the blanket non-interactive guard was removed (#16337),
853
- // loopback-transport flows succeed with a deferred auth URL so the
854
- // agent can present it to the user.
855
- mockGetProvider.mockImplementation((key: string) => {
856
- if (key === "custom-svc") {
857
- return {
858
- key: "custom-svc",
859
- authUrl: "https://auth.example.com",
860
- tokenUrl: "https://token.example.com",
861
- defaultScopes: JSON.stringify(["read"]),
862
- scopePolicy: JSON.stringify({}),
863
- };
864
- }
865
- return wellKnownProviders[key] ?? undefined;
866
- });
867
-
868
- const result = await credentialStoreTool.execute(
869
- {
870
- action: "oauth2_connect",
871
- service: "custom-svc",
872
- auth_url: "https://auth.example.com",
873
- token_url: "https://token.example.com",
874
- scopes: ["read"],
875
- client_id: "test-client-id",
876
- },
877
- { ..._ctx, isInteractive: false },
878
- );
879
- expect(result.isError).toBe(false);
880
- expect(result.content).toContain("mock-auth-url.example.com");
881
- });
882
-
883
- test("rejects missing client_id for google", async () => {
884
- // Missing client_id should fail
885
- const result = await credentialStoreTool.execute(
886
- {
887
- action: "oauth2_connect",
888
- service: "google",
889
- },
890
- _ctx,
891
- );
892
- expect(result.isError).toBe(true);
893
- // Should fail on client_id since none is stored
894
- expect(result.content).toContain("client_id is required");
895
- });
896
-
897
- test("resolves slack to its canonical name", async () => {
898
- const result = await credentialStoreTool.execute(
899
- {
900
- action: "oauth2_connect",
901
- service: "slack",
902
- },
903
- _ctx,
904
- );
905
- expect(result.isError).toBe(true);
906
- expect(result.content).toContain("client_id is required");
907
- });
908
-
909
- test("uses stored client_id from oauth-store DB", async () => {
910
- // Mock getMostRecentAppByProvider to return an app with a client_id
911
- // and store client_secret in the secure store.
912
- mockGetMostRecentAppByProvider.mockImplementation(() => ({
913
- id: "test-app-id",
914
- providerKey: "google",
915
- clientId: "stored-client-id-123",
916
- clientSecretCredentialPath: "oauth_app/test-app-id/client_secret",
917
- createdAt: Date.now(),
918
- }));
919
- mockGetProvider.mockImplementation(() => ({
920
- key: "google",
921
- authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
922
- tokenUrl: "https://oauth2.googleapis.com/token",
923
- defaultScopes: JSON.stringify(["https://mail.google.com/"]),
924
- scopePolicy: JSON.stringify({}),
925
- callbackTransport: "loopback",
926
- loopbackPort: 8756,
927
- }));
928
- await setSecureKeyAsync(
929
- "oauth_app/test-app-id/client_secret",
930
- "test-secret",
931
- );
932
-
933
- const result = await credentialStoreTool.execute(
934
- {
935
- action: "oauth2_connect",
936
- service: "google",
937
- },
938
- { ..._ctx, isInteractive: false },
939
- );
940
-
941
- // Should pass client_id and client_secret checks — the flow proceeds
942
- // through the channel path (google uses loopback transport so no
943
- // public ingress URL is needed) and returns the authorization URL.
944
- expect(result.isError).toBe(false);
945
- expect(result.content).toContain("To connect google, open this link");
946
- expect(result.content).not.toContain("client_id is required");
947
- expect(result.content).not.toContain("client_secret is required");
948
-
949
- // Reset mocks
950
- mockGetMostRecentAppByProvider.mockImplementation(() => undefined);
951
- mockGetProvider.mockImplementation(() => undefined);
952
- });
953
-
954
- test("uses getAppByProviderAndClientId when client_id is provided without client_secret", async () => {
955
- // When client_id is supplied but client_secret is not, the vault should
956
- // look up the matching app via getAppByProviderAndClientId (not the
957
- // most-recent-app heuristic) so the secret comes from the correct app.
958
- mockGetAppByProviderAndClientId.mockImplementation(
959
- (providerKey: string, cId: string) => {
960
- if (providerKey === "google" && cId === "caller-supplied-client-id") {
961
- return {
962
- id: "matched-app-id",
963
- providerKey: "google",
964
- clientId: "caller-supplied-client-id",
965
- clientSecretCredentialPath:
966
- "oauth_app/matched-app-id/client_secret",
967
- createdAt: Date.now(),
968
- };
969
- }
970
- return undefined;
971
- },
972
- );
973
- mockGetProvider.mockImplementation(() => ({
974
- key: "google",
975
- authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
976
- tokenUrl: "https://oauth2.googleapis.com/token",
977
- defaultScopes: JSON.stringify(["https://mail.google.com/"]),
978
- scopePolicy: JSON.stringify({}),
979
- callbackTransport: "loopback",
980
- loopbackPort: 8756,
981
- }));
982
- await setSecureKeyAsync(
983
- "oauth_app/matched-app-id/client_secret",
984
- "matched-secret",
985
- );
986
-
987
- const result = await credentialStoreTool.execute(
988
- {
989
- action: "oauth2_connect",
990
- service: "google",
991
- client_id: "caller-supplied-client-id",
992
- },
993
- { ..._ctx, isInteractive: false },
994
- );
995
-
996
- // Should succeed — client_secret resolved from the matched app
997
- expect(result.isError).toBe(false);
998
- expect(result.content).toContain("To connect google, open this link");
999
- // getMostRecentAppByProvider should NOT have been called since client_id was known
1000
- expect(mockGetMostRecentAppByProvider).not.toHaveBeenCalled();
1001
-
1002
- // Reset mocks
1003
- mockGetAppByProviderAndClientId.mockImplementation(() => undefined);
1004
- mockGetProvider.mockImplementation(() => undefined);
1005
- });
1006
-
1007
- test("falls back to getMostRecentAppByProvider when client_id is not provided", async () => {
1008
- // When neither client_id nor client_secret is provided, the vault should
1009
- // use getMostRecentAppByProvider (the fallback heuristic).
1010
- mockGetMostRecentAppByProvider.mockImplementation(() => ({
1011
- id: "recent-app-id",
1012
- providerKey: "google",
1013
- clientId: "recent-client-id",
1014
- clientSecretCredentialPath: "oauth_app/recent-app-id/client_secret",
1015
- createdAt: Date.now(),
1016
- }));
1017
- mockGetProvider.mockImplementation(() => ({
1018
- key: "google",
1019
- authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
1020
- tokenUrl: "https://oauth2.googleapis.com/token",
1021
- defaultScopes: JSON.stringify(["https://mail.google.com/"]),
1022
- scopePolicy: JSON.stringify({}),
1023
- callbackTransport: "loopback",
1024
- loopbackPort: 8756,
1025
- }));
1026
- await setSecureKeyAsync(
1027
- "oauth_app/recent-app-id/client_secret",
1028
- "recent-secret",
1029
- );
1030
-
1031
- const result = await credentialStoreTool.execute(
1032
- {
1033
- action: "oauth2_connect",
1034
- service: "google",
1035
- },
1036
- { ..._ctx, isInteractive: false },
1037
- );
1038
-
1039
- expect(result.isError).toBe(false);
1040
- expect(result.content).toContain("To connect google, open this link");
1041
- // getAppByProviderAndClientId should NOT have been called since client_id was unknown
1042
- expect(mockGetAppByProviderAndClientId).not.toHaveBeenCalled();
1043
-
1044
- // Reset mocks
1045
- mockGetMostRecentAppByProvider.mockImplementation(() => undefined);
1046
- mockGetProvider.mockImplementation(() => undefined);
1047
- });
1048
-
1049
- test("getAppByProviderAndClientId returning undefined leaves client_secret unresolved", async () => {
1050
- // When client_id is provided but getAppByProviderAndClientId returns no
1051
- // matching app, client_secret remains unresolved and the vault should
1052
- // report the missing secret error.
1053
- mockGetAppByProviderAndClientId.mockImplementation(() => undefined);
1054
- mockGetProvider.mockImplementation(() => ({
1055
- key: "google",
1056
- authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
1057
- tokenUrl: "https://oauth2.googleapis.com/token",
1058
- defaultScopes: JSON.stringify(["https://mail.google.com/"]),
1059
- requiresClientSecret: 1,
1060
- }));
1061
-
1062
- const result = await credentialStoreTool.execute(
1063
- {
1064
- action: "oauth2_connect",
1065
- service: "google",
1066
- client_id: "unknown-client-id",
1067
- },
1068
- _ctx,
1069
- );
1070
-
1071
- expect(result.isError).toBe(true);
1072
- expect(result.content).toContain("client_secret is required for google");
1073
- // getMostRecentAppByProvider should NOT have been called
1074
- expect(mockGetMostRecentAppByProvider).not.toHaveBeenCalled();
1075
-
1076
- // Reset mocks
1077
- mockGetAppByProviderAndClientId.mockImplementation(() => undefined);
1078
- mockGetProvider.mockImplementation(() => undefined);
1079
- });
1080
-
1081
- test("rejects when client_secret is missing for service that requires it", async () => {
1082
- // Mock getMostRecentAppByProvider to return an app with client_id but
1083
- // no client_secret in secure storage — validates the requiresClientSecret
1084
- // guardrail.
1085
- mockGetMostRecentAppByProvider.mockImplementation(() => ({
1086
- id: "test-app-id-no-secret",
1087
- providerKey: "google",
1088
- clientId: "stored-client-id-456",
1089
- createdAt: Date.now(),
1090
- }));
1091
- mockGetProvider.mockImplementation(() => ({
1092
- key: "google",
1093
- authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
1094
- tokenUrl: "https://oauth2.googleapis.com/token",
1095
- defaultScopes: JSON.stringify(["https://mail.google.com/"]),
1096
- requiresClientSecret: 1,
1097
- }));
1098
-
1099
- const result = await credentialStoreTool.execute(
1100
- {
1101
- action: "oauth2_connect",
1102
- service: "google",
1103
- },
1104
- _ctx,
1105
- );
1106
-
1107
- expect(result.isError).toBe(true);
1108
- expect(result.content).toContain("client_secret is required for google");
1109
-
1110
- // Reset mocks
1111
- mockGetMostRecentAppByProvider.mockImplementation(() => undefined);
1112
- mockGetProvider.mockImplementation(() => undefined);
1113
- });
1114
- });
1115
-
1116
- // ---------------------------------------------------------------------------
1117
- // 5. Vault — store action validation edge cases
705
+ // 4. Vault — store action validation edge cases
1118
706
  // ---------------------------------------------------------------------------
1119
707
 
1120
708
  describe("credential_store tool — store validation edge cases", () => {
@@ -1282,7 +870,7 @@ describe("credential_store tool — store validation edge cases", () => {
1282
870
  });
1283
871
 
1284
872
  // ---------------------------------------------------------------------------
1285
- // 6. Vault — tool definition schema
873
+ // 5. Vault — tool definition schema
1286
874
  // ---------------------------------------------------------------------------
1287
875
 
1288
876
  describe("credential_store tool — tool definition", () => {
@@ -1298,14 +886,7 @@ describe("credential_store tool — tool definition", () => {
1298
886
  expect(schema.type).toBe("object");
1299
887
  expect(schema.required).toContain("action");
1300
888
  const props = schema.properties as Record<string, Record<string, unknown>>;
1301
- expect(props.action.enum).toEqual([
1302
- "store",
1303
- "list",
1304
- "delete",
1305
- "prompt",
1306
- "oauth2_connect",
1307
- "describe",
1308
- ]);
889
+ expect(props.action.enum).toEqual(["store", "list", "delete", "prompt"]);
1309
890
  });
1310
891
 
1311
892
  test("getDefinition includes injection_templates schema", () => {
@@ -1326,7 +907,7 @@ describe("credential_store tool — tool definition", () => {
1326
907
  });
1327
908
 
1328
909
  // ---------------------------------------------------------------------------
1329
- // 7. Broker — serverUseById with transient not supported
910
+ // 6. Broker — serverUseById with transient not supported
1330
911
  // (transient is scoped to authorize+consume and browserFill/serverUse)
1331
912
  // ---------------------------------------------------------------------------
1332
913
 
@@ -1399,7 +980,7 @@ describe("CredentialBroker — serverUseById edge cases", () => {
1399
980
  });
1400
981
 
1401
982
  // ---------------------------------------------------------------------------
1402
- // 8. Broker — revokeAll clears transient values indirectly via token cleanup
983
+ // 7. Broker — revokeAll clears transient values indirectly via token cleanup
1403
984
  // ---------------------------------------------------------------------------
1404
985
 
1405
986
  describe("CredentialBroker — revokeAll", () => {
@@ -1087,32 +1087,32 @@ describe("assistant credentials CLI", () => {
1087
1087
  });
1088
1088
 
1089
1089
  // =========================================================================
1090
- // instance-scoped BASE_DATA_DIR
1090
+ // instance-scoped workspace
1091
1091
  // =========================================================================
1092
1092
 
1093
- describe("instance-scoped BASE_DATA_DIR", () => {
1094
- let savedBaseDataDir: string | undefined;
1093
+ describe("instance-scoped workspace", () => {
1094
+ let savedWorkspaceDir: string | undefined;
1095
1095
 
1096
1096
  beforeEach(() => {
1097
- savedBaseDataDir = process.env.BASE_DATA_DIR;
1097
+ savedWorkspaceDir = process.env.VELLUM_WORKSPACE_DIR;
1098
1098
  });
1099
1099
 
1100
1100
  afterEach(() => {
1101
- if (savedBaseDataDir === undefined) {
1102
- delete process.env.BASE_DATA_DIR;
1101
+ if (savedWorkspaceDir === undefined) {
1102
+ delete process.env.VELLUM_WORKSPACE_DIR;
1103
1103
  } else {
1104
- process.env.BASE_DATA_DIR = savedBaseDataDir;
1104
+ process.env.VELLUM_WORKSPACE_DIR = savedWorkspaceDir;
1105
1105
  }
1106
1106
  });
1107
1107
 
1108
- test("credential reveal reads from instance-scoped store when BASE_DATA_DIR is set", async () => {
1109
- // Point BASE_DATA_DIR to a temp directory (simulating instance-scoped dir)
1108
+ test("credential reveal reads from instance-scoped store when VELLUM_WORKSPACE_DIR is set", async () => {
1109
+ // Point VELLUM_WORKSPACE_DIR to a temp directory (simulating instance-scoped dir)
1110
1110
  const tmpDir = (await import("node:os")).tmpdir();
1111
1111
  const instanceDir = (await import("node:path")).join(
1112
1112
  tmpDir,
1113
1113
  `vellum-test-instance-${Date.now()}`,
1114
1114
  );
1115
- process.env.BASE_DATA_DIR = instanceDir;
1115
+ process.env.VELLUM_WORKSPACE_DIR = instanceDir;
1116
1116
 
1117
1117
  // Seed a credential in the mock store
1118
1118
  seedCredential("twilio", "auth_token", "instance_secret_abc123");
@@ -9,25 +9,6 @@
9
9
  import { describe, expect, mock, test } from "bun:test";
10
10
 
11
11
  // ── Platform mock (must happen before imports that read it) ─────────────────
12
- mock.module("../util/platform.js", () => ({
13
- getSessionTokenPath: () => "/tmp/test-token",
14
- getRootDir: () => "/tmp/test",
15
- getDataDir: () => "/tmp/test",
16
- getWorkspaceDir: () => "/tmp/test/workspace",
17
- getWorkspaceSkillsDir: () => "/tmp/test/skills",
18
- getSandboxWorkingDir: () => "/tmp/test/sandbox",
19
- getTCPPort: () => undefined,
20
- getTCPHost: () => "127.0.0.1",
21
- isTCPEnabled: () => false,
22
- isMacOS: () => false,
23
- isLinux: () => true,
24
- isWindows: () => false,
25
- getPidPath: () => "/tmp/test.pid",
26
- getLogPath: () => "/tmp/test.log",
27
- getDbPath: () => "/tmp/test.db",
28
- ensureDataDir: () => {},
29
- }));
30
-
31
12
  mock.module("../util/logger.js", () => ({
32
13
  getLogger: () =>
33
14
  new Proxy({} as Record<string, unknown>, {