@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
@@ -43,29 +43,23 @@ mock.module("../../runtime/assistant-event-hub.js", () => ({
43
43
  const {
44
44
  HOME_FEED_FILENAME,
45
45
  HOME_FEED_VERSION,
46
- MAX_ACTIONS_PER_SOURCE,
47
46
  appendFeedItem,
48
47
  getHomeFeedPath,
49
48
  patchFeedItemStatus,
50
49
  readHomeFeed,
51
50
  } = await import("../feed-writer.js");
52
51
 
53
- type FeedItemType = "nudge" | "digest" | "action" | "thread";
54
- type FeedItemAuthor = "assistant" | "platform";
55
52
  type FeedItemStatus = "new" | "seen" | "acted_on";
56
- type FeedItemSource = "gmail" | "slack" | "calendar" | "assistant";
57
53
 
58
54
  interface TestFeedItem {
59
55
  id: string;
60
- type: FeedItemType;
56
+ type: "notification";
61
57
  priority: number;
62
58
  title: string;
63
59
  summary: string;
64
- source?: FeedItemSource;
65
60
  timestamp: string;
66
61
  status: FeedItemStatus;
67
62
  expiresAt?: string;
68
- author: FeedItemAuthor;
69
63
  createdAt: string;
70
64
  }
71
65
 
@@ -73,13 +67,12 @@ function makeItem(
73
67
  overrides: Partial<TestFeedItem> & { id: string },
74
68
  ): TestFeedItem {
75
69
  return {
76
- type: "nudge",
70
+ type: "notification",
77
71
  priority: 50,
78
72
  title: "Test",
79
73
  summary: "Test summary",
80
74
  timestamp: "2026-04-14T12:00:00.000Z",
81
75
  status: "new",
82
- author: "platform",
83
76
  createdAt: "2026-04-14T12:00:00.000Z",
84
77
  ...overrides,
85
78
  };
@@ -127,7 +120,7 @@ describe("feed-writer", () => {
127
120
  });
128
121
 
129
122
  describe("readHomeFeed", () => {
130
- test("missing file returns an empty v1 HomeFeedFile", () => {
123
+ test("missing file returns an empty v2 HomeFeedFile", () => {
131
124
  const feed = readHomeFeed();
132
125
  expect(feed.version).toBe(HOME_FEED_VERSION);
133
126
  expect(feed.items).toEqual([]);
@@ -139,17 +132,15 @@ describe("feed-writer", () => {
139
132
  const past = new Date(Date.now() - 60_000).toISOString();
140
133
  const future = new Date(Date.now() + 60_000).toISOString();
141
134
  const file = {
142
- version: 1,
135
+ version: 2,
143
136
  updatedAt: "2026-04-14T12:00:00.000Z",
144
137
  items: [
145
138
  makeItem({
146
139
  id: "expired",
147
- type: "action",
148
140
  expiresAt: past,
149
141
  }),
150
142
  makeItem({
151
143
  id: "live",
152
- type: "action",
153
144
  expiresAt: future,
154
145
  }),
155
146
  ],
@@ -167,327 +158,144 @@ describe("feed-writer", () => {
167
158
  const feed = readHomeFeed();
168
159
  expect(feed.items).toEqual([]);
169
160
  });
161
+
162
+ test("v1 file (legacy schema) fails Zod validation and falls back to empty", () => {
163
+ // Defensive: if the workspace migration has not yet run (e.g. on
164
+ // first daemon boot before migrations land, or a corrupted
165
+ // migration checkpoint), the writer's read path must degrade
166
+ // gracefully rather than throwing.
167
+ mkdirSync(join(workspaceDir, "data"), { recursive: true });
168
+ const v1File = {
169
+ version: 1,
170
+ updatedAt: "2026-04-14T12:00:00.000Z",
171
+ items: [
172
+ {
173
+ id: "legacy",
174
+ type: "nudge",
175
+ priority: 50,
176
+ title: "Legacy",
177
+ summary: "Legacy summary",
178
+ source: "gmail",
179
+ author: "platform",
180
+ timestamp: "2026-04-14T12:00:00.000Z",
181
+ status: "new",
182
+ createdAt: "2026-04-14T12:00:00.000Z",
183
+ },
184
+ ],
185
+ };
186
+ writeFileSync(
187
+ getHomeFeedPath(),
188
+ JSON.stringify(v1File, null, 2),
189
+ "utf-8",
190
+ );
191
+
192
+ const feed = readHomeFeed();
193
+ expect(feed.items).toEqual([]);
194
+ });
170
195
  });
171
196
 
172
197
  describe("appendFeedItem", () => {
173
- test("appends a single nudge to disk", async () => {
198
+ test("appends a single notification to disk as v2", async () => {
174
199
  await appendFeedItem(
175
200
  makeItem({
176
- id: "nudge-1",
177
- type: "nudge",
178
- source: "gmail",
201
+ id: "notif-1",
179
202
  title: "New email",
180
203
  summary: "You have a new email",
181
204
  }),
182
205
  );
183
206
  const decoded = readFileJson();
184
- expect(decoded.version).toBe(1);
207
+ expect(decoded.version).toBe(2);
185
208
  expect(decoded.items).toHaveLength(1);
186
- expect(decoded.items[0]!.id).toBe("nudge-1");
209
+ expect(decoded.items[0]!.id).toBe("notif-1");
210
+ expect(decoded.items[0]!.type).toBe("notification");
187
211
  expect(decoded.items[0]!.title).toBe("New email");
188
212
  });
189
213
 
190
- test("second digest from the same source replaces the first", async () => {
214
+ test("incoming item with the same id replaces the existing entry in place", async () => {
215
+ // The v2 merge rule: same-id replaces (preserving array
216
+ // position); otherwise append. Older entries with the same id
217
+ // must NOT linger in the list as duplicates.
191
218
  await appendFeedItem(
192
219
  makeItem({
193
- id: "digest-old",
194
- type: "digest",
195
- source: "gmail",
196
- title: "Old digest",
220
+ id: "dup",
221
+ title: "Original title",
197
222
  createdAt: "2026-04-14T10:00:00.000Z",
198
223
  }),
199
224
  );
200
225
  await appendFeedItem(
201
226
  makeItem({
202
- id: "digest-new",
203
- type: "digest",
204
- source: "gmail",
205
- title: "New digest",
227
+ id: "other",
228
+ title: "Other entry",
206
229
  createdAt: "2026-04-14T11:00:00.000Z",
207
230
  }),
208
231
  );
209
-
210
- const decoded = readFileJson();
211
- const digests = decoded.items.filter((i) => i.type === "digest");
212
- expect(digests).toHaveLength(1);
213
- expect(digests[0]!.id).toBe("digest-new");
214
- expect(digests[0]!.title).toBe("New digest");
215
- });
216
-
217
- test("assistant nudge overwrites an existing platform nudge for the same source", async () => {
218
- await appendFeedItem(
219
- makeItem({
220
- id: "platform-nudge",
221
- type: "nudge",
222
- source: "slack",
223
- author: "platform",
224
- title: "Platform baseline",
225
- }),
226
- );
227
- await appendFeedItem(
228
- makeItem({
229
- id: "assistant-nudge",
230
- type: "nudge",
231
- source: "slack",
232
- author: "assistant",
233
- title: "Assistant override",
234
- }),
235
- );
236
-
237
- const decoded = readFileJson();
238
- const nudges = decoded.items.filter(
239
- (i) => i.type === "nudge" && i.source === "slack",
240
- );
241
- expect(nudges).toHaveLength(1);
242
- expect(nudges[0]!.author).toBe("assistant");
243
- expect(nudges[0]!.title).toBe("Assistant override");
244
- });
245
-
246
- test("platform nudge over an existing assistant nudge is a no-op", async () => {
247
- await appendFeedItem(
248
- makeItem({
249
- id: "assistant-nudge",
250
- type: "nudge",
251
- source: "slack",
252
- author: "assistant",
253
- title: "Assistant original",
254
- }),
255
- );
256
- await appendFeedItem(
257
- makeItem({
258
- id: "platform-nudge",
259
- type: "nudge",
260
- source: "slack",
261
- author: "platform",
262
- title: "Stale platform baseline",
263
- }),
264
- );
265
-
266
- const decoded = readFileJson();
267
- const nudges = decoded.items.filter(
268
- (i) => i.type === "nudge" && i.source === "slack",
269
- );
270
- expect(nudges).toHaveLength(1);
271
- expect(nudges[0]!.author).toBe("assistant");
272
- expect(nudges[0]!.title).toBe("Assistant original");
273
- });
274
-
275
- test("action without expiresAt is persisted with no auto-fade", async () => {
276
- // Action items are the feed's activity log — they must persist
277
- // until the user dismisses them. The writer used to fill in a
278
- // 24h default expiresAt; that behavior is intentionally gone.
279
- await appendFeedItem(
280
- makeItem({
281
- id: "action-1",
282
- type: "action",
283
- createdAt: "2026-04-14T12:00:00.000Z",
284
- }),
285
- );
286
- const decoded = readFileJson();
287
- expect(decoded.items).toHaveLength(1);
288
- expect(decoded.items[0]!.expiresAt).toBeUndefined();
289
- });
290
-
291
- test("action with an explicit expiresAt is left untouched", async () => {
292
- const explicit = "2026-04-15T00:00:00.000Z";
293
- await appendFeedItem(
294
- makeItem({
295
- id: "action-2",
296
- type: "action",
297
- expiresAt: explicit,
298
- createdAt: "2026-04-14T12:00:00.000Z",
299
- }),
300
- );
301
- const decoded = readFileJson();
302
- expect(decoded.items[0]!.expiresAt).toBe(explicit);
303
- });
304
-
305
- test("action with same id updates the existing entry in place", async () => {
306
- // Deterministic-dedup callers (emit-feed-event.ts dedupKey)
307
- // emit the same id on repeat signals; the writer must refresh
308
- // the existing entry rather than append a duplicate, otherwise
309
- // the same event would show up N times until the per-source
310
- // cap trimmed it.
311
- await appendFeedItem(
312
- makeItem({
313
- id: "emit:gmail:unread-msg-42",
314
- type: "action",
315
- source: "gmail",
316
- title: "Unread from Alice",
317
- createdAt: "2026-04-14T10:00:00.000Z",
318
- }),
319
- );
320
232
  await appendFeedItem(
321
233
  makeItem({
322
- id: "emit:gmail:unread-msg-42",
323
- type: "action",
324
- source: "gmail",
325
- title: "Unread from Alice (refreshed)",
234
+ id: "dup",
235
+ title: "Refreshed title",
326
236
  createdAt: "2026-04-14T12:00:00.000Z",
327
237
  }),
328
238
  );
329
239
 
330
240
  const decoded = readFileJson();
331
- const matching = decoded.items.filter(
332
- (i) => i.id === "emit:gmail:unread-msg-42",
333
- );
241
+ const matching = decoded.items.filter((i) => i.id === "dup");
334
242
  expect(matching).toHaveLength(1);
335
- expect(matching[0]!.title).toBe("Unread from Alice (refreshed)");
243
+ expect(matching[0]!.title).toBe("Refreshed title");
244
+ expect(decoded.items.find((i) => i.id === "other")).toBeDefined();
336
245
  });
337
246
 
338
- test("multiple actions with the same (type, source) all persist", async () => {
339
- // Actions must not collapse onto each other by (type, source) —
340
- // each append is a distinct entry in the activity log.
247
+ test("distinct ids all persist (no implicit dedup beyond same-id)", async () => {
341
248
  await appendFeedItem(
342
249
  makeItem({
343
- id: "action-a",
344
- type: "action",
345
- source: "gmail",
346
- title: "Acted A",
250
+ id: "a",
251
+ title: "First",
347
252
  createdAt: "2026-04-14T10:00:00.000Z",
348
253
  }),
349
254
  );
350
255
  await appendFeedItem(
351
256
  makeItem({
352
- id: "action-b",
353
- type: "action",
354
- source: "gmail",
355
- title: "Acted B",
257
+ id: "b",
258
+ title: "Second",
356
259
  createdAt: "2026-04-14T11:00:00.000Z",
357
260
  }),
358
261
  );
359
262
  await appendFeedItem(
360
263
  makeItem({
361
- id: "action-c",
362
- type: "action",
363
- source: "gmail",
364
- title: "Acted C",
264
+ id: "c",
265
+ title: "Third",
365
266
  createdAt: "2026-04-14T12:00:00.000Z",
366
267
  }),
367
268
  );
368
269
 
369
270
  const decoded = readFileJson();
370
- const gmailActions = decoded.items.filter(
371
- (i) => i.type === "action" && i.source === "gmail",
372
- );
373
- expect(gmailActions).toHaveLength(3);
374
- const ids = new Set(gmailActions.map((i) => i.id));
375
- expect(ids).toEqual(new Set(["action-a", "action-b", "action-c"]));
271
+ expect(decoded.items).toHaveLength(3);
272
+ const ids = new Set(decoded.items.map((i) => i.id));
273
+ expect(ids).toEqual(new Set(["a", "b", "c"]));
376
274
  });
377
275
 
378
- test("per-source action cap keeps only the N most recent per source", async () => {
379
- // Append MAX+5 actions for gmail, interleaved with a handful of
380
- // slack actions and a digest. Cap must apply only to the
381
- // overflowing source.
382
- const overflow = MAX_ACTIONS_PER_SOURCE + 5;
383
- for (let i = 0; i < overflow; i++) {
384
- await appendFeedItem(
385
- makeItem({
386
- id: `gmail-${i}`,
387
- type: "action",
388
- source: "gmail",
389
- title: `Gmail action ${i}`,
390
- createdAt: new Date(
391
- Date.parse("2026-04-14T00:00:00.000Z") + i * 60_000,
392
- ).toISOString(),
393
- }),
394
- );
395
- }
276
+ test("item without expiresAt is persisted as-is (no auto-fade)", async () => {
396
277
  await appendFeedItem(
397
278
  makeItem({
398
- id: "slack-1",
399
- type: "action",
400
- source: "slack",
401
- title: "Slack action",
279
+ id: "no-expiry",
402
280
  createdAt: "2026-04-14T12:00:00.000Z",
403
281
  }),
404
282
  );
405
- await appendFeedItem(
406
- makeItem({
407
- id: "digest-1",
408
- type: "digest",
409
- source: "gmail",
410
- title: "Gmail digest",
411
- createdAt: "2026-04-14T12:01:00.000Z",
412
- }),
413
- );
414
-
415
283
  const decoded = readFileJson();
416
- const gmailActions = decoded.items.filter(
417
- (i) => i.type === "action" && i.source === "gmail",
418
- );
419
- expect(gmailActions).toHaveLength(MAX_ACTIONS_PER_SOURCE);
420
-
421
- // The kept ids are the MAX most recent by createdAt — i.e. the
422
- // final MAX entries of the 0..overflow-1 sequence.
423
- const keptIds = new Set(gmailActions.map((i) => i.id));
424
- for (let i = overflow - MAX_ACTIONS_PER_SOURCE; i < overflow; i++) {
425
- expect(keptIds.has(`gmail-${i}`)).toBe(true);
426
- }
427
- for (let i = 0; i < overflow - MAX_ACTIONS_PER_SOURCE; i++) {
428
- expect(keptIds.has(`gmail-${i}`)).toBe(false);
429
- }
430
-
431
- // Slack is under the cap and the digest is a different type —
432
- // both untouched by the prune.
433
- expect(decoded.items.filter((i) => i.id === "slack-1")).toHaveLength(1);
434
- expect(decoded.items.filter((i) => i.type === "digest")).toHaveLength(1);
435
- });
436
-
437
- test("action items without a source are not subject to the cap", async () => {
438
- const n = MAX_ACTIONS_PER_SOURCE + 3;
439
- for (let i = 0; i < n; i++) {
440
- await appendFeedItem(
441
- makeItem({
442
- id: `sourceless-${i}`,
443
- type: "action",
444
- title: `Sourceless ${i}`,
445
- createdAt: new Date(
446
- Date.parse("2026-04-14T00:00:00.000Z") + i * 60_000,
447
- ).toISOString(),
448
- }),
449
- );
450
- }
451
- const decoded = readFileJson();
452
- const sourceless = decoded.items.filter(
453
- (i) => i.type === "action" && i.source === undefined,
454
- );
455
- expect(sourceless).toHaveLength(n);
284
+ expect(decoded.items).toHaveLength(1);
285
+ expect(decoded.items[0]!.expiresAt).toBeUndefined();
456
286
  });
457
287
 
458
- test("thread updates replace the existing thread with the same id in place", async () => {
459
- await appendFeedItem(
460
- makeItem({
461
- id: "thread-A",
462
- type: "thread",
463
- title: "Thread v1",
464
- priority: 80,
465
- createdAt: "2026-04-14T12:00:00.000Z",
466
- }),
467
- );
468
- await appendFeedItem(
469
- makeItem({
470
- id: "thread-B",
471
- type: "thread",
472
- title: "Other thread",
473
- priority: 60,
474
- createdAt: "2026-04-14T11:00:00.000Z",
475
- }),
476
- );
288
+ test("explicit expiresAt is left untouched", async () => {
289
+ const explicit = "2026-04-15T00:00:00.000Z";
477
290
  await appendFeedItem(
478
291
  makeItem({
479
- id: "thread-A",
480
- type: "thread",
481
- title: "Thread v2 updated",
482
- priority: 80,
292
+ id: "with-expiry",
293
+ expiresAt: explicit,
483
294
  createdAt: "2026-04-14T12:00:00.000Z",
484
295
  }),
485
296
  );
486
-
487
297
  const decoded = readFileJson();
488
- expect(decoded.items).toHaveLength(2);
489
- const threadA = decoded.items.find((i) => i.id === "thread-A");
490
- expect(threadA?.title).toBe("Thread v2 updated");
298
+ expect(decoded.items[0]!.expiresAt).toBe(explicit);
491
299
  });
492
300
 
493
301
  test("items sort by priority desc then createdAt desc", async () => {
@@ -527,7 +335,6 @@ describe("feed-writer", () => {
527
335
  await appendFeedItem(
528
336
  makeItem({
529
337
  id: "item-1",
530
- type: "nudge",
531
338
  title: "Original",
532
339
  }),
533
340
  );
@@ -545,7 +352,7 @@ describe("feed-writer", () => {
545
352
  });
546
353
 
547
354
  test("returns null for an unknown id", async () => {
548
- await appendFeedItem(makeItem({ id: "known", type: "nudge" }));
355
+ await appendFeedItem(makeItem({ id: "known" }));
549
356
  const result = await patchFeedItemStatus("unknown", "seen");
550
357
  expect(result).toBeNull();
551
358
  });
@@ -556,7 +363,6 @@ describe("feed-writer", () => {
556
363
  await appendFeedItem(
557
364
  makeItem({
558
365
  id: "fail-item",
559
- type: "nudge",
560
366
  title: "Pre-fail title",
561
367
  }),
562
368
  );
@@ -594,13 +400,10 @@ describe("feed-writer", () => {
594
400
  });
595
401
 
596
402
  describe("concurrency", () => {
597
- test("10 concurrent appends of items with distinct (type,source) pairs all land", async () => {
403
+ test("10 concurrent appends with distinct ids all land", async () => {
598
404
  const items = Array.from({ length: 10 }, (_, i) =>
599
405
  makeItem({
600
406
  id: `distinct-${i}`,
601
- type: "nudge",
602
- // No source → no (type,source) dedupe at all; every item
603
- // lands as-is. This is the purest concurrent-append test.
604
407
  title: `Item ${i}`,
605
408
  createdAt: new Date(
606
409
  Date.parse("2026-04-14T12:00:00.000Z") + i * 1000,
@@ -624,14 +427,12 @@ describe("feed-writer", () => {
624
427
  await appendFeedItem(
625
428
  makeItem({
626
429
  id: "new-1",
627
- type: "nudge",
628
430
  status: "new",
629
431
  }),
630
432
  );
631
433
  await appendFeedItem(
632
434
  makeItem({
633
435
  id: "new-2",
634
- type: "nudge",
635
436
  status: "new",
636
437
  createdAt: "2026-04-14T12:00:01.000Z",
637
438
  }),
@@ -639,7 +440,6 @@ describe("feed-writer", () => {
639
440
  await appendFeedItem(
640
441
  makeItem({
641
442
  id: "seen-1",
642
- type: "nudge",
643
443
  status: "seen",
644
444
  createdAt: "2026-04-14T12:00:02.000Z",
645
445
  }),
@@ -664,7 +464,6 @@ describe("feed-writer", () => {
664
464
  await appendFeedItem(
665
465
  makeItem({
666
466
  id: "x",
667
- type: "nudge",
668
467
  status: "new",
669
468
  }),
670
469
  );
@@ -44,7 +44,7 @@ afterEach(() => {
44
44
  // ─── Tests ─────────────────────────────────────────────────────────────
45
45
 
46
46
  describe("emitPostConnectNudge", () => {
47
- test("emits a nudge feed item for google", async () => {
47
+ test("emits a notification feed item for google", async () => {
48
48
  await emitPostConnectNudge("google");
49
49
 
50
50
  const feed = readHomeFeed();
@@ -52,14 +52,12 @@ describe("emitPostConnectNudge", () => {
52
52
 
53
53
  const item = feed.items[0]!;
54
54
  expect(item.id).toBe("connect-nudge:google");
55
- expect(item.type).toBe("nudge");
56
- expect(item.source).toBe("gmail");
55
+ expect(item.type).toBe("notification");
57
56
  expect(item.title).toContain("Gmail connected");
58
57
  expect(item.actions).toHaveLength(2);
59
58
  expect(item.actions![0]!.label).toBe("Triage my inbox");
60
59
  expect(item.actions![1]!.label).toBe("Set up daily digest");
61
60
  expect(item.expiresAt).toBeDefined();
62
- expect(item.author).toBe("platform");
63
61
  });
64
62
 
65
63
  test("no-ops for non-email services", async () => {
@@ -71,20 +69,19 @@ describe("emitPostConnectNudge", () => {
71
69
  expect(feed.items).toHaveLength(0);
72
70
  });
73
71
 
74
- test("reconnecting appends a second nudge (same-author nudges don't deduplicate)", async () => {
72
+ test("reconnecting replaces the existing notification in place (deterministic id)", async () => {
75
73
  await emitPostConnectNudge("google");
76
74
  await emitPostConnectNudge("google");
77
75
 
78
76
  const feed = readHomeFeed();
79
- // Same-author (platform) same-source nudges both persist
80
- // the feed writer's author-resolution only handles cross-author
81
- // replacement. In practice, reconnects are rare and the 7-day
82
- // expiry prevents buildup.
83
- expect(feed.items).toHaveLength(2);
84
- expect(feed.items.every((i) => i.id === "connect-nudge:google")).toBe(true);
77
+ // The deterministic `connect-nudge:<service>` id triggers the v2
78
+ // writer's "same id replaces in place" rule, so reconnecting
79
+ // produces a single feed entry rather than appending a duplicate.
80
+ expect(feed.items).toHaveLength(1);
81
+ expect(feed.items[0]!.id).toBe("connect-nudge:google");
85
82
  });
86
83
 
87
- test("nudge expires after 7 days", async () => {
84
+ test("notification expires after 7 days", async () => {
88
85
  await emitPostConnectNudge("google");
89
86
 
90
87
  const feed = readHomeFeed();