@vellumai/assistant 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -0,0 +1,398 @@
1
+ /**
2
+ * Tests for the shared inference-profile session handler.
3
+ *
4
+ * Covers: setInferenceProfileSession, closeInferenceProfileSession,
5
+ * and listInferenceProfileSessionsWithRemaining.
6
+ */
7
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
8
+
9
+ import { makeMockLogger } from "./helpers/mock-logger.js";
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // Mocks — must be declared before importing the module under test
13
+ // ---------------------------------------------------------------------------
14
+
15
+ mock.module("../util/logger.js", () => ({
16
+ getLogger: () => makeMockLogger(),
17
+ }));
18
+
19
+ // Stub the event hub so tests don't need a running event bus.
20
+ // Exposed as a `mock(...)` so individual tests can assert publish calls.
21
+ const publishMock = mock(async () => {});
22
+ mock.module("../runtime/assistant-event-hub.js", () => ({
23
+ assistantEventHub: { publish: publishMock },
24
+ }));
25
+
26
+ // Stub buildAssistantEvent to be an identity pass-through for the event object
27
+ mock.module("../runtime/assistant-event.js", () => ({
28
+ buildAssistantEvent: (event: unknown) => event,
29
+ }));
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // Config mock — controlled per test so we can inject profiles
33
+ // ---------------------------------------------------------------------------
34
+
35
+ let mockProfiles: Record<string, unknown> = {};
36
+ let mockMaxTtl: number | undefined;
37
+
38
+ mock.module("../config/loader.js", () => ({
39
+ loadConfig: () => ({
40
+ llm: {
41
+ profiles: mockProfiles,
42
+ profileSession: {
43
+ defaultTtlSeconds: 1800,
44
+ maxTtlSeconds: mockMaxTtl ?? 43200,
45
+ },
46
+ },
47
+ }),
48
+ }));
49
+
50
+ // ---------------------------------------------------------------------------
51
+ // Real DB — same pattern as conversation-crud-inference-profile.test.ts
52
+ // ---------------------------------------------------------------------------
53
+
54
+ import { createConversation, getConversation } from "../memory/conversation-crud.js";
55
+ import { getDb } from "../memory/db-connection.js";
56
+ import { initializeDb } from "../memory/db-init.js";
57
+
58
+ initializeDb();
59
+
60
+ import {
61
+ closeInferenceProfileSession,
62
+ listInferenceProfileSessionsWithRemaining,
63
+ setInferenceProfileSession,
64
+ } from "../runtime/routes/inference-profile-session-handler.js";
65
+
66
+ // ---------------------------------------------------------------------------
67
+ // Helpers
68
+ // ---------------------------------------------------------------------------
69
+
70
+ function resetDb() {
71
+ const db = getDb();
72
+ db.run(`DELETE FROM messages`);
73
+ db.run(`DELETE FROM conversations`);
74
+ }
75
+
76
+ // ---------------------------------------------------------------------------
77
+ // Tests
78
+ // ---------------------------------------------------------------------------
79
+
80
+ describe("setInferenceProfileSession", () => {
81
+ beforeEach(() => {
82
+ resetDb();
83
+ mockProfiles = { balanced: {}, "cost-optimized": {} };
84
+ mockMaxTtl = undefined; // reset to default 43200
85
+ publishMock.mockClear();
86
+ });
87
+
88
+ test("open with ttlSeconds=600 — returns UUID sessionId and expiresAt ≈ now + 600_000", async () => {
89
+ const conv = createConversation("sess-handler-ttl-600");
90
+ const before = Date.now();
91
+
92
+ const result = await setInferenceProfileSession({
93
+ conversationId: conv.id,
94
+ profile: "balanced",
95
+ ttlSeconds: 600,
96
+ });
97
+
98
+ expect(result.conversationId).toBe(conv.id);
99
+ expect(result.profile).toBe("balanced");
100
+ expect(typeof result.sessionId).toBe("string");
101
+ expect(result.sessionId).not.toBeNull();
102
+ // UUID pattern
103
+ expect(result.sessionId).toMatch(
104
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,
105
+ );
106
+ expect(result.expiresAt).not.toBeNull();
107
+ expect(result.expiresAt!).toBeGreaterThanOrEqual(before + 600_000);
108
+ expect(result.expiresAt!).toBeLessThanOrEqual(Date.now() + 600_000 + 1000);
109
+ expect(result.ttlSeconds).toBe(600);
110
+ expect(result.replaced).toBeNull();
111
+ });
112
+
113
+ test("open without ttlSeconds — sessionId=null, expiresAt=null (sticky)", async () => {
114
+ const conv = createConversation("sess-handler-no-ttl");
115
+
116
+ const result = await setInferenceProfileSession({
117
+ conversationId: conv.id,
118
+ profile: "balanced",
119
+ // ttlSeconds intentionally absent (undefined)
120
+ });
121
+
122
+ expect(result.profile).toBe("balanced");
123
+ expect(result.sessionId).toBeNull();
124
+ expect(result.expiresAt).toBeNull();
125
+ expect(result.ttlSeconds).toBeUndefined();
126
+ expect(result.replaced).toBeNull();
127
+ });
128
+
129
+ test("open with ttlSeconds=99_999_999 — clamped to maxTtlSeconds (43200)", async () => {
130
+ const conv = createConversation("sess-handler-clamp");
131
+ const before = Date.now();
132
+
133
+ const result = await setInferenceProfileSession({
134
+ conversationId: conv.id,
135
+ profile: "balanced",
136
+ ttlSeconds: 99_999_999,
137
+ });
138
+
139
+ expect(result.ttlSeconds).toBe(43200);
140
+ expect(result.expiresAt).not.toBeNull();
141
+ expect(result.expiresAt!).toBeGreaterThanOrEqual(before + 43200 * 1000);
142
+ expect(result.expiresAt!).toBeLessThanOrEqual(Date.now() + 43200 * 1000 + 1000);
143
+ });
144
+
145
+ test("open over active session — replaced carries prior session info", async () => {
146
+ const conv = createConversation("sess-handler-replace");
147
+
148
+ // Open first session
149
+ const first = await setInferenceProfileSession({
150
+ conversationId: conv.id,
151
+ profile: "balanced",
152
+ ttlSeconds: 300,
153
+ });
154
+
155
+ expect(first.replaced).toBeNull();
156
+
157
+ // Open second session over the first
158
+ const second = await setInferenceProfileSession({
159
+ conversationId: conv.id,
160
+ profile: "cost-optimized",
161
+ ttlSeconds: 600,
162
+ });
163
+
164
+ expect(second.replaced).not.toBeNull();
165
+ expect(second.replaced!.profile).toBe("balanced");
166
+ expect(second.replaced!.sessionId).toBe(first.sessionId);
167
+ expect(second.replaced!.expiresAt).toBe(first.expiresAt);
168
+ });
169
+
170
+ test("open with profile=null — all three cleared; replaced set if prior existed", async () => {
171
+ const conv = createConversation("sess-handler-clear");
172
+
173
+ // Set up an active session first
174
+ const opened = await setInferenceProfileSession({
175
+ conversationId: conv.id,
176
+ profile: "balanced",
177
+ ttlSeconds: 300,
178
+ });
179
+
180
+ // Now clear
181
+ const cleared = await setInferenceProfileSession({
182
+ conversationId: conv.id,
183
+ profile: null,
184
+ });
185
+
186
+ expect(cleared.profile).toBeNull();
187
+ expect(cleared.sessionId).toBeNull();
188
+ expect(cleared.expiresAt).toBeNull();
189
+ expect(cleared.replaced).not.toBeNull();
190
+ expect(cleared.replaced!.profile).toBe("balanced");
191
+ expect(cleared.replaced!.sessionId).toBe(opened.sessionId);
192
+
193
+ // DB should reflect cleared state
194
+ const row = getConversation(conv.id);
195
+ expect(row?.inferenceProfile).toBeNull();
196
+ expect(row?.inferenceProfileSessionId).toBeNull();
197
+ expect(row?.inferenceProfileExpiresAt).toBeNull();
198
+ });
199
+
200
+ test("clear is idempotent — repeated clears on already-empty row do not write or publish", async () => {
201
+ const conv = createConversation("sess-handler-clear-noop");
202
+
203
+ // Sanity: the freshly-created row is fully clear.
204
+ const before = getConversation(conv.id);
205
+ expect(before?.inferenceProfile).toBeNull();
206
+ expect(before?.inferenceProfileSessionId).toBeNull();
207
+ expect(before?.inferenceProfileExpiresAt).toBeNull();
208
+ const updatedAtBefore = before?.updatedAt;
209
+
210
+ publishMock.mockClear();
211
+ const result = await setInferenceProfileSession({
212
+ conversationId: conv.id,
213
+ profile: null,
214
+ });
215
+
216
+ // Returned shape matches a clear, with no replaced session.
217
+ expect(result.profile).toBeNull();
218
+ expect(result.sessionId).toBeNull();
219
+ expect(result.expiresAt).toBeNull();
220
+ expect(result.replaced).toBeNull();
221
+
222
+ // No event was published — this is the load-bearing assertion for the
223
+ // idempotency guard (Codex P2 on PR #29913).
224
+ expect(publishMock).not.toHaveBeenCalled();
225
+
226
+ // No DB write occurred — `updatedAt` is unchanged.
227
+ const after = getConversation(conv.id);
228
+ expect(after?.updatedAt).toBe(updatedAtBefore as number);
229
+ });
230
+
231
+ test("clear after sticky non-session override — still writes and publishes", async () => {
232
+ const conv = createConversation("sess-handler-clear-sticky");
233
+
234
+ // Open a sticky (no-TTL) override — sessionId stays null, expiresAt stays null,
235
+ // but inferenceProfile is set. This is NOT the noop case.
236
+ await setInferenceProfileSession({
237
+ conversationId: conv.id,
238
+ profile: "balanced",
239
+ ttlSeconds: null,
240
+ });
241
+
242
+ publishMock.mockClear();
243
+ const result = await setInferenceProfileSession({
244
+ conversationId: conv.id,
245
+ profile: null,
246
+ });
247
+
248
+ expect(result.profile).toBeNull();
249
+ // No prior active SESSION (sessionId was null), so replaced is null even
250
+ // though the sticky profile was cleared.
251
+ expect(result.replaced).toBeNull();
252
+
253
+ // The clear DID happen — DB row reflects it and an event was published.
254
+ expect(publishMock).toHaveBeenCalledTimes(1);
255
+ const row = getConversation(conv.id);
256
+ expect(row?.inferenceProfile).toBeNull();
257
+ });
258
+
259
+ test("open with unknown profile — throws BadRequestError", async () => {
260
+ const conv = createConversation("sess-handler-unknown-profile");
261
+
262
+ await expect(
263
+ setInferenceProfileSession({
264
+ conversationId: conv.id,
265
+ profile: "nonexistent-profile",
266
+ ttlSeconds: 300,
267
+ }),
268
+ ).rejects.toThrow('Profile "nonexistent-profile" is not defined in llm.profiles');
269
+ });
270
+
271
+ test("open with ttlSeconds=null — expiresAt=null, sessionId=null, profile kept", async () => {
272
+ const conv = createConversation("sess-handler-null-ttl");
273
+
274
+ const result = await setInferenceProfileSession({
275
+ conversationId: conv.id,
276
+ profile: "balanced",
277
+ ttlSeconds: null,
278
+ });
279
+
280
+ expect(result.profile).toBe("balanced");
281
+ expect(result.sessionId).toBeNull();
282
+ expect(result.expiresAt).toBeNull();
283
+ expect(result.ttlSeconds).toBeNull();
284
+ expect(result.replaced).toBeNull();
285
+ });
286
+
287
+ test("throws NotFoundError for unknown conversation id", async () => {
288
+ await expect(
289
+ setInferenceProfileSession({
290
+ conversationId: "conv-does-not-exist",
291
+ profile: "balanced",
292
+ }),
293
+ ).rejects.toThrow("not found");
294
+ });
295
+
296
+ test("caller-supplied sessionId is used when ttlSeconds is provided", async () => {
297
+ const conv = createConversation("sess-handler-caller-session-id");
298
+ const callerSessionId = "my-custom-session-id";
299
+
300
+ const result = await setInferenceProfileSession({
301
+ conversationId: conv.id,
302
+ profile: "balanced",
303
+ ttlSeconds: 300,
304
+ sessionId: callerSessionId,
305
+ });
306
+
307
+ expect(result.sessionId).toBe(callerSessionId);
308
+ });
309
+ });
310
+
311
+ describe("closeInferenceProfileSession", () => {
312
+ beforeEach(() => {
313
+ resetDb();
314
+ mockProfiles = { balanced: {} };
315
+ mockMaxTtl = undefined;
316
+ });
317
+
318
+ test("close — returns closed with profile and sessionId, noop=false", async () => {
319
+ const conv = createConversation("sess-handler-close");
320
+
321
+ const opened = await setInferenceProfileSession({
322
+ conversationId: conv.id,
323
+ profile: "balanced",
324
+ ttlSeconds: 300,
325
+ });
326
+
327
+ const closed = await closeInferenceProfileSession(conv.id);
328
+
329
+ expect(closed.conversationId).toBe(conv.id);
330
+ expect(closed.noop).toBe(false);
331
+ expect(closed.closed).not.toBeNull();
332
+ expect(closed.closed!.profile).toBe("balanced");
333
+ expect(closed.closed!.sessionId).toBe(opened.sessionId);
334
+ });
335
+
336
+ test("close with no active session — closed=null, noop=true", async () => {
337
+ const conv = createConversation("sess-handler-close-noop");
338
+
339
+ const result = await closeInferenceProfileSession(conv.id);
340
+
341
+ expect(result.conversationId).toBe(conv.id);
342
+ expect(result.noop).toBe(true);
343
+ expect(result.closed).toBeNull();
344
+ });
345
+
346
+ test("close with sticky override (no sessionId) — noop=true, sticky override preserved", async () => {
347
+ const conv = createConversation("sess-handler-close-sticky");
348
+
349
+ // Set a sticky override (no ttlSeconds → sessionId=null)
350
+ await setInferenceProfileSession({
351
+ conversationId: conv.id,
352
+ profile: "balanced",
353
+ });
354
+
355
+ expect(getConversation(conv.id)?.inferenceProfileSessionId).toBeNull();
356
+
357
+ const result = await closeInferenceProfileSession(conv.id);
358
+
359
+ expect(result.noop).toBe(true);
360
+ expect(result.closed).toBeNull();
361
+ // Sticky override must remain untouched
362
+ expect(getConversation(conv.id)?.inferenceProfile).toBe("balanced");
363
+ });
364
+ });
365
+
366
+ describe("listInferenceProfileSessionsWithRemaining", () => {
367
+ beforeEach(() => {
368
+ resetDb();
369
+ mockProfiles = { balanced: {} };
370
+ mockMaxTtl = undefined;
371
+ });
372
+
373
+ test("lists active sessions with remainingSeconds > 0", async () => {
374
+ const conv = createConversation("sess-handler-list");
375
+
376
+ await setInferenceProfileSession({
377
+ conversationId: conv.id,
378
+ profile: "balanced",
379
+ ttlSeconds: 600,
380
+ });
381
+
382
+ const sessions = listInferenceProfileSessionsWithRemaining(conv.id);
383
+
384
+ expect(sessions).toHaveLength(1);
385
+ expect(sessions[0].conversationId).toBe(conv.id);
386
+ expect(sessions[0].profile).toBe("balanced");
387
+ expect(sessions[0].remainingSeconds).toBeGreaterThan(0);
388
+ expect(sessions[0].remainingSeconds).toBeLessThanOrEqual(600);
389
+ });
390
+
391
+ test("returns empty list when no active session exists", async () => {
392
+ const conv = createConversation("sess-handler-list-empty");
393
+
394
+ const sessions = listInferenceProfileSessionsWithRemaining(conv.id);
395
+
396
+ expect(sessions).toHaveLength(0);
397
+ });
398
+ });
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Round-trip tests for the three inference-profile session IPC ops:
3
+ * inference_profile_open, inference_profile_close, inference_profile_list.
4
+ *
5
+ * These tests exercise the route handler functions (the IPC-facing entry
6
+ * points) rather than the shared helper directly.
7
+ */
8
+ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
9
+
10
+ import { makeMockLogger } from "./helpers/mock-logger.js";
11
+
12
+ mock.module("../util/logger.js", () => ({
13
+ getLogger: () => makeMockLogger(),
14
+ }));
15
+
16
+ mock.module("../runtime/assistant-event-hub.js", () => ({
17
+ assistantEventHub: { publish: async () => {} },
18
+ }));
19
+
20
+ mock.module("../runtime/assistant-event.js", () => ({
21
+ buildAssistantEvent: (event: unknown) => event,
22
+ }));
23
+
24
+ mock.module("../config/loader.js", () => ({
25
+ loadConfig: () => ({
26
+ llm: {
27
+ profiles: { balanced: {}, "cost-optimized": {} },
28
+ profileSession: { defaultTtlSeconds: 1800, maxTtlSeconds: 43200 },
29
+ },
30
+ }),
31
+ getConfig: () => ({
32
+ llm: {
33
+ profiles: { balanced: {}, "cost-optimized": {} },
34
+ profileSession: { defaultTtlSeconds: 1800, maxTtlSeconds: 43200 },
35
+ },
36
+ }),
37
+ }));
38
+
39
+ import { createConversation } from "../memory/conversation-crud.js";
40
+ import { getDb, resetDb } from "../memory/db-connection.js";
41
+ import { initializeDb } from "../memory/db-init.js";
42
+ import { ROUTES } from "../runtime/routes/inference-profile-session-routes.js";
43
+
44
+ initializeDb();
45
+
46
+ const openRoute = ROUTES.find((r) => r.operationId === "inference_profile_open")!;
47
+ const closeRoute = ROUTES.find((r) => r.operationId === "inference_profile_close")!;
48
+ const listRoute = ROUTES.find((r) => r.operationId === "inference_profile_list")!;
49
+
50
+ function clearTables(): void {
51
+ const db = getDb();
52
+ db.run("DELETE FROM conversation_assistant_attention_state");
53
+ db.run("DELETE FROM external_conversation_bindings");
54
+ db.run("DELETE FROM conversation_keys");
55
+ db.run("DELETE FROM messages");
56
+ db.run("DELETE FROM conversations");
57
+ }
58
+
59
+ describe("inference_profile_open IPC op", () => {
60
+ beforeEach(clearTables);
61
+ afterAll(() => {
62
+ resetDb();
63
+ mock.restore();
64
+ });
65
+
66
+ test("opens a session with TTL and returns sessionId + expiresAt", async () => {
67
+ const conv = createConversation("ipc-open-ttl");
68
+
69
+ const result = await openRoute.handler({
70
+ body: { conversationId: conv.id, profile: "balanced", ttlSeconds: 300 },
71
+ headers: {},
72
+ });
73
+
74
+ expect(result).toMatchObject({
75
+ conversationId: conv.id,
76
+ profile: "balanced",
77
+ replaced: null,
78
+ });
79
+ expect((result as { sessionId: string }).sessionId).not.toBeNull();
80
+ expect((result as { expiresAt: number }).expiresAt).toBeGreaterThan(Date.now());
81
+ });
82
+
83
+ test("opens a sticky session (no ttlSeconds) — sessionId=null, expiresAt=null", async () => {
84
+ const conv = createConversation("ipc-open-sticky");
85
+
86
+ const result = await openRoute.handler({
87
+ body: { conversationId: conv.id, profile: "balanced" },
88
+ headers: {},
89
+ });
90
+
91
+ expect(result).toMatchObject({
92
+ conversationId: conv.id,
93
+ profile: "balanced",
94
+ sessionId: null,
95
+ expiresAt: null,
96
+ replaced: null,
97
+ });
98
+ });
99
+
100
+ test("rejects profile=null with BadRequestError", async () => {
101
+ const conv = createConversation("ipc-open-null-profile");
102
+
103
+ await expect(
104
+ openRoute.handler({
105
+ body: { conversationId: conv.id, profile: null },
106
+ headers: {},
107
+ }),
108
+ ).rejects.toThrow("profile must be a non-empty string");
109
+ });
110
+
111
+ test("replaced carries prior session when opening over an active session", async () => {
112
+ const conv = createConversation("ipc-open-replace");
113
+
114
+ const first = (await openRoute.handler({
115
+ body: { conversationId: conv.id, profile: "balanced", ttlSeconds: 300 },
116
+ headers: {},
117
+ })) as { sessionId: string };
118
+
119
+ const second = (await openRoute.handler({
120
+ body: {
121
+ conversationId: conv.id,
122
+ profile: "cost-optimized",
123
+ ttlSeconds: 600,
124
+ },
125
+ headers: {},
126
+ })) as { replaced: { profile: string; sessionId: string } | null };
127
+
128
+ expect(second.replaced).not.toBeNull();
129
+ expect(second.replaced!.profile).toBe("balanced");
130
+ expect(second.replaced!.sessionId).toBe(first.sessionId);
131
+ });
132
+ });
133
+
134
+ describe("inference_profile_close IPC op", () => {
135
+ beforeEach(clearTables);
136
+
137
+ test("closes an active session — noop=false, closed carries profile and sessionId", async () => {
138
+ const conv = createConversation("ipc-close-active");
139
+
140
+ const opened = (await openRoute.handler({
141
+ body: { conversationId: conv.id, profile: "balanced", ttlSeconds: 300 },
142
+ headers: {},
143
+ })) as { sessionId: string };
144
+
145
+ const result = (await closeRoute.handler({
146
+ body: { conversationId: conv.id },
147
+ headers: {},
148
+ })) as { noop: boolean; closed: { profile: string; sessionId: string } | null };
149
+
150
+ expect(result.noop).toBe(false);
151
+ expect(result.closed).not.toBeNull();
152
+ expect(result.closed!.profile).toBe("balanced");
153
+ expect(result.closed!.sessionId).toBe(opened.sessionId);
154
+ });
155
+
156
+ test("close with no active session — noop=true, closed=null", async () => {
157
+ const conv = createConversation("ipc-close-noop");
158
+
159
+ const result = (await closeRoute.handler({
160
+ body: { conversationId: conv.id },
161
+ headers: {},
162
+ })) as { noop: boolean; closed: null };
163
+
164
+ expect(result.noop).toBe(true);
165
+ expect(result.closed).toBeNull();
166
+ });
167
+ });
168
+
169
+ describe("inference_profile_list IPC op", () => {
170
+ beforeEach(clearTables);
171
+
172
+ test("lists active sessions across all conversations when no filter", async () => {
173
+ const conv1 = createConversation("ipc-list-all-1");
174
+ const conv2 = createConversation("ipc-list-all-2");
175
+
176
+ await openRoute.handler({
177
+ body: { conversationId: conv1.id, profile: "balanced", ttlSeconds: 300 },
178
+ headers: {},
179
+ });
180
+ await openRoute.handler({
181
+ body: {
182
+ conversationId: conv2.id,
183
+ profile: "cost-optimized",
184
+ ttlSeconds: 600,
185
+ },
186
+ headers: {},
187
+ });
188
+
189
+ const result = (await listRoute.handler({
190
+ queryParams: {},
191
+ headers: {},
192
+ })) as { sessions: Array<{ conversationId: string }> };
193
+
194
+ expect(result.sessions.length).toBeGreaterThanOrEqual(2);
195
+ const ids = result.sessions.map((s) => s.conversationId);
196
+ expect(ids).toContain(conv1.id);
197
+ expect(ids).toContain(conv2.id);
198
+ });
199
+
200
+ test("scopes to a single conversation when conversationId filter is provided", async () => {
201
+ const conv1 = createConversation("ipc-list-filter-1");
202
+ const conv2 = createConversation("ipc-list-filter-2");
203
+
204
+ await openRoute.handler({
205
+ body: { conversationId: conv1.id, profile: "balanced", ttlSeconds: 300 },
206
+ headers: {},
207
+ });
208
+ await openRoute.handler({
209
+ body: {
210
+ conversationId: conv2.id,
211
+ profile: "cost-optimized",
212
+ ttlSeconds: 600,
213
+ },
214
+ headers: {},
215
+ });
216
+
217
+ const result = (await listRoute.handler({
218
+ queryParams: { conversationId: conv1.id },
219
+ headers: {},
220
+ })) as { sessions: Array<{ conversationId: string }> };
221
+
222
+ expect(result.sessions).toHaveLength(1);
223
+ expect(result.sessions[0].conversationId).toBe(conv1.id);
224
+ });
225
+
226
+ test("returns empty list when no active session for the given conversationId", async () => {
227
+ const conv = createConversation("ipc-list-empty");
228
+
229
+ const result = (await listRoute.handler({
230
+ queryParams: { conversationId: conv.id },
231
+ headers: {},
232
+ })) as { sessions: unknown[] };
233
+
234
+ expect(result.sessions).toHaveLength(0);
235
+ });
236
+ });
@@ -14,7 +14,7 @@
14
14
 
