@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
@@ -2,32 +2,18 @@
2
2
  * `assistant memory v2` CLI subgroup.
3
3
  *
4
4
  * Operator-facing subcommands for the v2 memory subsystem (concept-page
5
- * activation model). All commands are thin wrappers over two IPC routes:
6
- *
7
- * - `memory_v2/backfill` — enqueues one of three mutating jobs against the
8
- * memory job queue (`migrate`, `reembed`, `activation-recompute`).
9
- * Returns a `jobId` so the operator can poll status from the regular
10
- * memory subsystem.
11
- * - `memory_v2/validate` — read-only structural validation of the v2
12
- * workspace state. Returns an aggregate report of orphan outgoing-edge
13
- * targets, oversized pages, and parse failures.
5
+ * activation model).
14
6
  *
15
7
  * Subcommands:
16
8
  *
17
- * - `migrate [--force]` — one-shot v1->v2 synthesis. Refuses to run a
18
- * second time unless `--force` is passed (the migration handler writes a
19
- * sentinel after a successful first run).
20
9
  * - `reembed` — fan out an `embed_concept_page` job per page slug to
21
10
  * refresh dense + sparse vectors in Qdrant.
11
+ * - `reembed-skills` — synchronously re-seed v2 skill catalog entries
12
+ * from the current skill set.
22
13
  * - `activation` — refresh persisted activation state for every
23
14
  * conversation that has a stored row.
24
15
  * - `validate` — print a diagnostic report (page count, edge count, and
25
16
  * violation lists). Does not mutate the workspace.
26
- *
27
- * Lives alongside the existing v1 `memory` command rather than replacing it
28
- * so flipping `memory.v2.enabled` back to false fully re-engages the v1
29
- * pipeline. While v2 is on, v1 graph extraction/maintenance and PKB filing
30
- * are suppressed; v1 data stays in place but stops being updated.
31
17
  */
32
18
 
33
19
  import type { Command } from "commander";
@@ -36,13 +22,10 @@ import { cliIpcCall } from "../../ipc/cli-client.js";
36
22
  import type {
37
23
  MemoryV2BackfillOp,
38
24
  MemoryV2BackfillResult,
39
- MemoryV2ExplainSimilarityResult,
40
- MemoryV2ExplainSimilarityStats,
41
- MemoryV2FitAnisotropyResult,
42
- MemoryV2RebuildCorpusStatsResult,
43
25
  MemoryV2ReembedSkillsResult,
44
26
  MemoryV2ValidateResult,
45
27
  } from "../../runtime/routes/memory-v2-routes.js";
28
+ import { registerCommand } from "../lib/register-command.js";
46
29
  import { log } from "../logger.js";
47
30
 
48
31
  // ---------------------------------------------------------------------------
@@ -52,20 +35,12 @@ import { log } from "../logger.js";
52
35
  /**
53
36
  * Issue a backfill IPC call, log the resulting `jobId`, and set a non-zero
54
37
  * exit code on failure. Centralises the error-handling boilerplate for the
55
- * four mutating subcommands.
38
+ * mutating subcommands.
56
39
  */
