@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
@@ -3,7 +3,6 @@ import { describe, expect, test } from "bun:test";
3
3
  import {
4
4
  applyRuntimeInjections,
5
5
  injectWorkspaceTopLevelContext,
6
- stripWorkspaceTopLevelContext,
7
6
  } from "../daemon/conversation-runtime-assembly.js";
8
7
  import type { Message } from "../providers/types.js";
9
8
 
@@ -15,16 +14,12 @@ function userMsg(text: string): Message {
15
14
  return { role: "user", content: [{ type: "text", text }] };
16
15
  }
17
16
 
18
- function assistantMsg(text: string): Message {
19
- return { role: "assistant", content: [{ type: "text", text }] };
20
- }
21
-
22
17
  // ---------------------------------------------------------------------------
23
18
  // Tests
24
19
  // ---------------------------------------------------------------------------
25
20
 
26
21
  const sampleContext =
27
- "<workspace_top_level>\nRoot: /sandbox\nDirectories: src, lib, tests\n</workspace_top_level>";
22
+ "<workspace>\nRoot: /sandbox\nDirectories: src, lib, tests\n</workspace>";
28
23
 
29
24
  describe("Workspace top-level context — injection", () => {
30
25
  test("prepends workspace block to user message content", () => {
@@ -62,93 +57,6 @@ describe("Workspace top-level context — injection", () => {
62
57
  });
63
58
  });
64
59
 
65
- describe("Workspace top-level context — stripping", () => {
66
- test("strips injected workspace block from user messages", () => {
67
- const messages: Message[] = [
68
- {
69
- role: "user",
70
- content: [
71
- { type: "text", text: sampleContext },
72
- { type: "text", text: "Hello" },
73
- ],
74
- },
75
- assistantMsg("Hi there"),
76
- ];
77
-
78
- const stripped = stripWorkspaceTopLevelContext(messages);
79
-
80
- expect(stripped).toHaveLength(2);
81
- expect(stripped[0].content).toHaveLength(1);
82
- expect((stripped[0].content[0] as { text: string }).text).toBe("Hello");
83
- });
84
-
85
- test("does not strip non-workspace text blocks", () => {
86
- const messages: Message[] = [
87
- userMsg("Regular message"),
88
- assistantMsg("Response"),
89
- ];
90
-
91
- const stripped = stripWorkspaceTopLevelContext(messages);
92
- expect(stripped).toEqual(messages);
93
- });
94
-
95
- test("removes user message entirely when only workspace block remains", () => {
96
- const messages: Message[] = [
97
- { role: "user", content: [{ type: "text", text: sampleContext }] },
98
- assistantMsg("Response"),
99
- ];
100
-
101
- const stripped = stripWorkspaceTopLevelContext(messages);
102
- expect(stripped).toHaveLength(1);
103
- expect(stripped[0].role).toBe("assistant");
104
- });
105
-
106
- test("does not strip from assistant messages", () => {
107
- const messages: Message[] = [assistantMsg(sampleContext)];
108
-
109
- const stripped = stripWorkspaceTopLevelContext(messages);
110
- expect(stripped).toHaveLength(1);
111
- expect((stripped[0].content[0] as { text: string }).text).toBe(
112
- sampleContext,
113
- );
114
- });
115
-
116
- test("preserves tool_result blocks during stripping", () => {
117
- const messages: Message[] = [
118
- {
119
- role: "user",
120
- content: [
121
- { type: "text", text: sampleContext },
122
- {
123
- type: "tool_result",
124
- tool_use_id: "tu_1",
125
- content: "result",
126
- is_error: false,
127
- },
128
- ],
129
- },
130
- ];
131
-
132
- const stripped = stripWorkspaceTopLevelContext(messages);
133
- expect(stripped).toHaveLength(1);
134
- expect(stripped[0].content).toHaveLength(1);
135
- expect(stripped[0].content[0].type).toBe("tool_result");
136
- });
137
-
138
- test("no empty-message artifacts after stripping", () => {
139
- const messages: Message[] = [
140
- userMsg("Before"),
141
- { role: "user", content: [{ type: "text", text: sampleContext }] },
142
- assistantMsg("After"),
143
- ];
144
-
145
- const stripped = stripWorkspaceTopLevelContext(messages);
146
- expect(stripped).toHaveLength(2);
147
- expect(stripped[0].role).toBe("user");
148
- expect(stripped[1].role).toBe("assistant");
149
- });
150
- });
151
-
152
60
  describe("applyRuntimeInjections — workspace top-level context", () => {
153
61
  test("injects workspace context when provided", () => {
154
62
  const messages: Message[] = [userMsg("Hello")];
@@ -2,10 +2,12 @@
2
2
  * Regression tests for app surface refresh and eventing side effects in
3
3
  * createToolExecutor (conversation-tool-setup.ts).
4
4
  *
5
- * The app_refresh hook is the sole hook for app change refresh. These tests
6
- * verify that app_refresh, app_create, and app_delete hooks fire correctly,
7
- * and that removed hooks (app_update, app_file_edit, app_file_write) no
8
- * longer trigger side effects.
5
+ * Tests verify that app_refresh, app_create, and app_delete hooks fire
6
+ * correctly, and that removed hooks (app_update, app_file_edit,
7
+ * app_file_write) no longer trigger side effects.
8
+ *
9
+ * File-change detection for file_write/file_edit is handled by
10
+ * AppSourceWatcher (see app-source-watcher.test.ts).
9
11
  */
10
12
 
11
13
  import { beforeEach, describe, expect, mock, test } from "bun:test";
@@ -42,6 +44,16 @@ mock.module("../tools/browser/browser-screencast.js", () => ({
42
44
  registerConversationSender: mock(() => {}),
43
45
  }));
44
46
 
47
+ // Mock app-store functions used by handleAppChange in tool-side-effects
48
+ mock.module("../memory/app-store.js", () => ({
49
+ getApp: mock(() => null),
50
+ getAppDirPath: mock(() => "/tmp/test-apps/dummy"),
51
+ isMultifileApp: mock(() => false),
52
+ getAppsDir: mock(() => "/tmp/test-apps"),
53
+ resolveAppIdByDirName: mock(() => null),
54
+ resolveAppIdFromPath: mock(() => null),
55
+ }));
56
+
45
57
  // ---------------------------------------------------------------------------
46
58
  // Import createToolExecutor after mocks are in place
47
59
  // ---------------------------------------------------------------------------
@@ -423,4 +435,5 @@ describe("session-tool-setup app refresh side effects", () => {
423
435
  expect(updatePublishedSpy).toHaveBeenCalledTimes(1);
424
436
  });
425
437
  });
438
+
426
439
  });
@@ -94,7 +94,7 @@ describe("wipeConversation", () => {
94
94
 
95
95
  test("cancels pending memory jobs", async () => {
96
96
  const conv = createConversation("test");
97
- const msg = await addMessage(conv.id, "user", "hello", undefined, {
97
+ await addMessage(conv.id, "user", "hello", undefined, {
98
98
  skipIndexing: true,
99
99
  });
100
100
 
@@ -102,7 +102,7 @@ describe("wipeConversation", () => {
102
102
  const db = getDb();
103
103
  db.run(`DELETE FROM memory_jobs`);
104
104
 
105
- enqueueMemoryJob("extract_items", { messageId: msg.id });
105
+ enqueueMemoryJob("graph_extract", { conversationId: conv.id });
106
106
  enqueueMemoryJob("build_conversation_summary", {
107
107
  conversationId: conv.id,
108
108
  });
@@ -121,8 +121,6 @@ describe("wipeConversation", () => {
121
121
  .all() as Array<{ status: string; last_error: string | null }>;
122
122
 
123
123
  for (const job of jobs) {
124
- // Skip embed_item jobs enqueued by wipeConversation's unsupersede logic
125
- if (job.status === "pending") continue;
126
124
  expect(job.status).toBe("failed");
127
125
  expect(job.last_error).toContain("conversation_wiped");
128
126
  }
@@ -137,8 +135,6 @@ describe("wipeConversation", () => {
137
135
 
138
136
  expect(getConversation(conv.id)).toBeNull();
139
137
  expect(result.segmentIds).toEqual([]);
140
- expect(result.orphanedItemIds).toEqual([]);
141
- expect(result.unsupersededItemIds).toEqual([]);
142
138
  expect(result.deletedSummaryIds).toEqual([]);
143
139
  expect(result.cancelledJobCount).toBe(0);
144
140
  });
@@ -91,7 +91,7 @@ mock.module("../memory/conversation-crud.js", () => ({
91
91
  updateConversationUsage: () => {},
92
92
  updateConversationTitle: () => {},
93
93
  updateConversationContextWindow: () => {},
94
- deleteMessageById: () => ({ segmentIds: [], orphanedItemIds: [] }),
94
+ deleteMessageById: () => ({ segmentIds: [], deletedSummaryIds: [] }),
95
95
  deleteLastExchange: () => 0,
96
96
  }));
97
97
 
@@ -227,16 +227,13 @@ describe("Conversation workspace cache state", () => {
227
227
  expect(conversation.isWorkspaceTopLevelDirty()).toBe(false);
228
228
  expect(conversation.getWorkspaceTopLevelContext()).not.toBeNull();
229
229
  expect(conversation.getWorkspaceTopLevelContext()!).toContain(
230
- "<workspace_top_level>",
230
+ "<workspace>",
231
231
  );
232
232
  expect(conversation.getWorkspaceTopLevelContext()!).toContain(
233
- "</workspace_top_level>",
233
+ "</workspace>",
234
234
  );
235
235
  expect(conversation.getWorkspaceTopLevelContext()!).toContain(
236
- `Current conversation folder: ${conversationPath}`,
237
- );
238
- expect(conversation.getWorkspaceTopLevelContext()!).toContain(
239
- `Attachment files: ${conversationAttachmentsPath}`,
236
+ `Current conversation attachments: ${conversationAttachmentsPath}`,
240
237
  );
241
238
  });
242
239
 
@@ -267,7 +264,7 @@ describe("Conversation workspace cache state", () => {
267
264
 
268
265
  expect(conversation.getWorkspaceTopLevelContext()).not.toBeNull();
269
266
  expect(conversation.getWorkspaceTopLevelContext()!).toContain(
270
- "<workspace_top_level>",
267
+ "<workspace>",
271
268
  );
272
269
  expect(conversation.isWorkspaceTopLevelDirty()).toBe(false);
273
270
  });
@@ -286,10 +283,7 @@ describe("Conversation workspace cache state", () => {
286
283
  tempConversation.refreshWorkspaceTopLevelContextIfNeeded();
287
284
 
288
285
  expect(tempConversation.getWorkspaceTopLevelContext()!).toContain(
289
- `Current conversation folder: conversations/${legacyDirName}/`,
290
- );
291
- expect(tempConversation.getWorkspaceTopLevelContext()!).toContain(
292
- `Attachment files: conversations/${legacyDirName}/attachments/`,
286
+ `Current conversation attachments: conversations/${legacyDirName}/attachments/`,
293
287
  );
294
288
  } finally {
295
289
  rmSync(workspaceRoot, { recursive: true, force: true });
@@ -1,7 +1,6 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import type { AgentEvent } from "../agent/loop.js";
4
- import { getConversationDirName } from "../memory/conversation-disk-view.js";
5
4
  import type { Message, ProviderResponse } from "../providers/types.js";
6
5
 
7
6
  // ---------------------------------------------------------------------------
@@ -124,7 +123,7 @@ mock.module("../memory/conversation-crud.js", () => ({
124
123
  updateConversationUsage: () => {},
125
124
  updateConversationTitle: () => {},
126
125
  updateConversationContextWindow: () => {},
127
- deleteMessageById: () => ({ segmentIds: [], orphanedItemIds: [] }),
126
+ deleteMessageById: () => ({ segmentIds: [], deletedSummaryIds: [] }),
128
127
  deleteLastExchange: () => 0,
129
128
  }));
130
129
 
@@ -274,13 +273,6 @@ function messageText(message: Message): string {
274
273
  .join("\n");
275
274
  }
276
275
 
277
- const conversationDirName = getConversationDirName(
278
- "conv-1",
279
- Date.parse("2026-03-19T12:00:00.000Z"),
280
- );
281
- const conversationPath = `conversations/${conversationDirName}/`;
282
- const conversationAttachmentsPath = `${conversationPath}attachments/`;
283
-
284
276
  // ---------------------------------------------------------------------------
285
277
  // Tests
286
278
  // ---------------------------------------------------------------------------
@@ -302,8 +294,8 @@ describe("Conversation workspace injection", () => {
302
294
  const runtimeUser = runCalls[0][runCalls[0].length - 1];
303
295
  expect(runtimeUser.role).toBe("user");
304
296
  const text = messageText(runtimeUser);
305
- expect(text).toContain("<workspace_top_level>");
306
- expect(text).toContain("</workspace_top_level>");
297
+ expect(text).toContain("<workspace>");
298
+ expect(text).toContain("</workspace>");
307
299
  });
308
300
 
309
301
  test("workspace context includes root path and directories", async () => {
@@ -316,8 +308,8 @@ describe("Conversation workspace injection", () => {
316
308
  const runtimeUser = runCalls[0][runCalls[0].length - 1];
317
309
  const text = messageText(runtimeUser);
318
310
  expect(text).toContain("Root: /tmp");
319
- expect(text).toContain(`Current conversation folder: ${conversationPath}`);
320
- expect(text).toContain(`Attachment files: ${conversationAttachmentsPath}`);
311
+ expect(text).toContain("Directories: src, tests, docs");
312
+ expect(text).toContain("Files: README.md, package.json");
321
313
  });
322
314
 
323
315
  test("workspace context is prepended before user text", async () => {
@@ -331,33 +323,40 @@ describe("Conversation workspace injection", () => {
331
323
  const firstBlock = runtimeUser.content[0];
332
324
  expect(firstBlock.type).toBe("text");
333
325
  const firstText = (firstBlock as { type: "text"; text: string }).text;
334
- expect(firstText).toContain("<workspace_top_level>");
326
+ expect(firstText).toContain("<workspace>");
335
327
  });
336
328
 
337
- test("workspace context is stripped from persisted history", async () => {
329
+ test("workspace context persists in history (not stripped between turns)", async () => {
338
330
  const conversation = makeConversation();
339
331
  await conversation.loadFromDb();
340
332
 
341
333
  await conversation.processMessage("Hello", [], () => {});
342
334
 
335
+ // Workspace blocks use <workspace> tag which is intentionally NOT stripped.
343
336
  const persistedMessages = conversation.getMessages();
344
- for (const msg of persistedMessages) {
345
- const text = messageText(msg);
346
- expect(text).not.toContain("<workspace_top_level>");
347
- }
337
+ const userMsg = persistedMessages.find((m) => m.role === "user");
338
+ expect(userMsg).toBeDefined();
339
+ const text = messageText(userMsg!);
340
+ expect(text).toContain("<workspace>");
348
341
  });
349
342
 
350
- test("no empty user messages after stripping workspace context", async () => {
343
+ test("second message does NOT include workspace block", async () => {
351
344
  const conversation = makeConversation();
352
345
  await conversation.loadFromDb();
353
346
 
347
+ // First message — workspace is injected
354
348
  await conversation.processMessage("Hello", [], () => {});
355
-
356
- const persistedMessages = conversation.getMessages();
357
- const emptyUserMsgs = persistedMessages.filter(
358
- (m) => m.role === "user" && m.content.length === 0,
359
- );
360
- expect(emptyUserMsgs).toHaveLength(0);
349
+ expect(runCalls).toHaveLength(1);
350
+ const firstCallUser = runCalls[0][runCalls[0].length - 1];
351
+ const firstText = messageText(firstCallUser);
352
+ expect(firstText).toContain("<workspace>");
353
+
354
+ // Second message — workspace is NOT injected (not first message, no compaction)
355
+ await conversation.processMessage("Follow up", [], () => {});
356
+ expect(runCalls).toHaveLength(2);
357
+ const secondCallUser = runCalls[1][runCalls[1].length - 1];
358
+ const secondText = messageText(secondCallUser);
359
+ expect(secondText).not.toContain("<workspace>");
361
360
  });
362
361
  });
363
362
 
@@ -120,7 +120,7 @@ mock.module("../memory/conversation-crud.js", () => ({
120
120
  updateConversationUsage: () => {},
121
121
  updateConversationTitle: () => {},
122
122
  updateConversationContextWindow: () => {},
123
- deleteMessageById: () => ({ segmentIds: [], orphanedItemIds: [] }),
123
+ deleteMessageById: () => ({ segmentIds: [], deletedSummaryIds: [] }),
124
124
  deleteLastExchange: () => 0,
125
125
  }));
126
126