@vellumai/assistant 0.6.0 → 0.6.2

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 (358) hide show
  1. package/AGENTS.md +4 -0
  2. package/ARCHITECTURE.md +68 -15
  3. package/Dockerfile +2 -2
  4. package/bun.lock +6 -2
  5. package/docker-entrypoint.sh +42 -1
  6. package/docs/architecture/integrations.md +1 -1
  7. package/docs/architecture/memory.md +21 -24
  8. package/node_modules/@vellumai/ces-contracts/src/handles.ts +7 -9
  9. package/openapi.yaml +539 -4
  10. package/package.json +5 -1
  11. package/src/__tests__/anthropic-provider.test.ts +160 -95
  12. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  13. package/src/__tests__/app-executors.test.ts +47 -1
  14. package/src/__tests__/app-source-watcher.test.ts +159 -0
  15. package/src/__tests__/assistant-event-hub.test.ts +30 -0
  16. package/src/__tests__/checker.test.ts +138 -172
  17. package/src/__tests__/cli-command-risk-guard.test.ts +1 -1
  18. package/src/__tests__/config-schema.test.ts +5 -0
  19. package/src/__tests__/context-overflow-approval.test.ts +5 -5
  20. package/src/__tests__/conversation-agent-loop-overflow.test.ts +4 -6
  21. package/src/__tests__/conversation-agent-loop.test.ts +4 -51
  22. package/src/__tests__/conversation-analysis-routes.test.ts +169 -0
  23. package/src/__tests__/conversation-directories-parse.test.ts +105 -0
  24. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  25. package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
  26. package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
  27. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
  28. package/src/__tests__/conversation-wipe.test.ts +2 -6
  29. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
  30. package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
  31. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  32. package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
  33. package/src/__tests__/credential-execution-approval-bridge.test.ts +0 -2
  34. package/src/__tests__/date-context.test.ts +76 -210
  35. package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
  36. package/src/__tests__/file-list-tool.test.ts +219 -0
  37. package/src/__tests__/first-greeting.test.ts +1 -1
  38. package/src/__tests__/heartbeat-service.test.ts +180 -3
  39. package/src/__tests__/identity-routes.test.ts +328 -0
  40. package/src/__tests__/init-feature-flag-overrides.test.ts +167 -0
  41. package/src/__tests__/injection-block.test.ts +24 -0
  42. package/src/__tests__/inline-command-runner.test.ts +7 -5
  43. package/src/__tests__/install-skill-routing.test.ts +7 -6
  44. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +15 -14
  45. package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
  46. package/src/__tests__/llm-context-normalization.test.ts +18 -18
  47. package/src/__tests__/llm-context-route-provider.test.ts +101 -0
  48. package/src/__tests__/llm-request-log-turn-query.test.ts +162 -0
  49. package/src/__tests__/log-export-workspace.test.ts +257 -100
  50. package/src/__tests__/managed-credential-catalog-cli.test.ts +12 -14
  51. package/src/__tests__/mcp-abort-signal.test.ts +5 -0
  52. package/src/__tests__/mcp-client-auth.test.ts +5 -0
  53. package/src/__tests__/memory-recall-log-store.test.ts +132 -0
  54. package/src/__tests__/migration-export-streaming.test.ts +304 -0
  55. package/src/__tests__/migration-import-commit-http.test.ts +11 -10
  56. package/src/__tests__/mock-fetch.ts +87 -0
  57. package/src/__tests__/navigate-settings-tab.test.ts +14 -1
  58. package/src/__tests__/notification-broadcaster.test.ts +65 -0
  59. package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
  60. package/src/__tests__/onboarding-template-contract.test.ts +63 -14
  61. package/src/__tests__/parser.test.ts +32 -0
  62. package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
  63. package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
  64. package/src/__tests__/permission-mode-sse.test.ts +418 -0
  65. package/src/__tests__/permission-mode-store.test.ts +277 -0
  66. package/src/__tests__/permission-mode.test.ts +101 -0
  67. package/src/__tests__/pkb-autoinject.test.ts +96 -0
  68. package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
  69. package/src/__tests__/profiler-routes.test.ts +502 -0
  70. package/src/__tests__/profiler-run-store.test.ts +441 -0
  71. package/src/__tests__/proxy-approval-callback.test.ts +4 -75
  72. package/src/__tests__/registry.test.ts +1 -1
  73. package/src/__tests__/require-fresh-approval.test.ts +0 -2
  74. package/src/__tests__/sandbox-diagnostics.test.ts +1 -32
  75. package/src/__tests__/sandbox-host-parity.test.ts +5 -4
  76. package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
  77. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
  78. package/src/__tests__/search-skills-unified.test.ts +4 -3
  79. package/src/__tests__/send-endpoint-busy.test.ts +42 -3
  80. package/src/__tests__/set-permission-mode.test.ts +274 -0
  81. package/src/__tests__/skill-load-feature-flag.test.ts +12 -0
  82. package/src/__tests__/skill-memory.test.ts +2 -783
  83. package/src/__tests__/strip-memory-injections.test.ts +187 -0
  84. package/src/__tests__/subagent-detail.test.ts +84 -0
  85. package/src/__tests__/subagent-disposal.test.ts +308 -0
  86. package/src/__tests__/subagent-manager-notify.test.ts +19 -10
  87. package/src/__tests__/subagent-notify-parent.test.ts +390 -0
  88. package/src/__tests__/subagent-role-registry.test.ts +108 -0
  89. package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
  90. package/src/__tests__/subagent-tools.test.ts +464 -4
  91. package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
  92. package/src/__tests__/task-memory-cleanup.test.ts +12 -12
  93. package/src/__tests__/terminal-sandbox.test.ts +1 -1
  94. package/src/__tests__/terminal-tools.test.ts +16 -29
  95. package/src/__tests__/test-preload.ts +18 -0
  96. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -1
  97. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -8
  98. package/src/__tests__/tool-executor.test.ts +4 -27
  99. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  100. package/src/__tests__/top-level-renderer.test.ts +10 -13
  101. package/src/__tests__/transport-hints-queue.test.ts +77 -0
  102. package/src/__tests__/trust-store.test.ts +4 -4
  103. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +116 -2
  104. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
  105. package/src/__tests__/workspace-migration-030-seed-pkb-autoinject.test.ts +168 -0
  106. package/src/__tests__/workspace-policy.test.ts +2 -7
  107. package/src/agent/loop.ts +6 -29
  108. package/src/approvals/guardian-request-resolvers.ts +24 -0
  109. package/src/avatar/traits-png-sync.ts +3 -3
  110. package/src/channels/types.ts +5 -0
  111. package/src/cli/__tests__/run-assistant-command.ts +56 -0
  112. package/src/cli/__tests__/unknown-command.test.ts +33 -0
  113. package/src/cli/commands/__tests__/email-download.test.ts +245 -0
  114. package/src/cli/commands/__tests__/email-list.test.ts +192 -0
  115. package/src/cli/commands/__tests__/email-register.test.ts +186 -0
  116. package/src/cli/commands/__tests__/email-send.test.ts +291 -0
  117. package/src/cli/commands/__tests__/email-status.test.ts +181 -0
  118. package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
  119. package/src/cli/commands/__tests__/routes.test.ts +562 -0
  120. package/src/cli/commands/conversations.ts +1 -8
  121. package/src/cli/commands/default-action.ts +68 -1
  122. package/src/cli/commands/email.ts +584 -835
  123. package/src/cli/commands/memory.ts +1 -34
  124. package/src/cli/commands/notifications.ts +7 -2
  125. package/src/cli/commands/oauth/__tests__/connect.test.ts +27 -0
  126. package/src/cli/commands/oauth/connect.ts +25 -5
  127. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  128. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  129. package/src/cli/commands/platform/__tests__/status.test.ts +1 -1
  130. package/src/cli/commands/routes.ts +396 -0
  131. package/src/cli/commands/skills.ts +130 -20
  132. package/src/cli/program.ts +11 -2
  133. package/src/cli.ts +1 -120
  134. package/src/config/assistant-feature-flags.ts +59 -55
  135. package/src/config/bundled-skills/app-builder/SKILL.md +91 -5
  136. package/src/config/bundled-skills/gmail/SKILL.md +13 -8
  137. package/src/config/bundled-skills/gmail/TOOLS.json +1 -1
  138. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -1
  139. package/src/config/bundled-skills/messaging/SKILL.md +7 -0
  140. package/src/config/bundled-skills/schedule/SKILL.md +22 -2
  141. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  142. package/src/config/bundled-skills/settings/TOOLS.json +1 -1
  143. package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
  144. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
  145. package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
  146. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +8 -3
  147. package/src/config/bundled-skills/slack/SKILL.md +2 -0
  148. package/src/config/bundled-skills/subagent/SKILL.md +43 -3
  149. package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
  150. package/src/config/env-registry.ts +63 -0
  151. package/src/config/feature-flag-registry.json +17 -1
  152. package/src/config/schema.ts +8 -0
  153. package/src/config/schemas/filing.ts +51 -0
  154. package/src/config/schemas/heartbeat.ts +15 -12
  155. package/src/config/schemas/memory-lifecycle.ts +12 -0
  156. package/src/config/schemas/security.ts +14 -0
  157. package/src/config/schemas/services.ts +8 -0
  158. package/src/credential-execution/approval-bridge.ts +0 -1
  159. package/src/credential-execution/managed-catalog.ts +3 -7
  160. package/src/daemon/app-source-watcher.ts +93 -0
  161. package/src/daemon/config-watcher.ts +85 -3
  162. package/src/daemon/context-overflow-approval.ts +0 -1
  163. package/src/daemon/conversation-agent-loop-handlers.ts +20 -0
  164. package/src/daemon/conversation-agent-loop.ts +179 -65
  165. package/src/daemon/conversation-attachments.ts +0 -1
  166. package/src/daemon/conversation-history.ts +4 -19
  167. package/src/daemon/conversation-lifecycle.ts +8 -14
  168. package/src/daemon/conversation-messaging.ts +3 -0
  169. package/src/daemon/conversation-process.ts +30 -8
  170. package/src/daemon/conversation-queue-manager.ts +8 -0
  171. package/src/daemon/conversation-runtime-assembly.ts +359 -308
  172. package/src/daemon/conversation-surfaces.ts +65 -0
  173. package/src/daemon/conversation-tool-setup.ts +44 -17
  174. package/src/daemon/conversation-workspace.ts +1 -2
  175. package/src/daemon/conversation.ts +19 -3
  176. package/src/daemon/date-context.ts +26 -53
  177. package/src/daemon/first-greeting.ts +1 -1
  178. package/src/daemon/handlers/conversations.ts +5 -7
  179. package/src/daemon/handlers/shared.test.ts +143 -0
  180. package/src/daemon/handlers/shared.ts +70 -5
  181. package/src/daemon/handlers/skills.ts +11 -18
  182. package/src/daemon/lifecycle.ts +220 -158
  183. package/src/daemon/message-types/conversations.ts +29 -6
  184. package/src/daemon/message-types/messages.ts +9 -2
  185. package/src/daemon/message-types/notifications.ts +12 -0
  186. package/src/daemon/message-types/schedules.ts +1 -0
  187. package/src/daemon/message-types/settings.ts +18 -0
  188. package/src/daemon/profiler-run-store.ts +557 -0
  189. package/src/daemon/server.ts +87 -10
  190. package/src/daemon/shutdown-handlers.ts +5 -0
  191. package/src/daemon/tool-side-effects.ts +23 -3
  192. package/src/daemon/transport-hints.ts +33 -0
  193. package/src/export/transcript-formatter.ts +148 -0
  194. package/src/filing/filing-service.ts +228 -0
  195. package/src/heartbeat/heartbeat-service.ts +96 -7
  196. package/src/index.ts +1 -1
  197. package/src/mcp/client.ts +6 -0
  198. package/src/mcp/mcp-oauth-provider.ts +149 -27
  199. package/src/memory/admin.ts +33 -32
  200. package/src/memory/app-store.ts +69 -0
  201. package/src/memory/conversation-bootstrap.ts +1 -1
  202. package/src/memory/conversation-crud.ts +151 -117
  203. package/src/memory/conversation-directories.ts +39 -0
  204. package/src/memory/conversation-group-migration.ts +66 -6
  205. package/src/memory/conversation-queries.ts +58 -12
  206. package/src/memory/conversation-title-service.ts +1 -0
  207. package/src/memory/db-init.ts +182 -376
  208. package/src/memory/embedding-local.ts +1 -1
  209. package/src/memory/graph/bootstrap.ts +75 -66
  210. package/src/memory/graph/capability-seed.ts +167 -17
  211. package/src/memory/graph/consolidation.ts +38 -4
  212. package/src/memory/graph/conversation-graph-memory.ts +133 -104
  213. package/src/memory/graph/extraction-job.ts +9 -4
  214. package/src/memory/graph/extraction.ts +66 -23
  215. package/src/memory/graph/graph-memory-state-store.ts +37 -0
  216. package/src/memory/graph/graph-search.ts +29 -15
  217. package/src/memory/graph/injection.ts +38 -8
  218. package/src/memory/graph/inspect.ts +12 -3
  219. package/src/memory/graph/retriever.ts +365 -262
  220. package/src/memory/graph/store.test.ts +48 -0
  221. package/src/memory/graph/store.ts +150 -11
  222. package/src/memory/graph/tool-handlers.ts +84 -209
  223. package/src/memory/graph/tools.ts +8 -52
  224. package/src/memory/graph/types.ts +24 -0
  225. package/src/memory/group-crud.ts +25 -9
  226. package/src/memory/job-handlers/cleanup.ts +44 -1
  227. package/src/memory/jobs-store.ts +70 -60
  228. package/src/memory/jobs-worker.ts +44 -28
  229. package/src/memory/llm-request-log-store.ts +96 -12
  230. package/src/memory/memory-recall-log-store.ts +49 -5
  231. package/src/memory/migrations/203-drop-memory-items-tables.ts +33 -1
  232. package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
  233. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
  234. package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
  235. package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
  236. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
  237. package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
  238. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
  239. package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
  240. package/src/memory/migrations/index.ts +8 -0
  241. package/src/memory/migrations/registry.ts +8 -0
  242. package/src/memory/schema/conversations.ts +14 -0
  243. package/src/memory/schema/infrastructure.ts +8 -1
  244. package/src/memory/schema/memory-core.ts +0 -51
  245. package/src/memory/schema/memory-graph.ts +15 -0
  246. package/src/memory/task-memory-cleanup.ts +30 -11
  247. package/src/messaging/provider.ts +1 -1
  248. package/src/notifications/broadcaster.ts +6 -0
  249. package/src/notifications/conversation-pairing.ts +12 -4
  250. package/src/notifications/copy-composer.ts +86 -0
  251. package/src/notifications/decision-engine.ts +35 -0
  252. package/src/notifications/emit-signal.ts +14 -0
  253. package/src/notifications/signal.ts +11 -0
  254. package/src/oauth/platform-connection.test.ts +2 -2
  255. package/src/oauth/seed-providers.ts +1 -0
  256. package/src/permissions/checker.ts +15 -4
  257. package/src/permissions/defaults.ts +7 -8
  258. package/src/permissions/permission-mode-store.ts +180 -0
  259. package/src/permissions/permission-mode.ts +31 -0
  260. package/src/permissions/prompter.ts +0 -2
  261. package/src/permissions/workspace-policy.ts +9 -0
  262. package/src/platform/client.ts +1 -1
  263. package/src/prompts/system-prompt.ts +59 -7
  264. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
  265. package/src/prompts/templates/BOOTSTRAP.md +76 -162
  266. package/src/prompts/templates/HEARTBEAT.md +3 -1
  267. package/src/prompts/templates/SOUL.md +30 -9
  268. package/src/prompts/templates/UPDATES.md +8 -0
  269. package/src/providers/anthropic/client.ts +107 -219
  270. package/src/runtime/assistant-event-hub.ts +22 -0
  271. package/src/runtime/auth/route-policy.ts +23 -0
  272. package/src/runtime/auth/token-service.ts +8 -0
  273. package/src/runtime/http-server.ts +32 -2
  274. package/src/runtime/http-types.ts +12 -1
  275. package/src/runtime/migrations/vbundle-builder.ts +389 -3
  276. package/src/runtime/migrations/vbundle-importer.ts +8 -6
  277. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
  278. package/src/runtime/routes/app-management-routes.ts +1 -11
  279. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
  280. package/src/runtime/routes/archive-utils.ts +29 -0
  281. package/src/runtime/routes/avatar-routes.ts +2 -9
  282. package/src/runtime/routes/btw-routes.ts +14 -1
  283. package/src/runtime/routes/conversation-analysis-routes.ts +185 -0
  284. package/src/runtime/routes/conversation-management-routes.ts +1 -14
  285. package/src/runtime/routes/conversation-query-routes.ts +49 -3
  286. package/src/runtime/routes/conversation-routes.ts +270 -44
  287. package/src/runtime/routes/group-routes.ts +22 -8
  288. package/src/runtime/routes/heartbeat-routes.ts +4 -10
  289. package/src/runtime/routes/identity-routes.ts +53 -18
  290. package/src/runtime/routes/llm-context-normalization.ts +14 -10
  291. package/src/runtime/routes/log-export/AGENTS.md +104 -0
  292. package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +103 -0
  293. package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +716 -0
  294. package/src/runtime/routes/log-export/workspace-allowlist.ts +458 -0
  295. package/src/runtime/routes/log-export-routes.ts +41 -278
  296. package/src/runtime/routes/memory-item-routes.test.ts +168 -233
  297. package/src/runtime/routes/migration-routes.ts +18 -7
  298. package/src/runtime/routes/profiler-routes.ts +350 -0
  299. package/src/runtime/routes/schedule-routes.ts +27 -12
  300. package/src/runtime/routes/settings-routes.ts +95 -8
  301. package/src/runtime/routes/subagents-routes.ts +28 -7
  302. package/src/runtime/routes/user-route-dispatcher.ts +223 -0
  303. package/src/runtime/routes/user-routes.ts +41 -0
  304. package/src/runtime/routes/workspace-routes.ts +0 -1
  305. package/src/schedule/schedule-store.ts +30 -0
  306. package/src/schedule/scheduler.ts +45 -18
  307. package/src/skills/catalog-install.ts +10 -2
  308. package/src/skills/inline-command-runner.ts +12 -14
  309. package/src/skills/managed-store.ts +2 -2
  310. package/src/skills/skill-memory.ts +1 -293
  311. package/src/subagent/index.ts +13 -3
  312. package/src/subagent/manager.ts +308 -29
  313. package/src/subagent/types.ts +68 -0
  314. package/src/tasks/task-runner.ts +4 -4
  315. package/src/tools/apps/executors.ts +29 -4
  316. package/src/tools/filesystem/list.ts +93 -0
  317. package/src/tools/permission-checker.ts +78 -18
  318. package/src/tools/registry.ts +4 -0
  319. package/src/tools/schedule/create.ts +3 -0
  320. package/src/tools/schedule/list.ts +1 -0
  321. package/src/tools/schedule/update.ts +6 -0
  322. package/src/tools/secret-detection-handler.ts +0 -1
  323. package/src/tools/shared/filesystem/errors.ts +5 -0
  324. package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
  325. package/src/tools/shared/filesystem/types.ts +17 -0
  326. package/src/tools/shared/shell-output.ts +31 -2
  327. package/src/tools/skills/sandbox-runner.ts +3 -6
  328. package/src/tools/subagent/abort.ts +12 -2
  329. package/src/tools/subagent/message.ts +9 -2
  330. package/src/tools/subagent/notify-parent.ts +79 -0
  331. package/src/tools/subagent/read.ts +29 -8
  332. package/src/tools/subagent/resolve.ts +21 -0
  333. package/src/tools/subagent/spawn.ts +2 -0
  334. package/src/tools/subagent/status.ts +11 -1
  335. package/src/tools/system/avatar-generator.ts +3 -3
  336. package/src/tools/system/register.ts +23 -0
  337. package/src/tools/system/set-permission-mode.ts +103 -0
  338. package/src/tools/terminal/parser.ts +30 -5
  339. package/src/tools/terminal/safe-env.ts +16 -1
  340. package/src/tools/terminal/sandbox-diagnostics.ts +4 -4
  341. package/src/tools/terminal/sandbox.ts +4 -1
  342. package/src/tools/terminal/shell.ts +3 -5
  343. package/src/tools/tool-manifest.ts +6 -0
  344. package/src/tools/types.ts +2 -3
  345. package/src/util/logger.ts +1 -1
  346. package/src/util/platform.ts +50 -17
  347. package/src/watcher/provider-types.ts +1 -1
  348. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
  349. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
  350. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
  351. package/src/workspace/migrations/029-seed-pkb.ts +85 -0
  352. package/src/workspace/migrations/030-seed-pkb-autoinject.ts +73 -0
  353. package/src/workspace/migrations/registry.ts +6 -0
  354. package/src/workspace/top-level-renderer.ts +5 -9
  355. package/src/__tests__/cli-memory.test.ts +0 -377
  356. package/src/__tests__/clipboard.test.ts +0 -88
  357. package/src/cli/cli-memory.ts +0 -179
  358. package/src/util/clipboard.ts +0 -34
