@vellumai/assistant 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -0,0 +1,458 @@
1
+ /**
2
+ * Tests for the external plugin loader.
3
+ *
4
+ * The loader now owns the timeout / try-catch / `registerPlugin` triple
5
+ * directly, so tests exercise observable behavior: after
6
+ * `await loadExternalPlugin(dir)`, what does the registry hold?
7
+ *
8
+ * Each test materializes a synthetic plugin directory under a per-file
9
+ * tempdir. Surface files use plain TypeScript with default exports so
10
+ * bun can dynamic-import them at runtime without a build step.
11
+ */
12
+ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { afterAll, beforeEach, describe, expect, test } from "bun:test";
16
+
17
+ import { loadExternalPlugin } from "../plugins/external-plugin-loader.js";
18
+ import {
19
+ getRegisteredPlugins,
20
+ resetPluginRegistryForTests,
21
+ } from "../plugins/registry.js";
22
+
23
+ const ROOT = join(
24
+ tmpdir(),
25
+ `vellum-external-plugin-loader-test-${process.pid}-${Date.now()}`,
26
+ );
27
+
28
+ function freshPluginDir(name: string): string {
29
+ const dir = join(ROOT, name);
30
+ rmSync(dir, { recursive: true, force: true });
31
+ mkdirSync(dir, { recursive: true });
32
+ return dir;
33
+ }
34
+
35
+ function writePackageJson(dir: string, pkg: Record<string, unknown>): void {
36
+ writeFileSync(join(dir, "package.json"), JSON.stringify(pkg, null, 2));
37
+ }
38
+
39
+ function writeSurfaceFile(dir: string, relPath: string, body: string): void {
40
+ const parts = relPath.split("/");
41
+ parts.pop();
42
+ if (parts.length > 0) {
43
+ mkdirSync(join(dir, ...parts), { recursive: true });
44
+ }
45
+ writeFileSync(join(dir, relPath), body);
46
+ }
47
+
48
+ function registeredNames(): string[] {
49
+ return getRegisteredPlugins().map((p) => p.manifest.name);
50
+ }
51
+
52
+ beforeEach(() => {
53
+ resetPluginRegistryForTests();
54
+ });
55
+
56
+ afterAll(() => {
57
+ rmSync(ROOT, { recursive: true, force: true });
58
+ resetPluginRegistryForTests();
59
+ });
60
+
61
+ describe("loadExternalPlugin — manifest", () => {
62
+ test("uses package.json name and version", async () => {
63
+ const dir = freshPluginDir("minimal");
64
+ writePackageJson(dir, { name: "minimal-plugin", version: "1.2.3" });
65
+
66
+ await loadExternalPlugin(dir);
67
+
68
+ const registered = getRegisteredPlugins().find(
69
+ (p) => p.manifest.name === "minimal-plugin",
70
+ );
71
+ expect(registered).toBeDefined();
72
+ expect(registered?.manifest.version).toBe("1.2.3");
73
+ // Defaults to pluginRuntime v1 when no `vellum.requires` is set.
74
+ expect(registered?.manifest.requires).toEqual({ pluginRuntime: "v1" });
75
+ });
76
+
77
+ test("strips npm scope from name", async () => {
78
+ const dir = freshPluginDir("scoped");
79
+ writePackageJson(dir, {
80
+ name: "@vellumai/simple-memory",
81
+ version: "0.1.0",
82
+ });
83
+
84
+ await loadExternalPlugin(dir);
85
+
86
+ expect(registeredNames()).toContain("simple-memory");
87
+ });
88
+
89
+ test("defaults version to 0.0.0 when package.json omits it", async () => {
90
+ const dir = freshPluginDir("no-version");
91
+ writePackageJson(dir, { name: "no-version-plugin" });
92
+
93
+ await loadExternalPlugin(dir);
94
+
95
+ const registered = getRegisteredPlugins().find(
96
+ (p) => p.manifest.name === "no-version-plugin",
97
+ );
98
+ expect(registered?.manifest.version).toBe("0.0.0");
99
+ });
100
+
101
+ test("reads vellum.requires from package.json when present", async () => {
102
+ // Future direction (out of scope this PR): `requires` may carry
103
+ // `assistantVersion` alongside `pluginRuntime`. For today the registry
104
+ // validates against `ASSISTANT_API_VERSIONS` and only `pluginRuntime`
105
+ // is a known capability — so the loader's pass-through behavior is
106
+ // exercised with the keys the registry already accepts. The loader is
107
+ // opaque to the shape; additional keys propagate identically.
108
+ const dir = freshPluginDir("custom-requires");
109
+ writePackageJson(dir, {
110
+ name: "custom-requires",
111
+ version: "0.1.0",
112
+ vellum: { requires: { pluginRuntime: "v1" } },
113
+ });
114
+
115
+ await loadExternalPlugin(dir);
116
+
117
+ const registered = getRegisteredPlugins().find(
118
+ (p) => p.manifest.name === "custom-requires",
119
+ );
120
+ expect(registered?.manifest.requires).toEqual({ pluginRuntime: "v1" });
121
+ });
122
+
123
+ test("vellum.requires overrides the default — empty requires fails registration", async () => {
124
+ // Belt-and-suspenders proof that the loader reads `vellum.requires`
125
+ // rather than always defaulting: an empty `vellum.requires` propagates
126
+ // through, the registry rejects the plugin (missing pluginRuntime),
127
+ // and the registry stays empty.
128
+ const dir = freshPluginDir("empty-requires");
129
+ writePackageJson(dir, {
130
+ name: "empty-requires",
131
+ version: "0.1.0",
132
+ vellum: { requires: {} },
133
+ });
134
+
135
+ await loadExternalPlugin(dir);
136
+
137
+ expect(registeredNames()).not.toContain("empty-requires");
138
+ });
139
+
140
+ test("does not synthesize a provides field", async () => {
141
+ const dir = freshPluginDir("no-provides");
142
+ writePackageJson(dir, { name: "no-provides", version: "0.1.0" });
143
+
144
+ await loadExternalPlugin(dir);
145
+
146
+ const registered = getRegisteredPlugins().find(
147
+ (p) => p.manifest.name === "no-provides",
148
+ );
149
+ expect(registered?.manifest.provides).toBeUndefined();
150
+ });
151
+
152
+ test("malformed package.json is logged and skipped (registry untouched)", async () => {
153
+ const dir = freshPluginDir("malformed-pkg");
154
+ writeFileSync(join(dir, "package.json"), "{ this is not json");
155
+
156
+ await loadExternalPlugin(dir);
157
+
158
+ expect(registeredNames()).toHaveLength(0);
159
+ });
160
+
161
+ test("package.json missing name is logged and skipped", async () => {
162
+ const dir = freshPluginDir("no-name");
163
+ writePackageJson(dir, { version: "1.0.0" });
164
+
165
+ await loadExternalPlugin(dir);
166
+
167
+ expect(registeredNames()).toHaveLength(0);
168
+ });
169
+
170
+ test("empty string name is logged and skipped", async () => {
171
+ const dir = freshPluginDir("empty-name");
172
+ writePackageJson(dir, { name: "", version: "1.0.0" });
173
+
174
+ await loadExternalPlugin(dir);
175
+
176
+ expect(registeredNames()).toHaveLength(0);
177
+ });
178
+ });
179
+
180
+ describe("loadExternalPlugin — hooks", () => {
181
+ test("wires hooks/init.ts default export to plugin.hooks.init", async () => {
182
+ const dir = freshPluginDir("with-init");
183
+ writePackageJson(dir, { name: "with-init", version: "0.1.0" });
184
+ writeSurfaceFile(
185
+ dir,
186
+ "hooks/init.ts",
187
+ `export default async function init(_ctx: unknown): Promise<void> {
188
+ (globalThis as Record<string, unknown>).__externalInitCalled = true;
189
+ }
190
+ `,
191
+ );
192
+
193
+ await loadExternalPlugin(dir);
194
+
195
+ const registered = getRegisteredPlugins().find(
196
+ (p) => p.manifest.name === "with-init",
197
+ );
198
+ expect(typeof registered?.hooks?.init).toBe("function");
199
+ await registered?.hooks?.init?.({} as never);
200
+ expect(
201
+ (globalThis as Record<string, unknown>).__externalInitCalled,
202
+ ).toBe(true);
203
+ delete (globalThis as Record<string, unknown>).__externalInitCalled;
204
+ });
205
+
206
+ test("wires hooks/shutdown.ts default export to plugin.hooks.shutdown", async () => {
207
+ const dir = freshPluginDir("with-shutdown");
208
+ writePackageJson(dir, { name: "with-shutdown", version: "0.1.0" });
209
+ writeSurfaceFile(
210
+ dir,
211
+ "hooks/shutdown.ts",
212
+ `export default async function shutdown(ctx: { assistantVersion: string }): Promise<void> {
213
+ (globalThis as Record<string, unknown>).__externalShutdownCalled = true;
214
+ (globalThis as Record<string, unknown>).__externalShutdownVersion =
215
+ ctx.assistantVersion;
216
+ }
217
+ `,
218
+ );
219
+
220
+ await loadExternalPlugin(dir);
221
+
222
+ const registered = getRegisteredPlugins().find(
223
+ (p) => p.manifest.name === "with-shutdown",
224
+ );
225
+ expect(typeof registered?.hooks?.shutdown).toBe("function");
226
+ await registered?.hooks?.shutdown?.({ assistantVersion: "9.9.9-test" });
227
+ expect(
228
+ (globalThis as Record<string, unknown>).__externalShutdownCalled,
229
+ ).toBe(true);
230
+ expect(
231
+ (globalThis as Record<string, unknown>).__externalShutdownVersion,
232
+ ).toBe("9.9.9-test");
233
+ delete (globalThis as Record<string, unknown>).__externalShutdownCalled;
234
+ delete (globalThis as Record<string, unknown>).__externalShutdownVersion;
235
+ });
236
+
237
+ test("ignores hooks/*.d.ts declaration files alongside hooks/*.js", async () => {
238
+ // Compiled plugins ship `init.js` + `init.d.ts` side-by-side. The walker
239
+ // must filter the declaration files out — they have no default-exported
240
+ // runtime function, and crashing `importDefault` would skip the plugin
241
+ // wholesale. Regression guard for the .d.ts ingest bug fixed in this PR.
242
+ const dir = freshPluginDir("with-dts");
243
+ writePackageJson(dir, { name: "with-dts", version: "0.1.0" });
244
+ writeSurfaceFile(
245
+ dir,
246
+ "hooks/init.js",
247
+ `export default async function init(_ctx) {
248
+ (globalThis).__externalDtsInitCalled = true;
249
+ }
250
+ `,
251
+ );
252
+ writeSurfaceFile(
253
+ dir,
254
+ "hooks/init.d.ts",
255
+ `export default function init(ctx: unknown): Promise<void>;\n`,
256
+ );
257
+
258
+ await loadExternalPlugin(dir);
259
+
260
+ const registered = getRegisteredPlugins().find(
261
+ (p) => p.manifest.name === "with-dts",
262
+ );
263
+ expect(registered).toBeDefined();
264
+ expect(Object.keys(registered?.hooks ?? {})).toEqual(["init"]);
265
+ expect(typeof registered?.hooks?.init).toBe("function");
266
+ await registered?.hooks?.init?.({} as never);
267
+ expect((globalThis as Record<string, unknown>).__externalDtsInitCalled).toBe(
268
+ true,
269
+ );
270
+ delete (globalThis as Record<string, unknown>).__externalDtsInitCalled;
271
+ });
272
+
273
+ test("plugin.hooks is undefined when neither hook file is present", async () => {
274
+ const dir = freshPluginDir("no-hooks");
275
+ writePackageJson(dir, { name: "no-hooks", version: "0.1.0" });
276
+
277
+ await loadExternalPlugin(dir);
278
+
279
+ const registered = getRegisteredPlugins().find(
280
+ (p) => p.manifest.name === "no-hooks",
281
+ );
282
+ expect(registered?.hooks).toBeUndefined();
283
+ });
284
+
285
+ test("hooks/init.ts with no default export is logged and skipped", async () => {
286
+ const dir = freshPluginDir("init-no-default");
287
+ writePackageJson(dir, { name: "init-no-default", version: "0.1.0" });
288
+ writeSurfaceFile(
289
+ dir,
290
+ "hooks/init.ts",
291
+ `export const init = async () => undefined;\n`,
292
+ );
293
+
294
+ await loadExternalPlugin(dir);
295
+
296
+ expect(registeredNames()).toHaveLength(0);
297
+ });
298
+
299
+ test("hooks/init.ts default export not a function is logged and skipped", async () => {
300
+ const dir = freshPluginDir("init-not-fn");
301
+ writePackageJson(dir, { name: "init-not-fn", version: "0.1.0" });
302
+ writeSurfaceFile(
303
+ dir,
304
+ "hooks/init.ts",
305
+ `export default { not: "a function" };\n`,
306
+ );
307
+
308
+ await loadExternalPlugin(dir);
309
+
310
+ expect(registeredNames()).toHaveLength(0);
311
+ });
312
+ });
313
+
314
+ describe("loadExternalPlugin — tools", () => {
315
+ test("collects every default-exported tool under tools/", async () => {
316
+ const dir = freshPluginDir("two-tools");
317
+ writePackageJson(dir, { name: "two-tools", version: "0.1.0" });
318
+ writeSurfaceFile(
319
+ dir,
320
+ "tools/alpha.ts",
321
+ `export default {
322
+ name: "two_tools_alpha",
323
+ description: "alpha",
324
+ category: "plugin",
325
+ defaultRiskLevel: "low" as const,
326
+ getDefinition() { return { name: "two_tools_alpha", description: "alpha", input_schema: { type: "object", properties: {}, required: [] } }; },
327
+ async execute() { return { content: "a", isError: false }; },
328
+ };
329
+ `,
330
+ );
331
+ writeSurfaceFile(
332
+ dir,
333
+ "tools/beta.ts",
334
+ `export default {
335
+ name: "two_tools_beta",
336
+ description: "beta",
337
+ category: "plugin",
338
+ defaultRiskLevel: "low" as const,
339
+ getDefinition() { return { name: "two_tools_beta", description: "beta", input_schema: { type: "object", properties: {}, required: [] } }; },
340
+ async execute() { return { content: "b", isError: false }; },
341
+ };
342
+ `,
343
+ );
344
+
345
+ await loadExternalPlugin(dir);
346
+
347
+ const registered = getRegisteredPlugins().find(
348
+ (p) => p.manifest.name === "two-tools",
349
+ );
350
+ const names = (registered?.tools ?? []).map(
351
+ (t) => (t as { name: string }).name,
352
+ );
353
+ expect(names).toEqual(["two_tools_alpha", "two_tools_beta"]);
354
+ });
355
+
356
+ test("plugin.tools is undefined when tools/ is absent", async () => {
357
+ const dir = freshPluginDir("no-tools");
358
+ writePackageJson(dir, { name: "no-tools", version: "0.1.0" });
359
+
360
+ await loadExternalPlugin(dir);
361
+
362
+ const registered = getRegisteredPlugins().find(
363
+ (p) => p.manifest.name === "no-tools",
364
+ );
365
+ expect(registered?.tools).toBeUndefined();
366
+ });
367
+
368
+ test("a tool file with no default export is logged and skipped", async () => {
369
+ const dir = freshPluginDir("tool-no-default");
370
+ writePackageJson(dir, { name: "tool-no-default", version: "0.1.0" });
371
+ writeSurfaceFile(
372
+ dir,
373
+ "tools/broken.ts",
374
+ `export const broken = { name: "broken" };\n`,
375
+ );
376
+
377
+ await loadExternalPlugin(dir);
378
+
379
+ expect(registeredNames()).toHaveLength(0);
380
+ });
381
+
382
+ test("a tool default export missing string name is logged and skipped", async () => {
383
+ const dir = freshPluginDir("tool-no-name");
384
+ writePackageJson(dir, { name: "tool-no-name", version: "0.1.0" });
385
+ writeSurfaceFile(
386
+ dir,
387
+ "tools/nameless.ts",
388
+ `export default { description: "missing name" };\n`,
389
+ );
390
+
391
+ await loadExternalPlugin(dir);
392
+
393
+ expect(registeredNames()).toHaveLength(0);
394
+ });
395
+ });
396
+
397
+ describe("loadExternalPlugin — isolation", () => {
398
+ test("never throws when a load fails — error is logged and skipped", async () => {
399
+ const dir = freshPluginDir("definitely-broken");
400
+ writeFileSync(join(dir, "package.json"), "{ broken");
401
+
402
+ await expect(loadExternalPlugin(dir)).resolves.toBeUndefined();
403
+ expect(registeredNames()).toHaveLength(0);
404
+ });
405
+
406
+ test("times out and skips when build exceeds the timeout", async () => {
407
+ // hooks/init.ts has a top-level await that never resolves. The build
408
+ // hangs on dynamic-importing this surface file; the loader's timeout
409
+ // must rescue the daemon boot.
410
+ const dir = freshPluginDir("hanging-init");
411
+ writePackageJson(dir, { name: "hanging-init", version: "0.1.0" });
412
+ writeSurfaceFile(
413
+ dir,
414
+ "hooks/init.ts",
415
+ `await new Promise(() => {});
416
+ export default async function init(_ctx: unknown): Promise<void> {}
417
+ `,
418
+ );
419
+
420
+ await loadExternalPlugin(dir, { importTimeoutMs: 50 });
421
+
422
+ expect(registeredNames()).not.toContain("hanging-init");
423
+ });
424
+ });
425
+
426
+ describe("loadExternalPlugin — end-to-end @vellumai/simple-memory", () => {
427
+ test("loads the in-tree simple-memory plugin", async () => {
428
+ // Resolve the real on-disk plugin from the worktree. This double-acts
429
+ // as the loader's contract test against the canonical Phase 0 plugin
430
+ // and exercises the relative `../src/state.js` imports inside the
431
+ // plugin's surface files.
432
+ const pluginDir = join(
433
+ import.meta.dir,
434
+ "..",
435
+ "..",
436
+ "..",
437
+ "experimental",
438
+ "plugins",
439
+ "simple-memory",
440
+ );
441
+
442
+ await loadExternalPlugin(pluginDir);
443
+
444
+ const registered = getRegisteredPlugins().find(
445
+ (p) => p.manifest.name === "simple-memory",
446
+ );
447
+ expect(registered).toBeDefined();
448
+ expect(typeof registered?.hooks?.init).toBe("function");
449
+ expect(typeof registered?.hooks?.shutdown).toBe("function");
450
+ const toolNames = (registered?.tools ?? [])
451
+ .map((t) => (t as { name: string }).name)
452
+ .sort();
453
+ expect(toolNames).toEqual([
454
+ "simple_memory_recall",
455
+ "simple_memory_remember",
456
+ ]);
457
+ });
458
+ });
@@ -7,6 +7,13 @@ import { LLMSchema } from "../config/schemas/llm.js";
7
7
 