15
15
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
16
16
  import { join } from "node:path";
17
- import { beforeEach, describe, expect, mock, test } from "bun:test";
17
+ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
18
18
 
19
19
  // ── Mock setup (must be before any imports from the project) ──────────────
20
20
 
@@ -115,6 +115,7 @@ describe("inline-command skill_load permissions", () => {
115
115
  beforeEach(() => {
116
116
  clearRiskCache();
117
117
  _clearGlobalCacheForTesting();
118
+ _setOverridesForTesting({});
118
119
  mockIpcResponse("get_global_thresholds", {
119
120
  interactive: "low",
120
121
  autonomous: "medium",
@@ -133,6 +134,10 @@ describe("inline-command skill_load permissions", () => {
133
134
  }
134
135
  });
135
136
 
137
+ afterEach(() => {
138
+ _setOverridesForTesting({});
139
+ });
140
+
136
141
  // ── Default behavior ─────────────────────────────────────────────────
137
142
 
138
143
  describe("default behavior", () => {
@@ -180,7 +180,7 @@ describe("installSkill routing", () => {
180
180
  "vercel-labs",
181
181
  "agent-skills",
182
182
  "react-best-practices",
183
- true, // overwrite
183
+ true, // overwrite — handler default is true for HTTP API back-compat; CLI passes explicit false
184
184
  undefined, // ref
185
185
  undefined, // contactId
186
186
  );
@@ -221,7 +221,7 @@ describe("installSkill routing", () => {
221
221
  "owner",
222
222
  "repo",
223
223
  "my-skill",
224
- true,
224
+ true, // overwrite — handler default is true for HTTP API back-compat; CLI passes explicit false
225
225
  undefined, // ref
226
226
  undefined, // contactId
227
227
  );