@@ -17,7 +17,10 @@ import {
17
17
  createCanonicalGuardianRequest,
18
18
  getCanonicalGuardianRequest,
19
19
  } from "../memory/canonical-guardian-store.js";
20
- import { getOrCreateConversation } from "../memory/conversation-key-store.js";
20
+ import {
21
+ getConversationByKey,
22
+ getOrCreateConversation,
23
+ } from "../memory/conversation-key-store.js";
21
24
 
22
25
  mock.module("../util/logger.js", () => ({
23
26
  getLogger: () =>
@@ -855,7 +858,7 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
855
858
  await stopServer();
856
859
  });
857
860
 
858
- test("returns 400 when conversationKey is missing", async () => {
861
+ test("accepts message when conversationKey is omitted (defaults to stable channel key)", async () => {
859
862
  await startServer(() => makeCompletingConversation());
860
863
 
861
864
  const res = await fetch(messagesUrl(), {
@@ -867,7 +870,43 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
867
870
  interface: "macos",
868
871
  }),
869
872
  });
870
- expect(res.status).toBe(400);
873
+ expect(res.status).toBe(202);
874
+
875
+ await stopServer();
876
+ });
877
+
878
+ test("two calls without conversationKey use the same conversation", async () => {
879
+ await startServer(() => makeCompletingConversation());
880
+
881
+ // First message — no conversationKey
882
+ const res1 = await fetch(messagesUrl(), {
883
+ method: "POST",
884
+ headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
885
+ body: JSON.stringify({
886
+ content: "First",
887
+ sourceChannel: "vellum",
888
+ interface: "macos",
889
+ }),
890
+ });
891
+ expect(res1.status).toBe(202);
892
+
893
+ // Second message — same channel/interface, still no conversationKey
894
+ const res2 = await fetch(messagesUrl(), {
895
+ method: "POST",
896
+ headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
897
+ body: JSON.stringify({
898
+ content: "Second",
899
+ sourceChannel: "vellum",
900
+ interface: "macos",
901
+ }),
902
+ });
903
+ expect(res2.status).toBe(202);
904
+
905
+ // Both should have resolved to the same default conversation key
906
+ // ("default:vellum:macos"), which maps to the same conversationId.
907
+ const mapping = getConversationByKey("default:vellum:macos");
908
+ expect(mapping).not.toBeNull();
909
+ expect(mapping!.conversationId).toBeTruthy();
871
910
 
872
911
  await stopServer();
873
912
  });
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Tests for the set_permission_mode system tool.
3
+ *
4
+ * Verifies:
5
+ * - Mode transitions via askBeforeActing and hostAccess
6
+ * - Partial updates (only provided fields change)
7
+ * - Idempotent calls (setting same value is safe)
8
+ * - Error when no fields provided
9
+ * - Tool is not registered when permission-controls-v2 flag is off
10
+ * - Tool is registered when permission-controls-v2 flag is on
11
+ */
12
+
13
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
14
+ import { join } from "node:path";
15
+ import {
16
+ afterAll,
17
+ afterEach,
18
+ beforeEach,
19
+ describe,
20
+ expect,
21
+ mock,
22
+ test,
23
+ } from "bun:test";
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Mocks — declared before imports that depend on platform/logger
27
+ // ---------------------------------------------------------------------------
28
+
29
+ const WORKSPACE_DIR = process.env.VELLUM_WORKSPACE_DIR!;
30
+ const CONFIG_PATH = join(WORKSPACE_DIR, "config.json");
31
+
32
+ function ensureTestDir(): void {
33
+ const dirs = [
34
+ WORKSPACE_DIR,
35
+ join(WORKSPACE_DIR, "data"),
36
+ join(WORKSPACE_DIR, "data", "logs"),
37
+ ];
38
+ for (const dir of dirs) {
39
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
40
+ }
41
+ }
42
+
43
+ function makeLoggerStub(): Record<string, unknown> {
44
+ const stub: Record<string, unknown> = {};
45
+ for (const m of [
46
+ "info",
47
+ "warn",
48
+ "error",
49
+ "debug",
50
+ "trace",
51
+ "fatal",
52
+ "silent",
53
+ "child",
54
+ ]) {
55
+ stub[m] = m === "child" ? () => makeLoggerStub() : () => {};
56
+ }
57
+ return stub;
58
+ }
59
+
60
+ mock.module("../util/logger.js", () => ({
61
+ getLogger: () => makeLoggerStub(),
62
+ }));
63
+
64
+ afterAll(() => {
65
+ mock.restore();
66
+ });
67
+
68
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
69
+ import { invalidateConfigCache } from "../config/loader.js";
70
+ import {
71
+ getMode,
72
+ resetForTesting,
73
+ } from "../permissions/permission-mode-store.js";
74
+ import { __clearRegistryForTesting, getTool } from "../tools/registry.js";
75
+ import { registerSystemTools } from "../tools/system/register.js";
76
+ import { setPermissionModeTool } from "../tools/system/set-permission-mode.js";
77
+ import type { ToolContext } from "../tools/types.js";
78
+
79
+ // ---------------------------------------------------------------------------
80
+ // Helpers
81
+ // ---------------------------------------------------------------------------
82
+
83
+ function writeConfig(obj: unknown): void {
84
+ ensureTestDir();
85
+ writeFileSync(CONFIG_PATH, JSON.stringify(obj, null, 2) + "\n");
86
+ }
87
+
88
+ function makeContext(): ToolContext {
89
+ return {
90
+ workingDir: WORKSPACE_DIR,
91
+ conversationId: "test-conversation",
92
+ trustClass: "guardian",
93
+ };
94
+ }
95
+
96
+ // ---------------------------------------------------------------------------
97
+ // Setup / teardown
98
+ // ---------------------------------------------------------------------------
99
+
100
+ beforeEach(() => {
101
+ ensureTestDir();
102
+ resetForTesting();
103
+ invalidateConfigCache();
104
+ _setOverridesForTesting({});
105
+ __clearRegistryForTesting();
106
+ // Write a minimal config so the store initializes cleanly
107
+ writeConfig({});
108
+ });
109
+
110
+ afterEach(() => {
111
+ resetForTesting();
112
+ invalidateConfigCache();
113
+ _setOverridesForTesting({});
114
+ __clearRegistryForTesting();
115
+ });
116
+
117
+ // ---------------------------------------------------------------------------
118
+ // Tests — tool execution
119
+ // ---------------------------------------------------------------------------
120
+
121
+ describe("set_permission_mode tool", () => {
122
+ describe("mode transitions", () => {
123
+ test("sets askBeforeActing to false", async () => {
124
+ const result = await setPermissionModeTool.execute(
125
+ { askBeforeActing: false },
126
+ makeContext(),
127
+ );
128
+
129
+ expect(result.isError).toBe(false);
130
+ expect(result.content).toContain("askBeforeActing: false");
131
+
132
+ const mode = getMode();
133
+ expect(mode.askBeforeActing).toBe(false);
134
+ });
135
+
136
+ test("sets hostAccess to true", async () => {
137
+ const result = await setPermissionModeTool.execute(
138
+ { hostAccess: true },
139
+ makeContext(),
140
+ );
141
+
142
+ expect(result.isError).toBe(false);
143
+ expect(result.content).toContain("hostAccess: true");
144
+
145
+ const mode = getMode();
146
+ expect(mode.hostAccess).toBe(true);
147
+ });
148
+
149
+ test("sets both fields at once", async () => {
150
+ const result = await setPermissionModeTool.execute(
151
+ { askBeforeActing: false, hostAccess: true },
152
+ makeContext(),
153
+ );
154
+
155
+ expect(result.isError).toBe(false);
156
+ expect(result.content).toContain("askBeforeActing: false");
157
+ expect(result.content).toContain("hostAccess: true");
158
+
159
+ const mode = getMode();
160
+ expect(mode.askBeforeActing).toBe(false);
161
+ expect(mode.hostAccess).toBe(true);
162
+ });
163
+ });
164
+
165
+ describe("partial updates", () => {
166
+ test("only askBeforeActing changes, hostAccess unchanged", async () => {
167
+ await setPermissionModeTool.execute(
168
+ { askBeforeActing: false },
169
+ makeContext(),
170
+ );
171
+
172
+ const mode = getMode();
173
+ expect(mode.askBeforeActing).toBe(false);
174
+ // hostAccess should remain at default (false)
175
+ expect(mode.hostAccess).toBe(false);
176
+ });
177
+
178
+ test("only hostAccess changes, askBeforeActing unchanged", async () => {
179
+ await setPermissionModeTool.execute({ hostAccess: true }, makeContext());
180
+
181
+ const mode = getMode();
182
+ // askBeforeActing should remain at default (true)
183
+ expect(mode.askBeforeActing).toBe(true);
184
+ expect(mode.hostAccess).toBe(true);
185
+ });
186
+ });
187
+
188
+ describe("idempotent calls", () => {
189
+ test("setting askBeforeActing to current value is safe", async () => {
190
+ // Default is true
191
+ const result = await setPermissionModeTool.execute(
192
+ { askBeforeActing: true },
193
+ makeContext(),
194
+ );
195
+
196
+ expect(result.isError).toBe(false);
197
+ expect(getMode().askBeforeActing).toBe(true);
198
+ });
199
+
200
+ test("setting hostAccess to current value is safe", async () => {
201
+ // Default is false
202
+ const result = await setPermissionModeTool.execute(
203
+ { hostAccess: false },
204
+ makeContext(),
205
+ );
206
+
207
+ expect(result.isError).toBe(false);
208
+ expect(getMode().hostAccess).toBe(false);
209
+ });
210
+
211
+ test("repeated calls produce same result", async () => {
212
+ await setPermissionModeTool.execute(
213
+ { askBeforeActing: false, hostAccess: true },
214
+ makeContext(),
215
+ );
216
+ const result = await setPermissionModeTool.execute(
217
+ { askBeforeActing: false, hostAccess: true },
218
+ makeContext(),
219
+ );
220
+
221
+ expect(result.isError).toBe(false);
222
+ const mode = getMode();
223
+ expect(mode.askBeforeActing).toBe(false);
224
+ expect(mode.hostAccess).toBe(true);
225
+ });
226
+ });
227
+
228
+ describe("validation", () => {
229
+ test("returns error when no fields provided", async () => {
230
+ const result = await setPermissionModeTool.execute({}, makeContext());
231
+
232
+ expect(result.isError).toBe(true);
233
+ expect(result.content).toContain("at least one");
234
+ });
235
+ });
236
+
237
+ describe("tool definition", () => {
238
+ test("has correct name", () => {
239
+ expect(setPermissionModeTool.name).toBe("set_permission_mode");
240
+ });
241
+
242
+ test("has correct category", () => {
243
+ expect(setPermissionModeTool.category).toBe("system");
244
+ });
245
+
246
+ test("definition includes both properties", () => {
247
+ const def = setPermissionModeTool.getDefinition();
248
+ const schema = def.input_schema as { properties?: Record<string, unknown> };
249
+ const props = schema.properties as Record<string, unknown>;
250
+ expect(props).toHaveProperty("askBeforeActing");
251
+ expect(props).toHaveProperty("hostAccess");
252
+ });
253
+ });
254
+ });
255
+
256
+ // ---------------------------------------------------------------------------
257
+ // Tests — feature flag gating
258
+ // ---------------------------------------------------------------------------
259
+
260
+ describe("set_permission_mode registration", () => {
261
+ test("tool is NOT registered when permission-controls-v2 flag is off", () => {
262
+ _setOverridesForTesting({ "permission-controls-v2": false });
263
+ registerSystemTools();
264
+
265
+ expect(getTool("set_permission_mode")).toBeUndefined();
266
+ });
267
+
268
+ test("tool IS registered when permission-controls-v2 flag is on", () => {
269
+ _setOverridesForTesting({ "permission-controls-v2": true });
270
+ registerSystemTools();
271
+
272
+ expect(getTool("set_permission_mode")).toBeDefined();
273
+ });
274
+ });
@@ -39,6 +39,18 @@ mock.module("../config/loader.js", () => ({
39
39
  invalidateConfigCache: () => {},
40
40
  getNestedValue: () => undefined,
41
41
  setNestedValue: () => {},
42
+ deepMergeOverwrite: (a: unknown) => a,
43
+ mergeDefaultWorkspaceConfig: () => {},
44
+ API_KEY_PROVIDERS: [
45
+ "anthropic",
46
+ "openai",
47
+ "gemini",
48
+ "ollama",
49
+ "fireworks",
50
+ "openrouter",
51
+ "brave",
52
+ "perplexity",
53
+ ],
42
54
  }));
43
55
 
44
56
  await import("../tools/skills/load.js");