@vellumai/assistant 0.7.3 → 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 (778) hide show
  1. package/AGENTS.md +11 -0
  2. package/ARCHITECTURE.md +29 -28
  3. package/Dockerfile +6 -4
  4. package/README.md +2 -2
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  6. package/bun.lock +3 -0
  7. package/docker-entrypoint.sh +16 -0
  8. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  9. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  10. package/eslint.config.mjs +12 -0
  11. package/knip.json +3 -1
  12. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  13. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  14. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  15. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  16. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  17. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  19. package/openapi.yaml +4126 -959
  20. package/package.json +5 -1
  21. package/scripts/generate-openapi.ts +52 -4
  22. package/scripts/sync-llm-catalog.ts +165 -0
  23. package/scripts/sync-web-search-catalog.ts +107 -0
  24. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  25. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  26. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  27. package/src/__tests__/anthropic-provider.test.ts +92 -2
  28. package/src/__tests__/app-control-flow.test.ts +7 -0
  29. package/src/__tests__/approval-cascade.test.ts +8 -16
  30. package/src/__tests__/approval-routes-http.test.ts +6 -0
  31. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  32. package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
  33. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  34. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  35. package/src/__tests__/btw-routes.test.ts +1 -0
  36. package/src/__tests__/call-constants.test.ts +10 -1
  37. package/src/__tests__/call-controller.test.ts +127 -0
  38. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  39. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  40. package/src/__tests__/channel-policy.test.ts +12 -0
  41. package/src/__tests__/checker.test.ts +89 -0
  42. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
  43. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  44. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  45. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  46. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
  48. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  49. package/src/__tests__/config-schema.test.ts +14 -3
  50. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  51. package/src/__tests__/config-set-route.test.ts +198 -0
  52. package/src/__tests__/config-watcher.test.ts +6 -0
  53. package/src/__tests__/contacts-tools.test.ts +51 -199
  54. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  55. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  56. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  57. package/src/__tests__/context-search-fanout.test.ts +20 -157
  58. package/src/__tests__/context-search-memory-source.test.ts +3 -26
  59. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  60. package/src/__tests__/context-search-types.test.ts +7 -2
  61. package/src/__tests__/context-window-manager.test.ts +389 -1
  62. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
  63. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  64. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
  65. package/src/__tests__/conversation-agent-loop.test.ts +3 -3
  66. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  67. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  68. package/src/__tests__/conversation-error.test.ts +38 -0
  69. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  70. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  71. package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
  72. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  74. package/src/__tests__/conversation-process-callsite.test.ts +22 -7
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
  76. package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
  77. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  78. package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
  79. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  80. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  81. package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
  82. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
  83. package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
  84. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
  85. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  86. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  87. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  88. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  89. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  90. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  91. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  92. package/src/__tests__/filing-service.test.ts +25 -22
  93. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  94. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  95. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  96. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
  97. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  98. package/src/__tests__/heartbeat-service.test.ts +50 -233
  99. package/src/__tests__/history-repair.test.ts +89 -0
  100. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  101. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  102. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  103. package/src/__tests__/host-browser-routes.test.ts +325 -33
  104. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  105. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  106. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  107. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  108. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  109. package/src/__tests__/injector-chain.test.ts +24 -16
  110. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  111. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  112. package/src/__tests__/install-skill-routing.test.ts +2 -2
  113. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
  114. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  115. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  116. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  117. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  118. package/src/__tests__/llm-resolver.test.ts +46 -0
  119. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  120. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  121. package/src/__tests__/mcp-cli.test.ts +182 -220
  122. package/src/__tests__/mcp-health-check.test.ts +56 -27
  123. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  124. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  125. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  126. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  127. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  128. package/src/__tests__/oauth-cli.test.ts +38 -1888
  129. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  130. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  131. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  132. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  133. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  134. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  135. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  136. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  137. package/src/__tests__/plugin-types.test.ts +13 -11
  138. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  139. package/src/__tests__/profile-entry-status.test.ts +43 -0
  140. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  141. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  142. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  143. package/src/__tests__/relay-server.test.ts +164 -2
  144. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  145. package/src/__tests__/schedule-retry.test.ts +56 -4
  146. package/src/__tests__/schedule-routes.test.ts +104 -0
  147. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  148. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  149. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  150. package/src/__tests__/scheduler-wake.test.ts +0 -63
  151. package/src/__tests__/secret-allowlist.test.ts +1 -0
  152. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  153. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  154. package/src/__tests__/secret-response-routing.test.ts +7 -5
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  156. package/src/__tests__/server-history-render.test.ts +82 -0
  157. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  158. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  159. package/src/__tests__/skill-include-graph.test.ts +31 -0
  160. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  161. package/src/__tests__/skill-load-tool.test.ts +42 -16
  162. package/src/__tests__/skills.test.ts +39 -0
  163. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  164. package/src/__tests__/suggestion-routes.test.ts +3 -3
  165. package/src/__tests__/sync-message-contract.test.ts +63 -0
  166. package/src/__tests__/task-scheduler.test.ts +88 -23
  167. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  168. package/src/__tests__/tool-executor.test.ts +155 -0
  169. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  170. package/src/__tests__/usage-cli.test.ts +11 -73
  171. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  172. package/src/__tests__/vercel-config.test.ts +168 -0
  173. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  174. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  175. package/src/__tests__/web-search.test.ts +303 -2
  176. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  177. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  178. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
  179. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  180. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  181. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  182. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  183. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  184. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  185. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  186. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  187. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
  188. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  189. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  190. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  191. package/src/acp/resolve-agent.test.ts +25 -0
  192. package/src/acp/resolve-agent.ts +13 -2
  193. package/src/acp/session-manager.ts +14 -0
  194. package/src/agent/loop.ts +11 -0
  195. package/src/approvals/guardian-decision-primitive.ts +0 -13
  196. package/src/approvals/guardian-request-resolvers.ts +19 -102
  197. package/src/calls/call-constants.ts +5 -8
  198. package/src/calls/call-controller.ts +130 -67
  199. package/src/calls/relay-server.ts +42 -1
  200. package/src/calls/relay-setup-router.ts +36 -0
  201. package/src/calls/types.ts +1 -0
  202. package/src/calls/voice-session-bridge.ts +24 -5
  203. package/src/channels/config.ts +14 -1
  204. package/src/channels/types.ts +1 -0
  205. package/src/cli/AGENTS.md +164 -4
  206. package/src/cli/__tests__/notifications.test.ts +54 -0
  207. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  208. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  209. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  210. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  211. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  212. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  213. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  214. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  215. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  216. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  217. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  218. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  219. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  220. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  221. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  222. package/src/cli/commands/__tests__/status.test.ts +249 -0
  223. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  224. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  225. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  226. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  227. package/src/cli/commands/attachment.ts +8 -3
  228. package/src/cli/commands/audit.ts +95 -64
  229. package/src/cli/commands/auth.ts +61 -58
  230. package/src/cli/commands/avatar.ts +276 -390
  231. package/src/cli/commands/backup.ts +409 -505
  232. package/src/cli/commands/bash.ts +9 -5
  233. package/src/cli/commands/browser.ts +28 -9
  234. package/src/cli/commands/cache.ts +9 -4
  235. package/src/cli/commands/changelog.ts +414 -0
  236. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  237. package/src/cli/commands/clients.ts +8 -3
  238. package/src/cli/commands/completions.ts +9 -9
  239. package/src/cli/commands/config.ts +102 -72
  240. package/src/cli/commands/contacts.ts +575 -696
  241. package/src/cli/commands/conversations-defer.ts +17 -69
  242. package/src/cli/commands/conversations-import.ts +90 -253
  243. package/src/cli/commands/conversations.ts +346 -436
  244. package/src/cli/commands/credential-execution.ts +9 -6
  245. package/src/cli/commands/credentials.ts +456 -736
  246. package/src/cli/commands/domain.ts +128 -206
  247. package/src/cli/commands/email.ts +606 -794
  248. package/src/cli/commands/gateway.ts +8 -1
  249. package/src/cli/commands/image-generation.ts +157 -205
  250. package/src/cli/commands/inference-providers.ts +352 -0
  251. package/src/cli/commands/inference-session.ts +415 -0
  252. package/src/cli/commands/inference.ts +87 -65
  253. package/src/cli/commands/keys.ts +8 -3
  254. package/src/cli/commands/mcp.ts +103 -287
  255. package/src/cli/commands/memory-v2.ts +163 -517
  256. package/src/cli/commands/notifications.ts +33 -7
  257. package/src/cli/commands/oauth/apps.ts +292 -261
  258. package/src/cli/commands/oauth/connect.ts +182 -345
  259. package/src/cli/commands/oauth/disconnect.ts +16 -215
  260. package/src/cli/commands/oauth/index.ts +49 -45
  261. package/src/cli/commands/oauth/mode.ts +43 -199
  262. package/src/cli/commands/oauth/ping.ts +17 -125
  263. package/src/cli/commands/oauth/providers.ts +732 -921
  264. package/src/cli/commands/oauth/request.ts +60 -350
  265. package/src/cli/commands/oauth/shared.ts +11 -121
  266. package/src/cli/commands/oauth/status.ts +31 -121
  267. package/src/cli/commands/oauth/token.ts +13 -55
  268. package/src/cli/commands/pending.ts +19 -10
  269. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  270. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  271. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  272. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  273. package/src/cli/commands/platform/connect.ts +16 -80
  274. package/src/cli/commands/platform/disconnect.ts +14 -112
  275. package/src/cli/commands/platform/index.ts +177 -246
  276. package/src/cli/commands/routes.ts +153 -336
  277. package/src/cli/commands/sequence.ts +316 -360
  278. package/src/cli/commands/skills.ts +449 -671
  279. package/src/cli/commands/status.ts +58 -37
  280. package/src/cli/commands/stt.ts +94 -262
  281. package/src/cli/commands/task.ts +14 -40
  282. package/src/cli/commands/trust.ts +8 -3
  283. package/src/cli/commands/tts.ts +162 -167
  284. package/src/cli/commands/ui.ts +35 -42
  285. package/src/cli/commands/usage.ts +188 -126
  286. package/src/cli/commands/watchers.ts +8 -3
  287. package/src/cli/commands/webhooks.ts +99 -193
  288. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  289. package/src/cli/lib/daemon-credential-client.ts +4 -5
  290. package/src/cli/lib/nested-value.ts +44 -0
  291. package/src/cli/lib/open-browser.ts +36 -0
  292. package/src/cli/lib/register-command.ts +19 -0
  293. package/src/cli/lib/time-ago.ts +34 -0
  294. package/src/cli/program.ts +2 -4
  295. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  296. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  297. package/src/cli/utils/conversation-id.ts +30 -0
  298. package/src/cli/utils/parse-duration.ts +41 -0
  299. package/src/config/acp-defaults.test.ts +5 -1
  300. package/src/config/acp-defaults.ts +11 -4
  301. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  302. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  303. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  304. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  305. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  306. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  307. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  308. package/src/config/bundled-tool-registry.ts +0 -2
  309. package/src/config/feature-flag-registry.json +17 -17
  310. package/src/config/llm-resolver.ts +16 -1
  311. package/src/config/loader.ts +148 -33
  312. package/src/config/raw-config-utils.ts +2 -30
  313. package/src/config/schema.ts +4 -0
  314. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  315. package/src/config/schemas/call-site-catalog.ts +29 -7
  316. package/src/config/schemas/llm-request-logs.ts +57 -0
  317. package/src/config/schemas/llm.ts +52 -2
  318. package/src/config/schemas/memory-retrospective.ts +48 -0
  319. package/src/config/schemas/memory-v2.ts +33 -2
  320. package/src/config/schemas/memory.ts +4 -0
  321. package/src/config/schemas/services.ts +15 -12
  322. package/src/config/seed-inference-profiles.ts +195 -134
  323. package/src/contacts/contact-store.ts +0 -61
  324. package/src/context/window-manager.ts +191 -5
  325. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
  326. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  327. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  328. package/src/daemon/approval-generators.ts +23 -29
  329. package/src/daemon/config-watcher.ts +2 -0
  330. package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
  331. package/src/daemon/conversation-agent-loop.ts +140 -107
  332. package/src/daemon/conversation-error.ts +21 -0
  333. package/src/daemon/conversation-lifecycle.ts +68 -13
  334. package/src/daemon/conversation-process.ts +36 -19
  335. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  336. package/src/daemon/conversation-slash.ts +175 -23
  337. package/src/daemon/conversation-store.ts +17 -10
  338. package/src/daemon/conversation-surfaces.ts +92 -26
  339. package/src/daemon/conversation-tool-setup.ts +33 -19
  340. package/src/daemon/conversation.ts +49 -10
  341. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  342. package/src/daemon/guardian-action-generators.ts +7 -22
  343. package/src/daemon/handlers/config-model.ts +8 -126
  344. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  345. package/src/daemon/handlers/config-vercel.ts +3 -1
  346. package/src/daemon/handlers/shared.ts +26 -0
  347. package/src/daemon/handlers/skills.ts +84 -5
  348. package/src/daemon/history-repair.ts +33 -6
  349. package/src/daemon/host-app-control-proxy.ts +44 -19
  350. package/src/daemon/host-bash-proxy.ts +85 -158
  351. package/src/daemon/host-browser-proxy.ts +97 -36
  352. package/src/daemon/host-cu-proxy.ts +1 -1
  353. package/src/daemon/host-file-proxy.ts +1 -1
  354. package/src/daemon/host-proxy-base.ts +13 -1
  355. package/src/daemon/host-proxy-preactivation.ts +25 -1
  356. package/src/daemon/host-transfer-proxy.ts +2 -2
  357. package/src/daemon/identity-helpers.ts +19 -0
  358. package/src/daemon/lifecycle.ts +128 -114
  359. package/src/daemon/meet-host-supervisor.ts +15 -15
  360. package/src/daemon/memory-v2-startup.ts +62 -14
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/bookmarks.ts +18 -0
  363. package/src/daemon/message-types/conversations.ts +12 -9
  364. package/src/daemon/message-types/messages.ts +28 -2
  365. package/src/daemon/message-types/sync.ts +60 -0
  366. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  367. package/src/daemon/pkb-reminder-builder.ts +21 -7
  368. package/src/daemon/process-message.ts +56 -23
  369. package/src/daemon/server.ts +23 -18
  370. package/src/daemon/shutdown-handlers.ts +0 -2
  371. package/src/daemon/tool-setup-types.ts +9 -0
  372. package/src/daemon/tool-side-effects.ts +6 -4
  373. package/src/daemon/wake-target-adapter.ts +11 -0
  374. package/src/documents/document-store.ts +35 -1
  375. package/src/export/transcript-formatter.ts +61 -2
  376. package/src/filing/filing-service.ts +42 -56
  377. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  378. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  379. package/src/heartbeat/heartbeat-service.ts +149 -128
  380. package/src/home/__tests__/feed-types.test.ts +63 -131
  381. package/src/home/__tests__/feed-writer.test.ts +77 -278
  382. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  383. package/src/home/feed-types.ts +19 -73
  384. package/src/home/feed-writer.ts +25 -156
  385. package/src/home/post-connect-feed.ts +1 -3
  386. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  387. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  388. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  389. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  390. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  391. package/src/ipc/assistant-server.ts +148 -42
  392. package/src/ipc/cli-client.ts +370 -50
  393. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  394. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  395. package/src/ipc/skill-routes/events.ts +30 -3
  396. package/src/ipc/skill-server.ts +99 -42
  397. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  398. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  399. package/src/live-voice/live-voice-session-manager.ts +11 -4
  400. package/src/live-voice/live-voice-session.ts +14 -6
  401. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  402. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  403. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  404. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  405. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
  406. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  407. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  408. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  409. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  412. package/src/memory/bookmark-crud.ts +179 -0
  413. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  414. package/src/memory/context-search/agent-protocol.ts +5 -1
  415. package/src/memory/context-search/agent-runner.ts +60 -85
  416. package/src/memory/context-search/limits.ts +1 -4
  417. package/src/memory/context-search/search.ts +23 -113
  418. package/src/memory/context-search/sources/conversations.ts +18 -6
  419. package/src/memory/context-search/sources/memory-v2.ts +40 -31
  420. package/src/memory/context-search/sources/memory.ts +9 -2
  421. package/src/memory/context-search/sources/workspace.ts +13 -10
  422. package/src/memory/context-search/types.ts +1 -1
  423. package/src/memory/conversation-bootstrap.ts +11 -0
  424. package/src/memory/conversation-crud.ts +312 -10
  425. package/src/memory/conversation-queries.ts +9 -5
  426. package/src/memory/conversation-title-service.ts +1 -0
  427. package/src/memory/conversation-types.ts +16 -0
  428. package/src/memory/db-init.ts +14 -0
  429. package/src/memory/embedding-backend.ts +2 -1
  430. package/src/memory/embedding-runtime-manager.ts +1 -2
  431. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
  432. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  433. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  434. package/src/memory/graph/conversation-graph-memory.ts +108 -14
  435. package/src/memory/graph/extraction.ts +4 -0
  436. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  437. package/src/memory/graph/graph-search.test.ts +6 -5
  438. package/src/memory/graph/graph-search.ts +3 -4
  439. package/src/memory/graph/retriever.test.ts +12 -7
  440. package/src/memory/graph/retriever.ts +4 -5
  441. package/src/memory/graph/tool-handlers.ts +20 -11
  442. package/src/memory/graph/tools.ts +48 -9
  443. package/src/memory/indexer.ts +18 -2
  444. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
  445. package/src/memory/jobs/embed-concept-page.ts +261 -89
  446. package/src/memory/jobs-store.ts +51 -1
  447. package/src/memory/jobs-worker.ts +60 -7
  448. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  449. package/src/memory/llm-request-log-source-local.ts +26 -0
  450. package/src/memory/llm-request-log-source.ts +97 -0
  451. package/src/memory/llm-request-log-store.ts +1 -1
  452. package/src/memory/memory-retrospective-constants.ts +13 -0
  453. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  454. package/src/memory/memory-retrospective-job.ts +351 -0
  455. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  456. package/src/memory/memory-retrospective-state.ts +162 -0
  457. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  458. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  459. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  460. package/src/memory/message-content.ts +38 -1
  461. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  462. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  463. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  464. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  465. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  466. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  467. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  468. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  469. package/src/memory/migrations/243-provider-connections.ts +68 -0
  470. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  471. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  472. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  473. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  474. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  475. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  476. package/src/memory/migrations/index.ts +7 -0
  477. package/src/memory/pkb/pkb-search.test.ts +6 -5
  478. package/src/memory/pkb/pkb-search.ts +4 -5
  479. package/src/memory/published-pages-store.ts +16 -0
  480. package/src/memory/qdrant-client.ts +3 -0
  481. package/src/memory/schema/bookmarks.ts +38 -0
  482. package/src/memory/schema/conversations.ts +2 -0
  483. package/src/memory/schema/index.ts +2 -0
  484. package/src/memory/schema/inference.ts +29 -0
  485. package/src/memory/schema/memory-core.ts +9 -0
  486. package/src/memory/search/semantic.ts +5 -9
  487. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  488. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  489. package/src/memory/v2/__tests__/activation.test.ts +46 -9
  490. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  491. package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
  492. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  493. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  494. package/src/memory/v2/__tests__/injection.test.ts +768 -33
  495. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  496. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  497. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  498. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  499. package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
  500. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  501. package/src/memory/v2/__tests__/router.test.ts +516 -0
  502. package/src/memory/v2/__tests__/sim.test.ts +163 -8
  503. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  504. package/src/memory/v2/__tests__/static-context.test.ts +8 -35
  505. package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
  506. package/src/memory/v2/activation-store.ts +34 -5
  507. package/src/memory/v2/activation.ts +40 -27
  508. package/src/memory/v2/backfill-jobs.ts +17 -84
  509. package/src/memory/v2/consolidation-job.ts +92 -86
  510. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  511. package/src/memory/v2/injection.ts +466 -115
  512. package/src/memory/v2/migration.ts +117 -20
  513. package/src/memory/v2/page-index.ts +191 -0
  514. package/src/memory/v2/page-store.ts +42 -0
  515. package/src/memory/v2/prompts/consolidation.ts +14 -7
  516. package/src/memory/v2/prompts/router.ts +192 -0
  517. package/src/memory/v2/qdrant.ts +307 -133
  518. package/src/memory/v2/reranker.ts +14 -7
  519. package/src/memory/v2/router.ts +322 -0
  520. package/src/memory/v2/sim.ts +88 -34
  521. package/src/memory/v2/skill-store.ts +118 -29
  522. package/src/memory/v2/static-context.ts +20 -17
  523. package/src/memory/v2/sweep-job.ts +127 -102
  524. package/src/memory/v2/types.ts +16 -5
  525. package/src/memory/validation.ts +13 -0
  526. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  527. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  528. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  529. package/src/notifications/adapters/platform.ts +171 -0
  530. package/src/notifications/conversation-pairing.ts +2 -2
  531. package/src/notifications/copy-composer.ts +61 -12
  532. package/src/notifications/decision-engine.ts +46 -0
  533. package/src/notifications/destination-resolver.ts +21 -0
  534. package/src/notifications/emit-signal.ts +28 -1
  535. package/src/notifications/home-feed-side-effect.ts +111 -0
  536. package/src/notifications/signal.ts +5 -0
  537. package/src/permissions/checker.ts +12 -0
  538. package/src/permissions/gateway-threshold-reader.ts +116 -8
  539. package/src/permissions/ipc-risk-types.ts +2 -0
  540. package/src/permissions/prompter.ts +86 -96
  541. package/src/permissions/secret-prompter.ts +31 -31
  542. package/src/plugin-api/index.ts +13 -0
  543. package/src/plugin-api/package.json +12 -0
  544. package/src/plugin-api/types.ts +62 -0
  545. package/src/plugins/defaults/injectors.ts +20 -5
  546. package/src/plugins/external-plugin-loader.ts +294 -0
  547. package/src/plugins/types.ts +46 -30
  548. package/src/plugins/user-loader.ts +64 -41
  549. package/src/proactive-artifact/job.test.ts +63 -8
  550. package/src/proactive-artifact/job.ts +20 -2
  551. package/src/proactive-artifact/message-copy.ts +18 -1
  552. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  553. package/src/proactive-artifact/trigger-state.ts +4 -0
  554. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  555. package/src/prompts/system-prompt.ts +22 -1
  556. package/src/prompts/templates/SOUL.md +13 -28
  557. package/src/prompts/update-bulletin-job.ts +61 -73
  558. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  559. package/src/providers/__tests__/inference.test.ts +288 -0
  560. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  561. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  562. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  563. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  564. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  565. package/src/providers/anthropic/client.ts +95 -26
  566. package/src/providers/call-site-routing.ts +94 -16
  567. package/src/providers/connection-resolution.ts +163 -0
  568. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  569. package/src/providers/inference/adapter-factory.ts +173 -0
  570. package/src/providers/inference/auth.ts +112 -0
  571. package/src/providers/inference/backfill.ts +196 -0
  572. package/src/providers/inference/connections.ts +356 -0
  573. package/src/providers/inference/resolve-auth.ts +65 -0
  574. package/src/providers/model-catalog.ts +104 -6
  575. package/src/providers/openai/responses-provider.ts +4 -2
  576. package/src/providers/provider-env-vars.ts +17 -7
  577. package/src/providers/provider-secret-catalog.ts +49 -30
  578. package/src/providers/provider-send-message.ts +41 -20
  579. package/src/providers/registry.ts +143 -159
  580. package/src/providers/retry.ts +18 -10
  581. package/src/providers/search-provider-catalog.ts +121 -0
  582. package/src/runtime/AGENTS.md +18 -5
  583. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  584. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  585. package/src/runtime/actor-trust-resolver.ts +32 -10
  586. package/src/runtime/agent-wake.ts +35 -6
  587. package/src/runtime/assistant-event-hub.ts +3 -85
  588. package/src/runtime/auth/route-policy.ts +304 -8
  589. package/src/runtime/auth/same-actor.ts +2 -0
  590. package/src/runtime/background-job-runner.ts +339 -0
  591. package/src/runtime/btw-sidechain.ts +1 -0
  592. package/src/runtime/channel-approvals.ts +3 -2
  593. package/src/runtime/guardian-reply-router.ts +0 -10
  594. package/src/runtime/http-router.ts +36 -1
  595. package/src/runtime/http-server.ts +31 -5
  596. package/src/runtime/http-types.ts +2 -0
  597. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  598. package/src/runtime/middleware/request-logger.ts +62 -1
  599. package/src/runtime/pending-interactions.ts +19 -15
  600. package/src/runtime/pre-first-message-gate.ts +83 -0
  601. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  602. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  603. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  604. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  605. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  606. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  607. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  608. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  609. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  610. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  611. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  612. package/src/runtime/routes/acp-routes.ts +10 -8
  613. package/src/runtime/routes/app-management-routes.ts +228 -3
  614. package/src/runtime/routes/approval-routes.ts +7 -21
  615. package/src/runtime/routes/audit-routes.ts +43 -0
  616. package/src/runtime/routes/auth-routes.ts +72 -0
  617. package/src/runtime/routes/avatar-routes.ts +273 -20
  618. package/src/runtime/routes/backup-routes.ts +406 -2
  619. package/src/runtime/routes/bookmark-routes.ts +154 -0
  620. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  621. package/src/runtime/routes/consolidation-routes.ts +8 -9
  622. package/src/runtime/routes/contact-routes.ts +0 -160
  623. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  624. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  625. package/src/runtime/routes/conversation-query-routes.ts +373 -82
  626. package/src/runtime/routes/conversation-routes.ts +31 -10
  627. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  628. package/src/runtime/routes/credential-routes.ts +540 -0
  629. package/src/runtime/routes/debug-bash-routes.ts +2 -0
  630. package/src/runtime/routes/debug-routes.ts +2 -2
  631. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  632. package/src/runtime/routes/domain-routes.ts +167 -0
  633. package/src/runtime/routes/email-routes.ts +603 -0
  634. package/src/runtime/routes/errors.ts +2 -2
  635. package/src/runtime/routes/events-routes.ts +192 -0
  636. package/src/runtime/routes/filing-routes.ts +2 -3
  637. package/src/runtime/routes/home-feed-routes.ts +6 -78
  638. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  639. package/src/runtime/routes/host-browser-routes.ts +103 -22
  640. package/src/runtime/routes/http-adapter.ts +2 -0
  641. package/src/runtime/routes/identity-routes.ts +5 -0
  642. package/src/runtime/routes/image-generation-routes.ts +99 -0
  643. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  644. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  645. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  646. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
  647. package/src/runtime/routes/index.ts +36 -0
  648. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  649. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  650. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  651. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  652. package/src/runtime/routes/inference-send-routes.ts +115 -0
  653. package/src/runtime/routes/integrations/twilio.ts +1 -0
  654. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  655. package/src/runtime/routes/memory-item-routes.test.ts +3 -9
  656. package/src/runtime/routes/memory-item-routes.ts +5 -6
  657. package/src/runtime/routes/memory-v2-routes.ts +105 -404
  658. package/src/runtime/routes/notification-routes.ts +2 -0
  659. package/src/runtime/routes/oauth-apps.ts +112 -7
  660. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  661. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  662. package/src/runtime/routes/oauth-providers.ts +298 -8
  663. package/src/runtime/routes/platform-routes.ts +336 -0
  664. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  665. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  666. package/src/runtime/routes/playground/state.ts +2 -1
  667. package/src/runtime/routes/publish-routes.ts +221 -0
  668. package/src/runtime/routes/schedule-routes.ts +82 -0
  669. package/src/runtime/routes/sequence-routes.ts +291 -0
  670. package/src/runtime/routes/settings-routes.ts +2 -10
  671. package/src/runtime/routes/skills-routes.ts +31 -1
  672. package/src/runtime/routes/stt-routes.ts +240 -3
  673. package/src/runtime/routes/surface-action-routes.ts +43 -7
  674. package/src/runtime/routes/tts-routes.ts +67 -0
  675. package/src/runtime/routes/types.ts +32 -0
  676. package/src/runtime/routes/user-routes-cli.ts +243 -0
  677. package/src/runtime/routes/webhook-routes.ts +165 -0
  678. package/src/runtime/sync/resource-sync-events.ts +25 -0
  679. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  680. package/src/runtime/sync/sync-publisher.ts +21 -0
  681. package/src/schedule/scheduler.ts +200 -123
  682. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  683. package/src/security/secret-patterns.ts +3 -0
  684. package/src/sequence/engine.ts +38 -40
  685. package/src/skills/include-graph.ts +35 -13
  686. package/src/subagent/manager.ts +20 -15
  687. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  688. package/src/tools/browser/browser-execution.ts +15 -4
  689. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  690. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  691. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  692. package/src/tools/browser/cdp-client/factory.ts +66 -5
  693. package/src/tools/browser/runtime-check.ts +77 -0
  694. package/src/tools/document/document-tool.ts +20 -0
  695. package/src/tools/executor.ts +18 -2
  696. package/src/tools/memory/register.test.ts +10 -8
  697. package/src/tools/memory/register.ts +9 -1
  698. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  699. package/src/tools/network/web-search.ts +280 -37
  700. package/src/tools/permission-checker.ts +28 -5
  701. package/src/tools/skills/load.ts +24 -20
  702. package/src/tools/subagent/spawn.ts +3 -3
  703. package/src/tools/terminal/shell.ts +44 -0
  704. package/src/tools/tool-name-aliases.ts +19 -0
  705. package/src/tools/types.ts +19 -1
  706. package/src/usage/attribution.ts +3 -2
  707. package/src/util/pricing.ts +86 -160
  708. package/src/watcher/__tests__/engine.test.ts +301 -0
  709. package/src/watcher/constants.ts +7 -0
  710. package/src/watcher/engine.ts +90 -90
  711. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  712. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  713. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  714. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
  715. package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
  716. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  717. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  718. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  719. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  720. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  721. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  722. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  723. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  724. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  725. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  726. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  727. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  728. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  729. package/src/workspace/migrations/registry.ts +28 -0
  730. package/src/workspace/migrations/runner.ts +13 -2
  731. package/src/workspace/migrations/types.ts +13 -3
  732. package/src/workspace/provider-commit-message-generator.ts +3 -2
  733. package/src/__tests__/context-search-pkb-source.test.ts +0 -492
  734. package/src/__tests__/credentials-cli.test.ts +0 -1225
  735. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  736. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  737. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  738. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  739. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  740. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  741. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  742. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  743. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  744. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  745. package/src/cli/commands/autonomy.ts +0 -365
  746. package/src/cli/commands/memory.ts +0 -424
  747. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
  748. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  749. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  750. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  751. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  752. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  753. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  754. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  755. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  756. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  757. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  758. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  759. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  760. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  761. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  762. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  763. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  764. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  765. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  766. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  767. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  768. package/src/home/assistant-feed-authoring.ts +0 -135
  769. package/src/home/emit-feed-event.ts +0 -169
  770. package/src/home/feed-scheduler.ts +0 -281
  771. package/src/home/platform-gmail-digest.ts +0 -163
  772. package/src/home/rewrite-command-preview.ts +0 -66
  773. package/src/home/rewrite-feed-title.ts +0 -58
  774. package/src/home/rollup-producer.ts +0 -426
  775. package/src/memory/admin.ts +0 -326
  776. package/src/memory/context-search/sources/pkb.ts +0 -477
  777. package/src/memory/graph/compaction.ts +0 -299
  778. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -0,0 +1,268 @@
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ readFileSync,
5
+ rmSync,
6
+ writeFileSync,
7
+ } from "node:fs";
8
+ import { tmpdir } from "node:os";
9
+ import { join } from "node:path";
10
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
11
+
12
+ import { backfillManagedProfileLabelsMigration } from "../workspace/migrations/082-backfill-managed-profile-labels.js";
13
+
14
+ let workspaceDir: string;
15
+
16
+ function freshWorkspace(): void {
17
+ workspaceDir = join(
18
+ tmpdir(),
19
+ `vellum-migration-082-test-${Date.now()}-${Math.random().toString(36).slice(2)}`,
20
+ );
21
+ mkdirSync(workspaceDir, { recursive: true });
22
+ }
23
+
24
+ function writeConfig(data: Record<string, unknown>): void {
25
+ writeFileSync(
26
+ join(workspaceDir, "config.json"),
27
+ JSON.stringify(data, null, 2) + "\n",
28
+ );
29
+ }
30
+
31
+ function readConfig(): Record<string, unknown> {
32
+ return JSON.parse(readFileSync(join(workspaceDir, "config.json"), "utf-8"));
33
+ }
34
+
35
+ beforeEach(() => {
36
+ freshWorkspace();
37
+ });
38
+
39
+ afterEach(() => {
40
+ if (existsSync(workspaceDir)) {
41
+ rmSync(workspaceDir, { recursive: true, force: true });
42
+ }
43
+ });
44
+
45
+ describe("082-backfill-managed-profile-labels migration", () => {
46
+ test("has correct migration id", () => {
47
+ expect(backfillManagedProfileLabelsMigration.id).toBe(
48
+ "082-backfill-managed-profile-labels",
49
+ );
50
+ });
51
+
52
+ test("backfills missing labels on the canonical managed triplet (Marina QA #5)", () => {
53
+ // The exact shape migration 052 writes — provider + model + numeric
54
+ // tuning fields, no label, no source, no provider_connection.
55
+ writeConfig({
56
+ llm: {
57
+ default: { provider: "anthropic", model: "claude-opus-4-7" },
58
+ profiles: {
59
+ balanced: {
60
+ provider: "anthropic",
61
+ model: "claude-sonnet-4-6",
62
+ maxTokens: 16000,
63
+ effort: "high",
64
+ thinking: { enabled: true, streamThinking: true },
65
+ },
66
+ "quality-optimized": {
67
+ provider: "anthropic",
68
+ model: "claude-opus-4-7",
69
+ maxTokens: 32000,
70
+ effort: "max",
71
+ thinking: { enabled: true, streamThinking: true },
72
+ },
73
+ "cost-optimized": {
74
+ provider: "anthropic",
75
+ model: "claude-haiku-4-5-20251001",
76
+ maxTokens: 8192,
77
+ effort: "low",
78
+ thinking: { enabled: false, streamThinking: false },
79
+ },
80
+ },
81
+ activeProfile: "balanced",
82
+ },
83
+ });
84
+
85
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
86
+
87
+ const config = readConfig();
88
+ const profiles = (config.llm as Record<string, unknown>).profiles as Record<
89
+ string,
90
+ Record<string, unknown>
91
+ >;
92
+ expect(profiles.balanced.label).toBe("Balanced");
93
+ expect(profiles["quality-optimized"].label).toBe("Quality");
94
+ expect(profiles["cost-optimized"].label).toBe("Speed");
95
+ });
96
+
97
+ test("preserves user-set string labels without rewriting", () => {
98
+ writeConfig({
99
+ llm: {
100
+ profiles: {
101
+ balanced: {
102
+ provider: "anthropic",
103
+ model: "claude-sonnet-4-6",
104
+ label: "My Balanced",
105
+ },
106
+ "quality-optimized": {
107
+ provider: "anthropic",
108
+ model: "claude-opus-4-7",
109
+ // No label — backfills.
110
+ },
111
+ "cost-optimized": {
112
+ provider: "anthropic",
113
+ model: "claude-haiku-4-5-20251001",
114
+ label: "Speed (Managed)",
115
+ },
116
+ },
117
+ },
118
+ });
119
+
120
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
121
+
122
+ const config = readConfig();
123
+ const profiles = (config.llm as Record<string, unknown>).profiles as Record<
124
+ string,
125
+ Record<string, unknown>
126
+ >;
127
+ expect(profiles.balanced.label).toBe("My Balanced");
128
+ expect(profiles["quality-optimized"].label).toBe("Quality");
129
+ expect(profiles["cost-optimized"].label).toBe("Speed (Managed)");
130
+ });
131
+
132
+ test("preserves explicit null labels (user cleared the label)", () => {
133
+ // `null` is a meaningful signal — the user cleared the label via the
134
+ // PUT route. Treat the key as present and skip backfill.
135
+ writeConfig({
136
+ llm: {
137
+ profiles: {
138
+ balanced: {
139
+ provider: "anthropic",
140
+ model: "claude-sonnet-4-6",
141
+ label: null,
142
+ },
143
+ },
144
+ },
145
+ });
146
+
147
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
148
+
149
+ const config = readConfig();
150
+ const profiles = (config.llm as Record<string, unknown>).profiles as Record<
151
+ string,
152
+ Record<string, unknown>
153
+ >;
154
+ expect(profiles.balanced.label).toBeNull();
155
+ });
156
+
157
+ test("does NOT touch non-canonical profile names", () => {
158
+ writeConfig({
159
+ llm: {
160
+ profiles: {
161
+ "my-custom": {
162
+ provider: "openai",
163
+ model: "gpt-5.4",
164
+ // No label — must NOT be backfilled.
165
+ },
166
+ balanced: {
167
+ provider: "anthropic",
168
+ model: "claude-sonnet-4-6",
169
+ // Missing label — gets backfilled.
170
+ },
171
+ },
172
+ },
173
+ });
174
+
175
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
176
+
177
+ const config = readConfig();
178
+ const profiles = (config.llm as Record<string, unknown>).profiles as Record<
179
+ string,
180
+ Record<string, unknown>
181
+ >;
182
+ expect("label" in profiles["my-custom"]).toBe(false);
183
+ expect(profiles.balanced.label).toBe("Balanced");
184
+ });
185
+
186
+ test("is idempotent — second run produces no further changes", () => {
187
+ writeConfig({
188
+ llm: {
189
+ profiles: {
190
+ balanced: {
191
+ provider: "anthropic",
192
+ model: "claude-sonnet-4-6",
193
+ },
194
+ },
195
+ },
196
+ });
197
+
198
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
199
+ const afterFirst = readFileSync(
200
+ join(workspaceDir, "config.json"),
201
+ "utf-8",
202
+ );
203
+
204
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
205
+ const afterSecond = readFileSync(
206
+ join(workspaceDir, "config.json"),
207
+ "utf-8",
208
+ );
209
+
210
+ expect(afterSecond).toBe(afterFirst);
211
+ });
212
+
213
+ test("no-op when config.json does not exist", () => {
214
+ // Fresh workspace, no config file. Migration must not throw or create
215
+ // the file.
216
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
217
+ expect(existsSync(join(workspaceDir, "config.json"))).toBe(false);
218
+ });
219
+
220
+ test("no-op when llm.profiles is absent", () => {
221
+ writeConfig({ llm: { default: { provider: "anthropic" } } });
222
+ const before = readFileSync(join(workspaceDir, "config.json"), "utf-8");
223
+
224
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
225
+
226
+ const after = readFileSync(join(workspaceDir, "config.json"), "utf-8");
227
+ expect(after).toBe(before);
228
+ });
229
+
230
+ test("ignores malformed config.json without throwing", () => {
231
+ writeFileSync(join(workspaceDir, "config.json"), "{ not valid json");
232
+ // Should not throw.
233
+ expect(() =>
234
+ backfillManagedProfileLabelsMigration.run(workspaceDir),
235
+ ).not.toThrow();
236
+ });
237
+
238
+ test("does NOT skip when VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH is set", () => {
239
+ // Unlike the seed migrations (040/046/052/054/...), this is a forward
240
+ // data repair that runs regardless. Platform-supplied overlay labels
241
+ // already win at the profile level (the on-disk entry has a `label`
242
+ // key, so this migration leaves it alone). Skipping the whole
243
+ // migration when the env var is set would leave migration-052 holes
244
+ // unhealed on platform-style hatches.
245
+ process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH = "/tmp/overlay.json";
246
+ writeConfig({
247
+ llm: {
248
+ profiles: {
249
+ balanced: {
250
+ provider: "anthropic",
251
+ model: "claude-sonnet-4-6",
252
+ },
253
+ },
254
+ },
255
+ });
256
+
257
+ try {
258
+ backfillManagedProfileLabelsMigration.run(workspaceDir);
259
+
260
+ const config = readConfig();
261
+ const profiles = (config.llm as Record<string, unknown>)
262
+ .profiles as Record<string, Record<string, unknown>>;
263
+ expect(profiles.balanced.label).toBe("Balanced");
264
+ } finally {
265
+ delete process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH;
266
+ }
267
+ });
268
+ });
@@ -12,7 +12,6 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
12
12
  import { releaseNotesSafeStorageLimitsMigration } from "../workspace/migrations/067-release-notes-safe-storage-limits.js";