8
8
  const testWorkspaceDir = process.env.VELLUM_WORKSPACE_DIR!;
9
9
 
10
+ // Default the warm-pool gate to OPEN for existing tests — they predate
11
+ // the gate and expect filing's runOnce() to fire on every tick.
12
+ mock.module("../runtime/pre-first-message-gate.js", () => ({
13
+ hasReceivedUserMessage: () => true,
14
+ _resetPreFirstMessageGateCacheForTests: () => {},
15
+ }));
16
+
10
17
  // Mock config loader. Filing's `runOnce()` reads `getConfig().filing`, and
11
18
  // `executeRun()` no longer reads `config.speed` (PR 8) — the call site is
12
19
  // hardcoded to 'filingAgent' and the resolver picks up `llm.callSites.filingAgent`
@@ -35,8 +42,12 @@ mock.module("../config/loader.js", () => ({
35
42
  }));
36
43
 
37
44
  // Mock conversation store
38
- const createdConversations: Array<{ title: string; conversationType: string }> =
39
- [];
45
+ const createdConversations: Array<{
46
+ title: string;
47
+ conversationType: string;
48
+ source?: string;
49
+ groupId?: string;
50
+ }> = [];
40
51
  let conversationIdCounter = 0;
41
52
 
42
53
  mock.module("../memory/conversation-crud.js", () => ({
@@ -63,7 +74,12 @@ mock.module("../memory/conversation-crud.js", () => ({
63
74
  }),
64
75
  getConversationOriginInterface: () => null,
65
76
  getConversationOriginChannel: () => null,
66
- createConversation: (opts: { title: string; conversationType: string }) => {
77
+ createConversation: (opts: {
78
+ title: string;
79
+ conversationType: string;
80
+ source?: string;
81
+ groupId?: string;
82
+ }) => {
67
83
  createdConversations.push(opts);
68
84
  return { id: `conv-${++conversationIdCounter}`, ...opts };
69
85
  },
@@ -220,6 +236,10 @@ describe("FilingService", () => {
220
236
  expect(createdConversations).toHaveLength(1);
221
237
  expect(createdConversations[0].title).toBe("Generating title...");
222
238
  expect(createdConversations[0].conversationType).toBe("background");
239
+ // Confirms FilingService routes through runBackgroundJob:
240
+ // source="filing" + runner-default groupId="system:background".
241
+ expect(createdConversations[0].source).toBe("filing");
242
+ expect(createdConversations[0].groupId).toBe("system:background");
223
243
  });
224
244
 
225
245
  describe("runCompactionOnce()", () => {
@@ -224,6 +224,11 @@ export function createMockChromeExtension(
224
224
  headers: {
225
225
  "Content-Type": "application/json",
226
226
  Authorization: `Bearer ${options.token}`,
227
+ // Same-actor binding: identifies this fixture to the daemon's
228
+ // result-route check. The daemon will reject targeted host_browser
229
+ // results without this header (or where it doesn't match the
230
+ // captured target client).
231
+ "X-Vellum-Client-Id": clientId,
227
232
  },
228
233
  body: JSON.stringify(body),
229
234
  });
@@ -34,7 +34,6 @@ const ALLOWLIST = new Set([
34
34
 
35
35
  // --- Chrome extension (local relay communication, not gateway API consumption) ---
36
36
  "clients/chrome-extension/background/worker.ts",
37
- "clients/chrome-extension/popup/popup.ts",
38
37
  // --- Documentation and comments that mention the port for explanatory purposes ---
39
38
  "AGENTS.md", // documents the gateway-only rule itself
40
39
  "ARCHITECTURE.md", // architecture overview with port references
@@ -191,6 +191,40 @@ describe("parseExtractionResponse event_date coercion", () => {
191
191
  expect(diff.updateNodes[0].changes.eventDate).toBe(1712534400000);
192
192
  });
193
193
 
194
+ test("auto-creates an event trigger for future event_date", () => {
195
+ const conversationTs = Date.UTC(2026, 3, 26, 0, 0, 0);
196
+ const futureEventDate = Date.UTC(2026, 5, 1, 0, 0, 0);
197
+ const input = makeInput({ event_date: futureEventDate });
198
+ const { deferredTriggers } = parseExtractionResponse(
199
+ input,
200
+ conversationId,
201
+ scopeId,
202
+ candidateNodeIds,
203
+ conversationTs,
204
+ );
205
+ const auto = deferredTriggers.find(
206
+ (t) =>
207
+ t.trigger.type === "event" && t.trigger.eventDate === futureEventDate,
208
+ );
209
+ expect(auto).toBeTruthy();
210
+ });
211
+
212
+ test("does not auto-create an event trigger for past event_date", () => {
213
+ const conversationTs = Date.UTC(2026, 3, 26, 0, 0, 0);
214
+ const pastEventDate = Date.UTC(2025, 0, 15, 0, 0, 0);
215
+ const input = makeInput({ event_date: pastEventDate });
216
+ const { deferredTriggers } = parseExtractionResponse(
217
+ input,
218
+ conversationId,
219
+ scopeId,
220
+ candidateNodeIds,
221
+ conversationTs,
222
+ );
223
+ expect(deferredTriggers.some((t) => t.trigger.type === "event")).toBe(
224
+ false,
225
+ );
226
+ });
227
+
194
228
  test("null-clears event_date on update_nodes when explicitly null", () => {
195
229
  const existingNodeId = "existing-node-1";
196
230
  const candidates = new Set([existingNodeId]);
@@ -245,12 +245,4 @@ describe("v2 skill re-seed gating in skill handlers", () => {
245
245
  expect(mockMaybeSeedMemoryV2Skills).toHaveBeenCalledTimes(1);
246
246
  expect(callOrder).toEqual(["v1"]);
247
247
  });
248
-
249
- // Note: "seed rejection swallowed" is now an internal concern of
250
- // `maybeSeedMemoryV2Skills` — it dispatches the seed call as a
251
- // fire-and-forget promise with `.catch(log.warn)`. That behavior is
252
- // covered by `lifecycle-memory-v2-seed.test.ts`. From the handler's
253
- // perspective, we only need to verify the helper is invoked
254
- // synchronously with the correct config — which the cases above already
255
- // exercise.
256
248
  });
@@ -1,5 +1,12 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
+ // Default the warm-pool gate to OPEN — these tests probe disk-pressure
4
+ // behavior, not the pre-first-message guard.
5
+ mock.module("../runtime/pre-first-message-gate.js", () => ({
6
+ hasReceivedUserMessage: () => true,
7
+ _resetPreFirstMessageGateCacheForTests: () => {},
8
+ }));
9
+
3
10
  mock.module("../util/logger.js", () => ({
4
11
  getLogger: () => ({
5
12
  info: () => {},
@@ -63,6 +70,10 @@ mock.module("../memory/conversation-crud.js", () => ({
63
70
  createdConversations.push(opts);
64
71
  return { id: "conv-1", ...opts };
65
72
  },
73
+ // runBackgroundJob (loaded transitively via heartbeat-service) imports
74
+ // addMessage. Disk-pressure short-circuits before addMessage ever runs,
75
+ // but the mock module must still expose every name the real module does.
76
+ addMessage: () => Promise.resolve({ id: "mock-msg-id" }),
66
77
  }));
67
78
 
68
79
  const mockProcessMessage = mock(() => Promise.resolve({ messageId: "msg-1" }));
@@ -70,9 +81,11 @@ mock.module("../daemon/process-message.js", () => ({
70
81
  processMessage: mockProcessMessage,
71
82
  }));
72
83
 
73
- const mockEmitFeedEvent = mock(() => Promise.resolve());
74
- mock.module("../home/emit-feed-event.js", () => ({
75
- emitFeedEvent: mockEmitFeedEvent,
84
+ const emittedNotificationSignals: Array<{ sourceEventName?: string }> = [];
85
+ mock.module("../notifications/emit-signal.js", () => ({
86
+ emitNotificationSignal: async (opts: { sourceEventName?: string }) => {
87
+ emittedNotificationSignals.push({ sourceEventName: opts.sourceEventName });
88
+ },
76
89
  }));
77
90
 
78
91
  mock.module("../prompts/persona-resolver.js", () => ({
@@ -131,10 +144,10 @@ describe("HeartbeatService disk pressure gate", () => {
131
144
  mockMarkStaleRunningAsError.mockClear();
132
145
  mockMarkStaleRunningAsError.mockImplementation(() => 0);
133
146
  mockProcessMessage.mockClear();
134
- mockEmitFeedEvent.mockClear();
147
+ emittedNotificationSignals.length = 0;
135
148
  });
136
149
 
137
- test("skips without creating heartbeat rows, conversations, or feed events", async () => {
150
+ test("skips without creating heartbeat rows, conversations, or notifications", async () => {
138
151
  const service = new HeartbeatService({
139
152
  alerter: () => {},
140
153
  });
@@ -148,7 +161,7 @@ describe("HeartbeatService disk pressure gate", () => {
148
161
  expect(mockSkipHeartbeatRun).not.toHaveBeenCalled();
149
162
  expect(createdConversations).toHaveLength(0);
150
163
  expect(mockProcessMessage).not.toHaveBeenCalled();
151
- expect(mockEmitFeedEvent).not.toHaveBeenCalled();
164
+ expect(emittedNotificationSignals).toHaveLength(0);
152
165
  });
153
166
 
154
167
  test("allows forced user-initiated heartbeat runs while locked", async () => {
@@ -168,7 +181,7 @@ describe("HeartbeatService disk pressure gate", () => {
168
181
  expect(mockProcessMessage).toHaveBeenCalledTimes(1);
169
182
  });
170
183
 
171
- test("start recovery skips missed-run feed events while locked", async () => {
184
+ test("start recovery skips missed-run notifications while locked", async () => {
172
185
  mockMarkStaleRunsAsMissed.mockImplementationOnce(() => 1);
173
186
  const service = new HeartbeatService({
174
187
  alerter: () => {},
@@ -178,6 +191,6 @@ describe("HeartbeatService disk pressure gate", () => {
178
191
  await service.stop();
179
192
 
180
193
  expect(mockMarkStaleRunsAsMissed).toHaveBeenCalledTimes(1);
181
- expect(mockEmitFeedEvent).not.toHaveBeenCalled();
194
+ expect(emittedNotificationSignals).toHaveLength(0);
182
195
  });
183
196
  });