57
- async function runBackfillOp(
58
- op: MemoryV2BackfillOp,
59
- opts: { force?: boolean } = {},
60
- ): Promise<void> {
61
- // Only forward `force: true` — the route handler already defaults missing
62
- // to false, so omitting the field keeps the queued JSON minimal.
63
- const params: Record<string, unknown> = { op };
64
- if (opts.force === true) params.force = true;
65
-
40
+ async function runBackfillOp(op: MemoryV2BackfillOp): Promise<void> {
66
41
  const result = await cliIpcCall<MemoryV2BackfillResult>(
67
42
  "memory_v2_backfill",
68
- { body: params },
43
+ { body: { op } },
69
44
  );
70
45
 
71
46
  if (!result.ok) {
@@ -77,171 +52,53 @@ async function runBackfillOp(
77
52
  log.info(`Queued ${op} job: ${result.result!.jobId}`);
78
53
  }
79
54
 
80
- /** Format a number for table output. */
81
- function fmt(n: number | null, decimals: number): string {
82
- if (n === null) return "—";
83
- return n.toFixed(decimals);
84
- }
85
-
86
- /** Render the per-channel breakdown table + stats for the explain command. */
87
- function printExplainResult(result: MemoryV2ExplainSimilarityResult): void {
88
- log.info(
89
- `dense_weight=${result.config.dense_weight} sparse_weight=${result.config.sparse_weight}`,
90
- );
91
-
92
- for (const channel of result.channels) {
93
- log.info("");
94
- log.info(`── channel: ${channel.channel} ──`);
95
- log.info(`text: ${channel.textPreview}`);
96
- log.info(
97
- `maxSparse (used for normalization): ${channel.maxSparse.toFixed(4)}`,
98
- );
99
- log.info(
100
- `effective: dw=${channel.effectiveDenseWeight.toFixed(3)} sw=${channel.effectiveSparseWeight.toFixed(3)} (sparseSpread=${channel.sparseSpread.toFixed(3)})`,
101
- );
102
- log.info("");
103
- log.info(
104
- "slug".padEnd(48) +
105
- "dense".padStart(10) +
106
- "sparseRaw".padStart(12) +
107
- "sparseNorm".padStart(12) +
108
- "fused".padStart(10),
109
- );
110
- log.info("─".repeat(92));
111
- for (const row of channel.rows) {
112
- const slugCol =
113
- row.slug.length > 47 ? `${row.slug.slice(0, 46)}…` : row.slug;
114
- log.info(
115
- slugCol.padEnd(48) +
116
- fmt(row.denseScore, 4).padStart(10) +
117
- fmt(row.sparseRaw, 4).padStart(12) +
118
- fmt(row.sparseNorm, 4).padStart(12) +
119
- fmt(row.fused, 4).padStart(10),
120
- );
121
- }
122
- log.info("");
123
- log.info("Stats (per channel):");
124
- log.info(` ${formatStatLine("dense ", channel.stats.dense)}`);
125
- log.info(` ${formatStatLine("sparseRaw ", channel.stats.sparseRaw)}`);
126
- log.info(` ${formatStatLine("sparseNorm ", channel.stats.sparseNorm)}`);
127
- log.info(` ${formatStatLine("fused ", channel.stats.fused)}`);
128
- }
129
- }
130
-
131
- function formatStatLine(
132
- label: string,
133
- stats: MemoryV2ExplainSimilarityStats,
134
- ): string {
135
- if (stats.count === 0) {
136
- return `${label} n=0`;
137
- }
138
- const range = stats.max - stats.min;
139
- return (
140
- `${label} n=${String(stats.count).padStart(3)}` +
141
- ` range=[${stats.min.toFixed(4)}, ${stats.max.toFixed(4)}]` +
142
- ` (Δ=${range.toFixed(4)})` +
143
- ` mean=${stats.mean.toFixed(4)}` +
144
- ` std=${stats.stddev.toFixed(4)}`
145
- );
146
- }
147
-
148
55
  // ---------------------------------------------------------------------------
149
56
  // Registration
150
57
  // ---------------------------------------------------------------------------
151
58
 
152
59
  export function registerMemoryV2Command(program: Command): void {
153
- // Attach the `v2` subgroup to the existing top-level `memory` command so
154
- // operators invoke it as `assistant memory v2 <op>`. The plan deliberately
155
- // namespaces v2 under v1 rather than promoting it to a top-level command,
156
- // so `assistant memory --help` surfaces both eras side-by-side until the
157
- // post-soak cutover removes v1.
158
- const memory = program.commands.find((c) => c.name() === "memory");
159
- if (!memory) {
160
- throw new Error(
161
- "registerMemoryV2Command: parent `memory` command not found. " +
162
- "Call registerMemoryCommand(program) before registerMemoryV2Command(program).",
163
- );
164
- }
165
-
166
- const v2 = memory
167
- .command("v2")
168
- .description("Memory v2 subsystem operations (concept-page model)");
169
-
170
- v2.addHelpText(
171
- "after",
172
- `
173
- The v2 subsystem replaces the v1 graph + PKB with prose concept pages,
174
- directed edges stored in each page's frontmatter, and activation-based
175
- retrieval. v2 is gated behind the memory.v2.enabled config field —
176
- these subcommands remain useful operator tools regardless of whether
177
- v2 is currently active.
178
-
179
- Subcommands fall into three groups:
180
-
181
- Mutating (return a jobId enqueued on the memory job queue):
182
- migrate One-shot v1->v2 synthesis. Refuses to overwrite an
183
- existing v2 state without --force.
184
- reembed Refresh dense + sparse vectors for every concept page.
185
- activation Refresh persisted activation state for every conversation.
186
-
187
- Mutating (synchronous — runs inside the daemon and returns when done):
188
- reembed-skills Re-seed v2 skill entries from the current skill catalog.
189
-
190
- Read-only:
191
- validate Print a diagnostic report of orphan outgoing-edge
192
- targets, oversized pages, and parse failures.
193
-
194
- Calibration:
195
- fit-anisotropy Fit Mu & Viswanath's all-but-the-top correction so
196
- embedding cosines stop clustering in a narrow band.
60
+ // Reuse an existing `memory` parent if some other registrar attached to it
61
+ // first; otherwise create one. This keeps the registration order between
62
+ // sibling memory registrars unconstrained.
63
+ const memory =
64
+ program.commands.find((c) => c.name() === "memory") ??
65
+ program
66
+ .command("memory")
67
+ .description("Manage the v2 memory subsystem (concept-page model)");
68
+
69
+ registerCommand(memory, {
70
+ name: "v2",
71
+ transport: "ipc",
72
+ description: "Memory v2 subsystem operations (concept-page model)",
73
+ build: (v2) => {
74
+ v2.addHelpText(
75
+ "after",
76
+ `
77
+ The v2 memory subsystem stores prose concept pages with directed edges in
78
+ each page's frontmatter and uses activation-based retrieval. Pages live
79
+ under /workspace/memory/concepts/ and are gated behind the
80
+ memory.v2.enabled config field.
81
+
82
+ Mutating subcommands return a jobId enqueued on the memory job queue,
83
+ except reembed-skills which runs synchronously inside the assistant.
84
+ Read-only subcommands print diagnostic reports without mutating state.
197
85
 
198
86
  Examples:
199
87
  $ assistant memory v2 validate
200
- $ assistant memory v2 migrate
201
- $ assistant memory v2 migrate --force
202
88
  $ assistant memory v2 reembed
203
89
  $ assistant memory v2 reembed-skills
204
- $ assistant memory v2 activation
205
- $ assistant memory v2 fit-anisotropy`,
206
- );
90
+ $ assistant memory v2 activation`,
91
+ );
207
92
 
208
- // ── migrate ───────────────────────────────────────────────────────────
209
-
210
- v2.command("migrate")
211
- .description("Run the v1->v2 migration (one-shot synthesis)")
212
- .option(
213
- "-f, --force",
214
- "Re-run the migration even if the v2 sentinel is already present",
215
- )
216
- .addHelpText(
217
- "after",
218
- `
219
- Synthesises v2 concept pages from the v1 graph + PKB, writing each page's
220
- outgoing directed edges directly into its frontmatter. The migration handler
221
- stores a sentinel at memory/.v2-state/.migration-complete-v1-to-v2 after a
222
- successful run and refuses to run again unless --force is passed.
93
+ // ── reembed ───────────────────────────────────────────────────────────
223
94
 
224
- The job runs on the background memory worker — this command returns once
225
- the job is enqueued. Track progress via 'assistant memory status' or the
226
- assistant logs.
227
-
228
- Examples:
229
- $ assistant memory v2 migrate
230
- $ assistant memory v2 migrate --force`,
231
- )
232
- .action(async (opts: { force?: boolean }) => {
233
- await runBackfillOp("migrate", { force: opts.force });
234
- });
235
-
236
- // ── reembed ───────────────────────────────────────────────────────────
237
-
238
- v2.command("reembed")
239
- .description(
240
- "Refresh dense + sparse vectors for every concept page in Qdrant",
241
- )
242
- .addHelpText(
243
- "after",
244
- `
95
+ v2.command("reembed")
96
+ .description(
97
+ "Refresh dense + sparse vectors for every concept page in Qdrant",
98
+ )
99
+ .addHelpText(
100
+ "after",
101
+ `
245
102
  Fans out an embed_concept_page job per concept page slug (plus the four
246
103
  reserved meta-file slugs) so each page's dense and sparse vectors get
247
104
  recomputed against the current embedding backend. Useful after upgrading
@@ -252,20 +109,20 @@ once the parent job is enqueued.
252
109
 
253
110
  Examples:
254
111
  $ assistant memory v2 reembed`,
255
- )
256
- .action(async () => {
257
- await runBackfillOp("reembed");
258
- });
259
-
260
- // ── reembed-skills ────────────────────────────────────────────────────
261
-
262
- v2.command("reembed-skills")
263
- .description(
264
- "Re-seed v2 skill entries from the current skill catalog (synchronous)",
265
- )
266
- .addHelpText(
267
- "after",
268
- `
112
+ )
113
+ .action(async () => {
114
+ await runBackfillOp("reembed");
115
+ });
116
+
117
+ // ── reembed-skills ────────────────────────────────────────────────────
118
+
119
+ v2.command("reembed-skills")
120
+ .description(
121
+ "Re-seed v2 skill entries from the current skill catalog (synchronous)",
122
+ )
123
+ .addHelpText(
124
+ "after",
125
+ `
269
126
  Re-runs the v2 skill catalog seed against the current skill set, replacing
270
127
  both the in-process skill cache and the skill entries in the unified
271
128
  memory_v2_concept_pages Qdrant collection (under the skills/<id> slug
@@ -273,36 +130,36 @@ prefix). Useful after editing a skill's SKILL.md, after a feature-flag flip
273
130
  changes the enabled-skill set, or to recover corrupted skill embeddings.
274
131
 
275
132
  Unlike 'reembed' (concept pages), this runs synchronously inside the
276
- daemon — the command returns only once the seed completes. Requires
133
+ assistant — the command returns only once the seed completes. Requires
277
134
  memory.v2.enabled to be true.
278
135
 
279
136
  Examples:
280
137
  $ assistant memory v2 reembed-skills`,
281
- )
282
- .action(async () => {
283
- const result = await cliIpcCall<MemoryV2ReembedSkillsResult>(
284
- "memory_v2_reembed_skills",
285
- { body: {} },
286
- );
287
-
288
- if (!result.ok) {
289
- log.error(result.error ?? "Failed to re-seed v2 skill entries");
290
- process.exitCode = 1;
291
- return;
292
- }
293
-
294
- log.info("Skill re-seed complete.");
295
- });
296
-
297
- // ── activation ────────────────────────────────────────────────────────
298
-
299
- v2.command("activation")
300
- .description(
301
- "Refresh persisted activation state for every active conversation",
302
- )
303
- .addHelpText(
304
- "after",
305
- `
138
+ )
139
+ .action(async () => {
140
+ const result = await cliIpcCall<MemoryV2ReembedSkillsResult>(
141
+ "memory_v2_reembed_skills",
142
+ { body: {} },
143
+ );
144
+
145
+ if (!result.ok) {
146
+ log.error(result.error ?? "Failed to re-seed v2 skill entries");
147
+ process.exitCode = 1;
148
+ return;
149
+ }
150
+
151
+ log.info("Skill re-seed complete.");
152
+ });
153
+
154
+ // ── activation ────────────────────────────────────────────────────────
155
+
156
+ v2.command("activation")
157
+ .description(
158
+ "Refresh persisted activation state for every active conversation",
159
+ )
160
+ .addHelpText(
161
+ "after",
162
+ `
306
163
  Walks every conversation row in the activation_state table and
307
164
  recomputes the persisted state without rendering or injecting a memory
308
165
  block. Useful after tuning the activation params (d, c_user, c_assistant,
@@ -314,298 +171,87 @@ the job is enqueued.
314
171
 
315
172
  Examples:
316
173
  $ assistant memory v2 activation`,
317
- )
318
- .action(async () => {
319
- await runBackfillOp("activation-recompute");
320
- });
321
-
322
- // ── explain ───────────────────────────────────────────────────────────
323
-
324
- v2.command("explain")
325
- .description(
326
- "Diagnose dense vs sparse score distributions for a query (read-only)",
327
- )
328
- .requiredOption(
329
- "--text <text>",
330
- "Query text to embed and score against the concept-page collection (the user channel).",
331
- )
332
- .option(
333
- "--assistant-text <text>",
334
- "Optional second query text scored independently as the assistant channel.",
335
- )
336
- .option(
337
- "--now-text <text>",
338
- "Optional third query text scored independently as the now channel.",
339
- )
340
- .option(
341
- "--top <n>",
342
- "Number of top hits to fetch per channel (default 25)",
343
- "25",
344
- )
345
- .addHelpText(
346
- "after",
347
- `
348
- Embeds the supplied text(s), runs the hybrid dense + sparse query against
349
- the v2 concept-page Qdrant collection, and prints per-slug raw dense, raw
350
- sparse, normalized sparse, and fused scores plus per-channel summary
351
- statistics (range, mean, stddev). Use this to identify whether dense
352
- embedding compression (anisotropy) or per-batch sparse normalization is
353
- the dominant cause of score compression at the head of the activation
354
- distribution.
355
-
356
- Read-only: does not mutate Qdrant, the workspace, or the activation log.
357
-
358
- Interpretation:
359
- Dense range < 0.1 AND sparseNorm range > 0.5 → embedding anisotropy
360
- Dense range > 0.2 AND sparseNorm range < 0.1 → sparse max-normalization
361
- Both compressed → both contribute
362
- Both wide → channel mixing is the cause
363
-
364
- Examples:
365
- $ assistant memory v2 explain --text "what's bothering me"
366
- $ assistant memory v2 explain --text "..." --top 50
367
- $ assistant memory v2 explain --text "..." --assistant-text "..." --now-text "..."`,
368
- )
369
- .action(
370
- async (opts: {
371
- text: string;
372
- assistantText?: string;
373
- nowText?: string;
374
- top: string;
375
- }) => {
376
- const top = Number.parseInt(opts.top, 10);
377
- if (!Number.isFinite(top) || top < 1) {
378
- log.error("--top must be a positive integer");
379
- process.exitCode = 1;
380
- return;
381
- }
382
-
383
- const result = await cliIpcCall<MemoryV2ExplainSimilarityResult>(
384
- "memory_v2_explain_similarity",
385
- {
386
- body: {
387
- userText: opts.text,
388
- assistantText: opts.assistantText,
389
- nowText: opts.nowText,
390
- top,
391
- },
392
- },
393
- );
394
-
395
- if (!result.ok) {
396
- log.error(result.error ?? "Failed to run similarity diagnostic");
397
- process.exitCode = 1;
398
- return;
399
- }
400
-
401
- printExplainResult(result.result!);
402
- },
403
- );
404
-
405
- // ── rebuild-corpus-stats ──────────────────────────────────────────────
406
-
407
- v2.command("rebuild-corpus-stats")
408
- .description(
409
- "Rebuild the BM25 corpus stats (DF table + avg doc length) used by the sparse channel",
410
- )
411
- .addHelpText(
412
- "after",
413
- `
414
- Walks every concept page on disk and recomputes the document-frequency
415
- table and average document length used to weight BM25 sparse vectors.
416
- Atomic swap — the previous stats stay live until the new ones are ready.
417
-
418
- Run after bulk content imports, after manually editing many pages, or to
419
- recover from a startup rebuild that errored.
420
-
421
- Note: this only refreshes the in-memory stats used to *construct* new
422
- document-side sparse vectors. Existing sparse vectors stored in Qdrant
423
- are not refreshed by this command — pair with 'assistant memory v2
424
- reembed' if document-side weights need updating.
425
-
426
- Examples:
427
- $ assistant memory v2 rebuild-corpus-stats`,
428
- )
429
- .action(async () => {
430
- const result = await cliIpcCall<MemoryV2RebuildCorpusStatsResult>(
431
- "memory_v2_rebuild_corpus_stats",
432
- { body: {} },
433
- );
434
-
435
- if (!result.ok) {
436
- log.error(result.error ?? "Failed to rebuild corpus stats");
437
- process.exitCode = 1;
438
- return;
439
- }
440
-
441
- const r = result.result!;
442
- log.info(`Rebuilt BM25 corpus stats: ${r.totalDocs} docs.`);
443
- log.info(` avg doc length: ${r.avgDl.toFixed(2)} tokens`);
444
- log.info(` vocabulary buckets: ${r.vocabularyBuckets.toLocaleString()}`);
445
- });
446
-
447
- // ── fit-anisotropy ────────────────────────────────────────────────────
448
-
449
- v2.command("fit-anisotropy")
450
- .description(
451
- "Fit the embedding anisotropy correction (Mu & Viswanath 'all-but-the-top')",
452
- )
453
- .option(
454
- "--k <n>",
455
- "Number of leading principal components to project out (default 1; raise to 2-3 only if PC2/PC3 also explain >5% variance)",
456
- "1",
457
- )
458
- .option(
459
- "--sample <n>",
460
- "Maximum stored dense vectors to pull for the fit (default 5000)",
461
- "5000",
462
- )
463
- .addHelpText(
464
- "after",
465
- `
466
- Modern transformer embeddings (Gemini in particular) are anisotropic — every
467
- vector lives in a narrow cone of the embedding space, which compresses cosine
468
- similarities into a tight band (typically 0.4-0.7) and lets a few dominant
469
- directions drown out semantic signal.
470
-
471
- This command samples stored dense vectors from the concept-page Qdrant
472
- collection, fits a corpus mean + top-k principal components, and persists the
473
- calibration. Subsequent embeds and queries apply the correction automatically:
474
-
475
- vec' = vec - mean
476
- for each pc_i: vec' = vec' - (vec' · pc_i) pc_i
477
- vec' = vec' / ||vec'||
478
-
479
- After fitting, run 'assistant memory v2 reembed' to re-process every stored
480
- concept page through the new calibration. Until then, queries are corrected
481
- but stored vectors are not — the score range stays the same and retrieval may
482
- degrade. The calibration is keyed by (provider, model, dim), so changing
483
- embedding model invalidates it.
484
-
485
- Recommended k:
486
- k=1 safest default. Removes the dominant common direction.
487
- k=2-3 only when explained-variance ratios show PC2/PC3 each above ~5%.
488
- k>3 not justified without a labeled retrieval eval set.
489
-
490
- Examples:
491
- $ assistant memory v2 fit-anisotropy
492
- $ assistant memory v2 fit-anisotropy --k 2
493
- $ assistant memory v2 fit-anisotropy --sample 10000`,
494
- )
495
- .action(async (opts: { k: string; sample: string }) => {
496
- const k = Number.parseInt(opts.k, 10);
497
- const sample = Number.parseInt(opts.sample, 10);
498
- if (!Number.isFinite(k) || k < 1) {
499
- log.error("--k must be a positive integer");
500
- process.exitCode = 1;
501
- return;
502
- }
503
- if (!Number.isFinite(sample) || sample < 1) {
504
- log.error("--sample must be a positive integer");
505
- process.exitCode = 1;
506
- return;
507
- }
508
-
509
- const result = await cliIpcCall<MemoryV2FitAnisotropyResult>(
510
- "memory_v2_fit_anisotropy",
511
- { body: { k, sample } },
512
- );
513
-
514
- if (!result.ok) {
515
- log.error(result.error ?? "Failed to fit anisotropy calibration");
516
- process.exitCode = 1;
517
- return;
518
- }
519
-
520
- const r = result.result!;
521
- log.info(
522
- `Fit anisotropy calibration: ${r.provider}/${r.model} (dim=${r.dim})`,
523
- );
524
- log.info(` samples: ${r.sampleCount}`);
525
- log.info(` total variance: ${r.totalVariance.toFixed(6)}`);
526
- log.info(" explained variance per component:");
527
- for (let i = 0; i < r.componentVariance.length; i++) {
528
- const ratio = (r.explainedVarianceRatio[i] * 100).toFixed(2);
529
- log.info(
530
- ` PC${i + 1}: ${r.componentVariance[i].toFixed(6)} (${ratio}%)`,
531
- );
532
- }
533
- log.info(` written to: ${r.path}`);
534
- log.info("");
535
- log.info(
536
- "Next step: run 'assistant memory v2 reembed' so every stored concept page is re-written under the new calibration. Until then, query-side correction operates on stored vectors that were embedded without it.",
537
- );
538
- });
539
-
540
- // ── validate ──────────────────────────────────────────────────────────
541
-
542
- v2.command("validate")
543
- .description("Print a diagnostic report of v2 workspace state (read-only)")
544
- .addHelpText(
545
- "after",
546
- `
547
- Walks every concept page and aggregates outgoing edges from each page's
548
- frontmatter, returning a diagnostic report of:
549
-
550
- pageCount Number of concept pages successfully parsed.
551
- edgeCount Total number of directed outgoing edges across pages.
552
- missingEdgeEndpoints Outgoing edges whose target slug has no
553
- corresponding concept page (orphan targets).
554
- oversizedPages Pages whose body exceeds memory.v2.max_page_chars
555
- (a soft cap; consolidation will eventually split).
556
- parseFailures Pages whose YAML frontmatter or schema validation
557
- failed during read.
558
-
559
- This is purely diagnostic — the command never mutates the workspace.
174
+ )
175
+ .action(async () => {
176
+ await runBackfillOp("activation-recompute");
177
+ });
178
+
179
+ // ── validate ──────────────────────────────────────────────────────────
180
+
181
+ v2.command("validate")
182
+ .description(
183
+ "Print a diagnostic report of v2 workspace state (read-only)",
184
+ )
185
+ .addHelpText(
186
+ "after",
187
+ `
188
+ Walks the v2 concept-page tree on disk and reports:
189
+ - Page count
190
+ - Edge count (total and unique outgoing targets)
191
+ - Missing outgoing edge targets (orphan edges)
192
+ - Oversized pages (over the per-folder size cap)
193
+ - Parse failures (missing or malformed frontmatter)
194
+
195
+ Read-only does not mutate the workspace. Exits non-zero if any
196
+ violations are reported.
560
197
 
561
198
  Examples:
562
199
  $ assistant memory v2 validate`,
563
- )
564
- .action(async () => {
565
- const result = await cliIpcCall<MemoryV2ValidateResult>(
566
- "memory_v2_validate",
567
- {
568
- body: {},
569
- },
570
- );
571
-
572
- if (!result.ok) {
573
- log.error(result.error ?? "Failed to validate memory v2 state");
574
- process.exitCode = 1;
575
- return;
576
- }
577
-
578
- const report = result.result!;
579
- log.info(`Pages: ${report.pageCount}`);
580
- log.info(`Edges: ${report.edgeCount}`);
581
-
582
- if (report.missingEdgeEndpoints.length === 0) {
583
- log.info("Missing outgoing edge targets: none");
584
- } else {
585
- log.info(
586
- `Missing outgoing edge targets: ${report.missingEdgeEndpoints.length}`,
587
- );
588
- for (const { from, to } of report.missingEdgeEndpoints) {
589
- log.info(` ${from} -> ${to}`);
590
- }
591
- }
592
-
593
- if (report.oversizedPages.length === 0) {
594
- log.info("Oversized pages: none");
595
- } else {
596
- log.info(`Oversized pages: ${report.oversizedPages.length}`);
597
- for (const { slug, chars } of report.oversizedPages) {
598
- log.info(` ${slug} (${chars.toLocaleString()} chars)`);
599
- }
600
- }
601
-
602
- if (report.parseFailures.length === 0) {
603
- log.info("Parse failures: none");
604
- } else {
605
- log.info(`Parse failures: ${report.parseFailures.length}`);
606
- for (const { slug, error } of report.parseFailures) {
607
- log.info(` ${slug}: ${error}`);
608
- }
609
- }
610
- });
200
+ )
201
+ .action(async () => {
202
+ const result = await cliIpcCall<MemoryV2ValidateResult>(
203
+ "memory_v2_validate",
204
+ { body: {} },
205
+ );
206
+
207
+ if (!result.ok) {
208
+ log.error(result.error ?? "Failed to validate memory v2 state");
209
+ process.exitCode = 1;
210
+ return;
211
+ }
212
+
213
+ const report = result.result!;
214
+ log.info(`Pages: ${report.pageCount}`);
215
+ log.info(`Edges: ${report.edgeCount}`);
216
+ log.info(
217
+ `Missing edge endpoints: ${
218
+ report.missingEdgeEndpoints.length === 0
219
+ ? "none"
220
+ : report.missingEdgeEndpoints.length
221
+ }`,
222
+ );
223
+ for (const m of report.missingEdgeEndpoints) {
224
+ log.info(` - ${m.from} → ${m.to}`);
225
+ }
226
+ log.info(
227
+ `Oversized pages: ${
228
+ report.oversizedPages.length === 0
229
+ ? "none"
230
+ : report.oversizedPages.length
231
+ }`,
232
+ );
233
+ for (const p of report.oversizedPages) {
234
+ log.info(` - ${p.slug}: ${p.chars} chars`);
235
+ }
236
+ log.info(
237
+ `Parse failures: ${
238
+ report.parseFailures.length === 0
239
+ ? "none"
240
+ : report.parseFailures.length
241
+ }`,
242
+ );
243
+ for (const p of report.parseFailures) {
244
+ log.info(` - ${p.slug}: ${p.error}`);
245
+ }
246
+
247
+ if (
248
+ report.missingEdgeEndpoints.length > 0 ||
249
+ report.oversizedPages.length > 0 ||
250
+ report.parseFailures.length > 0
251
+ ) {
252
+ process.exitCode = 1;
253
+ }
254
+ });
255
+ },
256
+ });
611
257
  }