13
13
 
14
14
  const MIGRATION_ID = "067-release-notes-safe-storage-limits";
15
- const MARKER = `<!-- release-note-id:${MIGRATION_ID} -->`;
16
15
 
17
16
  let workspaceDir: string;
18
17
 
@@ -28,10 +27,6 @@ function updatesPath(): string {
28
27
  return join(workspaceDir, "UPDATES.md");
29
28
  }
30
29
 
31
- function markerCount(content: string): number {
32
- return content.split(MARKER).length - 1;
33
- }
34
-
35
30
  beforeEach(() => {
36
31
  freshWorkspace();
37
32
  });
@@ -47,44 +42,37 @@ describe("workspace migration 067-release-notes-safe-storage-limits", () => {
47
42
  expect(releaseNotesSafeStorageLimitsMigration.id).toBe(MIGRATION_ID);
48
43
  });
49
44
 
50
- test("creates UPDATES.md with marker and key copy when file is absent", () => {
45
+ test("does not create UPDATES.md when file is absent", () => {
51
46
  expect(existsSync(updatesPath())).toBe(false);
52
47
 
53
48
  releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
54
49
 
55
- const content = readFileSync(updatesPath(), "utf-8");
56
- expect(content).toContain(MARKER);
57
- expect(content).toContain("safe-storage-limits");
58
- expect(content).toContain("critical 95% threshold");
59
- expect(content).toContain("trusted-contact messages");
50
+ expect(existsSync(updatesPath())).toBe(false);
60
51
  });
61
52
 
62
- test("is idempotent when run twice", () => {
63
- releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
53
+ test("leaves existing UPDATES.md byte-identical", () => {
54
+ const existing = "## Prior\n\nExisting release note.\n";
55
+ writeFileSync(updatesPath(), existing, "utf-8");
56
+
64
57
  releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
65
58
 
66
- const content = readFileSync(updatesPath(), "utf-8");
67
- expect(markerCount(content)).toBe(1);
68
- expect(content.match(/Safe storage limits/g)?.length).toBe(1);
59
+ expect(readFileSync(updatesPath(), "utf-8")).toBe(existing);
69
60
  });
70
61
 
71
- test("appends to existing UPDATES.md when marker is absent", () => {
72
- const prior = "## Prior\n\nExisting release note.\n";
73
- writeFileSync(updatesPath(), prior, "utf-8");
74
-
62
+ test("is idempotent when run twice in an empty workspace", () => {
63
+ releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
75
64
  releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
76
65
 
77
- const content = readFileSync(updatesPath(), "utf-8");
78
- expect(content.startsWith(prior)).toBe(true);
79
- expect(content).toContain(MARKER);
66
+ expect(existsSync(updatesPath())).toBe(false);
80
67
  });
81
68
 
82
- test("is a no-op when marker is already present", () => {
83
- const seeded = `## Prior\n\n${MARKER}\nAlready announced.\n`;
84
- writeFileSync(updatesPath(), seeded, "utf-8");
69
+ test("is idempotent when run twice with existing UPDATES.md", () => {
70
+ const existing = "## Prior\n\nExisting release note.\n";
71
+ writeFileSync(updatesPath(), existing, "utf-8");
85
72
 
73
+ releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
86
74
  releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
87
75
 
88
- expect(readFileSync(updatesPath(), "utf-8")).toBe(seeded);
76
+ expect(readFileSync(updatesPath(), "utf-8")).toBe(existing);
89
77
  });
90
78
  });
@@ -127,9 +127,9 @@ describe("038-unify-llm-callsite-configs migration", () => {
127
127
  // if llm.default exists`) then silently skipped, and migration 039
128
128
  // stripped `services.inference.{provider,model}` — losing the user's
129
129
  // actual configuration. The fix prefers legacy source keys over the
130
- // injected schema defaults whenever both are present. (The loader
131
- // no longer writes defaults to disk, but workspaces still on disk
132
- // from that era can carry the bad state forward.)
130
+ // injected schema defaults whenever both are present. (Defaults are
131
+ // applied in-memory only; legacy workspaces may still carry the
132
+ // on-disk state from that era.)
133
133
  writeConfig({
134
134
  services: {
135
135
  inference: {
@@ -0,0 +1,115 @@
1
+ import { readdirSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { describe, expect, test } from "bun:test";
4
+
5
+ type Registry = {
6
+ flags: Array<{
7
+ key: string;
8
+ scope: string;
9
+ defaultEnabled: boolean;
10
+ }>;
11
+ };
12
+
13
+ const LEGACY_FLAGGED_RELEASE_NOTE_ALLOWLIST = new Map<string, string>([
14
+ [
15
+ "045-release-notes-meet-avatar.ts",
16
+ "Historical bulletin that already shipped before this guard existed.",
17
+ ],
18
+ ]);
19
+
20
+ const FLAGGED_FEATURE_LANGUAGE_PATTERNS: Array<{
21
+ label: string;
22
+ pattern: RegExp;
23
+ }> = [
24
+ { label: "feature flag", pattern: /\bfeature[- ]flag(?:ged)?\b/i },
25
+ { label: "rollout flag", pattern: /\brollout flag\b/i },
26
+ { label: "behind ... flag", pattern: /\bbehind\b[^\n.]{0,120}\bflag\b/i },
27
+ { label: "gated on", pattern: /\bgated on\b/i },
28
+ { label: "when enabled", pattern: /\bwhen enabled\b/i },
29
+ ];
30
+
31
+ function getRepoRoot(): string {
32
+ return join(process.cwd(), "..");
33
+ }
34
+
35
+ function getReleaseNoteMigrationFiles(): string[] {
36
+ const migrationsDir = join(process.cwd(), "src", "workspace", "migrations");
37
+ return readdirSync(migrationsDir)
38
+ .filter((fileName) => /^\d+-release-notes-[a-z0-9-]+\.ts$/.test(fileName))
39
+ .sort();
40
+ }
41
+
42
+ function loadDefaultDisabledAssistantFlagKeys(): string[] {
43
+ const registryPath = join(
44
+ getRepoRoot(),
45
+ "meta",
46
+ "feature-flags",
47
+ "feature-flag-registry.json",
48
+ );
49
+ const registry = JSON.parse(readFileSync(registryPath, "utf-8")) as Registry;
50
+ return registry.flags
51
+ .filter((flag) => flag.scope === "assistant" && !flag.defaultEnabled)
52
+ .map((flag) => flag.key)
53
+ .sort();
54
+ }
55
+
56
+ function escapeRegExp(value: string): string {
57
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
58
+ }
59
+
60
+ function featureFlagKeyPattern(key: string): RegExp {
61
+ const escaped = escapeRegExp(key);
62
+ if (key.includes("-")) {
63
+ return new RegExp(`(?:^|[^a-z0-9-])${escaped}(?:$|[^a-z0-9-])`, "i");
64
+ }
65
+
66
+ return new RegExp("[`'\"]" + escaped + "[`'\"]", "i");
67
+ }
68
+
69
+ describe("workspace release-note migrations feature flag guard", () => {
70
+ test("new release-note migrations do not announce default-disabled feature-flagged work", () => {
71
+ const migrationsDir = join(process.cwd(), "src", "workspace", "migrations");
72
+ const defaultDisabledFlagKeys = loadDefaultDisabledAssistantFlagKeys();
73
+ const violations: string[] = [];
74
+
75
+ for (const fileName of getReleaseNoteMigrationFiles()) {
76
+ if (LEGACY_FLAGGED_RELEASE_NOTE_ALLOWLIST.has(fileName)) {
77
+ continue;
78
+ }
79
+
80
+ const content = readFileSync(join(migrationsDir, fileName), "utf-8");
81
+
82
+ for (const { label, pattern } of FLAGGED_FEATURE_LANGUAGE_PATTERNS) {
83
+ if (pattern.test(content)) {
84
+ violations.push(
85
+ `${fileName}: contains flagged-feature language "${label}"`,
86
+ );
87
+ }
88
+ }
89
+
90
+ for (const key of defaultDisabledFlagKeys) {
91
+ if (featureFlagKeyPattern(key).test(content)) {
92
+ violations.push(
93
+ `${fileName}: references default-disabled assistant feature flag "${key}"`,
94
+ );
95
+ }
96
+ }
97
+ }
98
+
99
+ if (violations.length > 0) {
100
+ const message = [
101
+ "Release-note migrations write to UPDATES.md, which is processed without checking feature flags.",
102
+ "Do not announce features that are still behind default-disabled assistant flags or rollout flags.",
103
+ "Wait until GA and add a new append-only release-note migration with a new marker.",
104
+ "",
105
+ "Violations:",
106
+ ...violations.map((violation) => ` - ${violation}`),
107
+ "",
108
+ "If this is an already-shipped historical bulletin, add a narrow entry to",
109
+ "LEGACY_FLAGGED_RELEASE_NOTE_ALLOWLIST in workspace-release-notes-feature-flag-guard.test.ts.",
110
+ ].join("\n");
111
+
112
+ expect(violations, message).toEqual([]);
113
+ }
114
+ });
115
+ });
@@ -11,7 +11,8 @@
11
11
  * in `afterAll` so the swap doesn't leak into other files.
12
12
  */
13
13
 
14
- type WhichStub = (command: string) => string | null;
14
+ type WhichOptions = { PATH?: string; cwd?: string };
15
+ type WhichStub = (command: string, options?: WhichOptions) => string | null;
15
16
 
16
17
  /**
17
18
  * Installs a process-global stub for Bun.which. Returns helpers to drive and
@@ -30,7 +31,8 @@ export function installWhichStub(): {
30
31
  const originalWhich = Bun.which;
31
32
  let whichStub: WhichStub = () => null;
32
33
 
33
- (Bun as unknown as { which: WhichStub }).which = (cmd) => whichStub(cmd);
34
+ (Bun as unknown as { which: WhichStub }).which = (cmd, options) =>
35
+ whichStub(cmd, options);
34
36
 
35
37
  function setWhich(arg: Record<string, string | null> | WhichStub): void {
36
38
  whichStub = typeof arg === "function" ? arg : (cmd) => arg[cmd] ?? null;
@@ -161,6 +161,31 @@ describe("resolveAcpAgent", () => {
161
161
  expect(result.hint).toBe("npm i -g @zed-industries/codex-acp");
162
162
  });
163
163
 
164
+ test("binary preflight honors agent.env.PATH override (matches spawn env)", () => {
165
+ // The actual spawn merges `agentConfig.env` into the child env, so a
166
+ // per-agent PATH override wins over the daemon's PATH. The preflight
167
+ // must use the same PATH or it will reject configs that would have
168
+ // spawned successfully.
169
+ config.setConfig({
170
+ agents: {
171
+ custom: {
172
+ command: "my-binary",
173
+ args: [],
174
+ env: { PATH: "/opt/custom/bin" },
175
+ },
176
+ },
177
+ });
178
+ which.setWhich((cmd, options) =>
179
+ cmd === "my-binary" && options?.PATH === "/opt/custom/bin"
180
+ ? "/opt/custom/bin/my-binary"
181
+ : null,
182
+ );
183
+
184
+ const result = resolveAcpAgent("custom");
185
+
186
+ expect(result.ok).toBe(true);
187
+ });
188
+
164
189
  test("ok result when user config provides agent and binary is on PATH", () => {
165
190
  config.setConfig({
166
191
  agents: {
@@ -65,6 +65,17 @@ function installHintFor(command: string): string {
65
65
  : `Install '${command}' and ensure it is on PATH.`;
66
66
  }
67
67
 
68
+ /**
69
+ * Resolve the binary using the same PATH the spawn will see. `AcpAgentProcess`
70
+ * spawns with `{ ...process.env, ...config.env }`, so a per-agent `env.PATH`
71
+ * override wins over the daemon's PATH. Mirror that here so a config that
72
+ * relies on a custom PATH to locate the binary doesn't fail preflight.
73
+ */
74
+ function findAgentBinary(agent: AcpAgentConfig): string | null {
75
+ const PATH = agent.env?.PATH ?? process.env.PATH;
76
+ return Bun.which(agent.command, PATH ? { PATH } : undefined);
77
+ }
78
+
68
79
  /**
69
80
  * Resolve an id against user config first, then bundled defaults. Returns the
70
81
  * resolved entry plus a `source` label so callers can surface "user override
@@ -122,7 +133,7 @@ export function resolveAcpAgent(id: string): ResolveAcpAgentResult {
122
133
  }
123
134
 
124
135
  const { agent } = found;
125
- if (!Bun.which(agent.command)) {
136
+ if (!findAgentBinary(agent)) {
126
137
  return {
127
138
  ok: false,
128
139
  reason: "binary_not_found",
@@ -157,7 +168,7 @@ export function listAcpAgents(): {
157
168
  const agents: AcpAgentEntry[] = mergedAgentIds(userAgents).map((id) => {
158
169
  // Non-null: ids come from `mergedAgentIds` so the lookup always resolves.
159
170
  const { agent, source } = lookupAgent(userAgents, id)!;
160
- const available = Bun.which(agent.command) !== null;
171
+ const available = findAgentBinary(agent) !== null;
161
172
  const entry: AcpAgentEntry = {
162
173
  id,
163
174
  command: agent.command,
@@ -278,12 +278,26 @@ export class AcpSessionManager {
278
278
 
279
279
  /**
280
280
  * Kills the agent process and removes the session from tracking.
281
+ *
282
+ * Persists the buffered event log first so abort paths
283
+ * (`executeAcpAbort`, daemon shutdown) don't drop history. If the
284
+ * session is still in a non-terminal state, mark it cancelled so the
285
+ * persisted row reflects reality. The in-flight prompt's then/catch
286
+ * handler will short-circuit after teardown removes the entry.
281
287
  */
282
288
  close(acpSessionId: string): void {
283
289
  const entry = this.sessions.get(acpSessionId);
284
290
  if (!entry) {
285
291
  throw new Error(`ACP session "${acpSessionId}" not found`);
286
292
  }
293
+ if (
294
+ entry.state.status === "running" ||
295
+ entry.state.status === "initializing"
296
+ ) {
297
+ entry.state.status = "cancelled";
298
+ entry.state.completedAt = Date.now();
299
+ }
300
+ this.persistTerminal(acpSessionId, entry);
287
301
  this.teardownSession(acpSessionId, entry);
288
302
  }
289
303
 
package/src/agent/loop.ts CHANGED
@@ -96,6 +96,11 @@ export type AgentEvent =
96
96
  matchedTrustRuleId?: string;
97
97
  isContainerized?: boolean;
98
98
  riskScopeOptions?: Array<{ pattern: string; label: string }>;
99
+ riskAllowlistOptions?: Array<{
100
+ label: string;
101
+ description: string;
102
+ pattern: string;
103
+ }>;
99
104
  riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
100
105
  approvalMode?: string;
101
106
  approvalReason?: string;
@@ -282,6 +287,11 @@ export type LoopToolExecutor = (
282
287
  matchedTrustRuleId?: string;
283
288
  isContainerized?: boolean;
284
289
  riskScopeOptions?: Array<{ pattern: string; label: string }>;
290
+ riskAllowlistOptions?: Array<{
291
+ label: string;
292
+ description: string;
293
+ pattern: string;
294
+ }>;
285
295
  riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
286
296
  approvalMode?: string;
287
297
  approvalReason?: string;
@@ -1001,6 +1011,7 @@ export class AgentLoop {
1001
1011
  matchedTrustRuleId: result.matchedTrustRuleId,
1002
1012
  isContainerized: result.isContainerized,
1003
1013
  riskScopeOptions: result.riskScopeOptions,
1014
+ riskAllowlistOptions: result.riskAllowlistOptions,
1004
1015
  riskDirectoryScopeOptions: result.riskDirectoryScopeOptions,
1005
1016
  approvalMode: result.approvalMode,
1006
1017
  approvalReason: result.approvalReason,
@@ -355,12 +355,6 @@ export type CanonicalDecisionResult =
355
355
  resolverFailed?: boolean;
356
356
  resolverFailureReason?: string;
357
357
  resolverReplyText?: string;
358
- activatedContact?: {
359
- sourceChannel: string;
360
- externalUserId: string;
361
- externalChatId?: string;
362
- displayName?: string;
363
- };
364
358
  }
365
359
  | {
366
360
  applied: false;
@@ -527,9 +521,6 @@ export async function applyCanonicalGuardianDecision(
527
521
  let resolverFailed = false;
528
522
  let resolverFailureReason: string | undefined;
529
523
  let resolverReplyText: string | undefined;
530
- let activatedContact:
531
- | { sourceChannel: string; externalUserId: string; externalChatId?: string; displayName?: string }
532
- | undefined;
533
524
  const resolver = getResolver(request.kind);
534
525
  if (resolver) {
535
526
  const resolverResult = await resolver.resolve({
@@ -558,9 +549,6 @@ export async function applyCanonicalGuardianDecision(
558
549
  resolverFailureReason = resolverResult.reason;
559
550
  } else {
560
551
  resolverReplyText = resolverResult.guardianReplyText;
561
- if (resolverResult.activatedContact) {
562
- activatedContact = resolverResult.activatedContact;
563
- }
564
552
  }
565
553
  } else {
566
554
  log.info(
@@ -612,6 +600,5 @@ export async function applyCanonicalGuardianDecision(
612
600
  grantMinted,
613
601
  ...(resolverFailed ? { resolverFailed, resolverFailureReason } : {}),
614
602
  ...(resolverReplyText ? { resolverReplyText } : {}),
615
- ...(activatedContact ? { activatedContact } : {}),
616
603
  };
617
604
  }