@vellumai/assistant 0.8.4 → 0.8.6

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 (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -1,3 +1,5 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
1
3
  import { afterAll, beforeEach, describe, expect, test } from "bun:test";
2
4
 
3
5
  import {
@@ -8,14 +10,15 @@ import {
8
10
  projectAssistantMessage,
9
11
  recordConversationSeenSignal,
10
12
  } from "../memory/conversation-attention-store.js";
11
- import { createConversation } from "../memory/conversation-crud.js";
12
- import { getDb, resetDb } from "../memory/db-connection.js";
13
+ import { addMessage, createConversation } from "../memory/conversation-crud.js";
14
+ import { getDb } from "../memory/db-connection.js";
13
15
  import { initializeDb } from "../memory/db-init.js";
14
16
  import type { AssistantEvent } from "../runtime/assistant-event.js";
15
17
  import { assistantEventHub } from "../runtime/assistant-event-hub.js";
16
18
  import { ROUTES as CONVERSATION_LIST_ROUTES } from "../runtime/routes/conversation-list-routes.js";
17
19
  import { ROUTES as CONVERSATION_MANAGEMENT_ROUTES } from "../runtime/routes/conversation-management-routes.js";
18
20
  import type { RouteDefinition } from "../runtime/routes/types.js";
21
+ import { resetDbForTesting } from "./db-test-helpers.js";
19
22
  import { waitFor } from "./helpers/wait-for.js";
20
23
 
21
24
  initializeDb();
@@ -70,10 +73,19 @@ describe("conversation sync tags", () => {
70
73
  });
71
74
 
72
75
  afterAll(() => {
73
- resetDb();
76
+ resetDbForTesting();
74
77
  });
75
78
 
76
- test("rename emits legacy title/list events and conversation metadata sync tags", async () => {
79
+ test("rename emits the typed title event and a metadata-only sync tag (no list umbrella)", async () => {
80
+ // Rename is a content-only change: the row stays in place, the list
81
+ // shape is unchanged, only the title field flips. Web patches the
82
+ // single cached row via the typed `conversation_title_updated` event
83
+ // (`patchConversation` in `metadata-handlers.ts`) and the per-
84
+ // conversation `sync_changed` metadata tag is included as a belt-and-
85
+ // suspenders signal for sibling-tab consumers that missed the typed
86
+ // event. The legacy `conversation_list_invalidated` broadcast is
87
+ // scoped to `targetInterfaceId: "macos"` and therefore not visible to
88
+ // this process-type subscriber.
77
89
  const conversation = createConversation("Old title");
78
90
  const route = findRoute(
79
91
  CONVERSATION_MANAGEMENT_ROUTES,
@@ -85,23 +97,55 @@ describe("conversation sync tags", () => {
85
97
  pathParams: { id: conversation.id },
86
98
  body: { name: "New title" },
87
99
  });
88
- }, 3);
100
+ }, 2);
89
101
 
90
102
  expect(received.map((event) => event.message.type)).toEqual([
91
103
  "conversation_title_updated",
92
- "conversation_list_invalidated",
93
104
  "sync_changed",
94
105
  ]);
95
- expect(received[2]!.message).toEqual({
106
+ expect(received[1]!.message).toEqual({
96
107
  type: "sync_changed",
97
- tags: [
98
- SYNC_TAGS.conversationsList,
99
- conversationMetadataSyncTag(conversation.id),
100
- ],
108
+ tags: [conversationMetadataSyncTag(conversation.id)],
101
109
  });
110
+ // Defense-in-depth: the umbrella `conversationsList` tag would force
111
+ // web to redrain the full paginated list — we deliberately omit it
112
+ // for content-only reasons.
113
+ expect((received[1]!.message as { tags: string[] }).tags).not.toContain(
114
+ SYNC_TAGS.conversationsList,
115
+ );
116
+ // The legacy invalidation broadcast is macOS-scoped and must not
117
+ // reach this process-type subscriber.
118
+ expect(
119
+ received.some(
120
+ (event) => event.message.type === "conversation_list_invalidated",
121
+ ),
122
+ ).toBe(false);
102
123
  });
103
124
 
104
- test("create emits legacy list invalidation and list/metadata sync tags", async () => {
125
+ test("agent-loop title updates emit metadata-only sync tags (no list umbrella)", () => {
126
+ const source = readFileSync(
127
+ join(import.meta.dir, "..", "daemon", "conversation-agent-loop.ts"),
128
+ "utf-8",
129
+ );
130
+ const titleUpdateBlocks =
131
+ source.match(
132
+ /type: "conversation_title_updated"[\s\S]{0,500}?type: "sync_changed"[\s\S]{0,250}?tags: \[[\s\S]*?\]/g,
133
+ ) ?? [];
134
+
135
+ expect(titleUpdateBlocks.length).toBeGreaterThanOrEqual(2);
136
+ for (const block of titleUpdateBlocks) {
137
+ expect(block).not.toContain("SYNC_TAGS.conversationsList");
138
+ }
139
+ });
140
+
141
+ test("create emits a sync_changed with the conversationsList umbrella tag", async () => {
142
+ // Create is shape-changing — a row is added to the paginated list,
143
+ // so web must redrain the list (cannot patch a row it has never
144
+ // fetched). The umbrella `conversationsList` tag is the signal for
145
+ // that redrain. Per-conversation metadata is included so any future
146
+ // single-row consumer can patch the freshly added row in place
147
+ // without an extra GET. The legacy macOS-only invalidation broadcast
148
+ // is not visible to process subscribers.
105
149
  const route = findRoute(
106
150
  CONVERSATION_MANAGEMENT_ROUTES,
107
151
  "createConversation",
@@ -113,23 +157,33 @@ describe("conversation sync tags", () => {
113
157
  body: { conversationKey: "sync-create-test" },
114
158
  })) as { id: string };
115
159
  conversationId = result.id;
116
- }, 2);
160
+ }, 1);
117
161
 
118
162
  expect(conversationId).toBeDefined();
119
163
  expect(received.map((event) => event.message.type)).toEqual([
120
- "conversation_list_invalidated",
121
164
  "sync_changed",
122
165
  ]);
123
- expect(received[1]!.message).toEqual({
166
+ expect(received[0]!.message).toEqual({
124
167
  type: "sync_changed",
125
168
  tags: [
126
169
  SYNC_TAGS.conversationsList,
127
170
  conversationMetadataSyncTag(conversationId!),
128
171
  ],
129
172
  });
173
+ expect(
174
+ received.some(
175
+ (event) => event.message.type === "conversation_list_invalidated",
176
+ ),
177
+ ).toBe(false);
130
178
  });
131
179
 
132
- test("reorder emits list invalidation and metadata sync tags for touched conversations", async () => {
180
+ test("reorder emits a sync_changed with the umbrella tag and per-conversation metadata tags", async () => {
181
+ // Reorder changes the row position in the paginated list — also
182
+ // shape-changing. The umbrella `conversationsList` tag forces a
183
+ // redrain so the new ordering shows. Per-conversation metadata tags
184
+ // are bundled in to give any single-row consumer a hint that the
185
+ // touched conversations' positions have moved (currently web
186
+ // consumes only the umbrella tag; metadata tags are forward-compat).
133
187
  const first = createConversation("First");
134
188
  const second = createConversation("Second");
135
189
  const route = findRoute(
@@ -146,13 +200,12 @@ describe("conversation sync tags", () => {
146
200
  ],
147
201
  },
148
202
  });
149
- }, 2);
203
+ }, 1);
150
204
 
151
205
  expect(received.map((event) => event.message.type)).toEqual([
152
- "conversation_list_invalidated",
153
206
  "sync_changed",
154
207
  ]);
155
- expect(received[1]!.message).toEqual({
208
+ expect(received[0]!.message).toEqual({
156
209
  type: "sync_changed",
157
210
  tags: [
158
211
  SYNC_TAGS.conversationsList,
@@ -160,9 +213,28 @@ describe("conversation sync tags", () => {
160
213
  conversationMetadataSyncTag(second.id),
161
214
  ],
162
215
  });
216
+ expect(
217
+ received.some(
218
+ (event) => event.message.type === "conversation_list_invalidated",
219
+ ),
220
+ ).toBe(false);
163
221
  });
164
222
 
165
- test("record seen emits list invalidation and metadata sync tags for the touched conversation", async () => {
223
+ test("record seen emits only a per-conversation metadata sync tag (no list umbrella)", async () => {
224
+ // Seen state is per-conversation attention metadata, not list-
225
+ // shaped. The old behavior emitted `sync_changed` carrying the
226
+ // umbrella `conversationsList` tag, which forced every subscribed
227
+ // web client to redrain the full paginated sidebar on every
228
+ // conversation switch that landed on an unseen conversation (~14
229
+ // requests at ~300 conversations). The current behavior emits a
230
+ // single `sync_changed` with only the per-conversation
231
+ // `conversation:<id>:metadata` tag, which web consumes by GET-and-
232
+ // patching the single cached row via `refreshConversationRow`.
233
+ //
234
+ // The legacy `conversation_list_invalidated` broadcast is still
235
+ // emitted for macOS (which has no per-row patcher) but is scoped
236
+ // to `targetInterfaceId: "macos"` and therefore not visible to
237
+ // this process-type subscriber.
166
238
  const conversation = createConversation("Attention");
167
239
  projectAssistantMessage({
168
240
  conversationId: conversation.id,
@@ -181,22 +253,32 @@ describe("conversation sync tags", () => {
181
253
  source: "test",
182
254
  },
183
255
  });
184
- }, 2);
256
+ }, 1);
185
257
 
186
258
  expect(received.map((event) => event.message.type)).toEqual([
187
- "conversation_list_invalidated",
188
259
  "sync_changed",
189
260
  ]);
190
- expect(received[1]!.message).toEqual({
261
+ expect(received[0]!.message).toEqual({
191
262
  type: "sync_changed",
192
- tags: [
193
- SYNC_TAGS.conversationsList,
194
- conversationMetadataSyncTag(conversation.id),
195
- ],
263
+ tags: [conversationMetadataSyncTag(conversation.id)],
196
264
  });
265
+ // Defense-in-depth: the umbrella `conversationsList` tag would
266
+ // force the very paginated-list drain this redesign exists to
267
+ // avoid. It must not appear here.
268
+ expect((received[0]!.message as { tags: string[] }).tags).not.toContain(
269
+ SYNC_TAGS.conversationsList,
270
+ );
271
+ expect(
272
+ received.some(
273
+ (event) => event.message.type === "conversation_list_invalidated",
274
+ ),
275
+ ).toBe(false);
197
276
  });
198
277
 
199
- test("mark unread emits list invalidation and metadata sync tags for the touched conversation", async () => {
278
+ test("mark unread emits only a per-conversation metadata sync tag (no list umbrella)", async () => {
279
+ // Symmetric with `record seen`: mark-unread flips the per-conversation
280
+ // hasUnseen flag back to true. Same per-conversation sync tag, same
281
+ // absence of list-level fan-out.
200
282
  const conversation = createConversation("Attention");
201
283
  projectAssistantMessage({
202
284
  conversationId: conversation.id,
@@ -218,18 +300,119 @@ describe("conversation sync tags", () => {
218
300
  conversationId: conversation.id,
219
301
  },
220
302
  });
221
- }, 2);
303
+ }, 1);
222
304
 
223
305
  expect(received.map((event) => event.message.type)).toEqual([
224
- "conversation_list_invalidated",
225
306
  "sync_changed",
226
307
  ]);
227
- expect(received[1]!.message).toEqual({
308
+ expect(received[0]!.message).toEqual({
228
309
  type: "sync_changed",
229
- tags: [
230
- SYNC_TAGS.conversationsList,
231
- conversationMetadataSyncTag(conversation.id),
232
- ],
310
+ tags: [conversationMetadataSyncTag(conversation.id)],
311
+ });
312
+ expect((received[0]!.message as { tags: string[] }).tags).not.toContain(
313
+ SYNC_TAGS.conversationsList,
314
+ );
315
+ expect(
316
+ received.some(
317
+ (event) => event.message.type === "conversation_list_invalidated",
318
+ ),
319
+ ).toBe(false);
320
+ });
321
+
322
+ test("addMessage('assistant') emits a metadata sync tag when attention state transitions", async () => {
323
+ // When an assistant message transitions a conversation from seen to
324
+ // unseen, `addMessage` emits `conversation:<id>:metadata` so the web
325
+ // sidebar picks up the attention state change without a full list
326
+ // refetch. This is the fix for LUM-1907: background processes that
327
+ // add assistant messages (notification delivery, proactive artifacts)
328
+ // now automatically notify clients.
329
+ const conversation = createConversation("Attention sync");
330
+
331
+ const received = await captureEvents(async () => {
332
+ await addMessage(
333
+ conversation.id,
334
+ "assistant",
335
+ JSON.stringify([{ type: "text", text: "hello" }]),
336
+ );
337
+ }, 1);
338
+
339
+ expect(received.map((event) => event.message.type)).toEqual([
340
+ "sync_changed",
341
+ ]);
342
+ expect(received[0]!.message).toEqual({
343
+ type: "sync_changed",
344
+ tags: [conversationMetadataSyncTag(conversation.id)],
345
+ });
346
+ });
347
+
348
+ test("addMessage('assistant') does not emit a metadata sync tag when already unseen", async () => {
349
+ // When the conversation is already unseen (attention cursor was
350
+ // already past the seen cursor), a subsequent assistant message
351
+ // should NOT emit a metadata tag — no state transition occurred.
352
+ const conversation = createConversation("Already unseen");
353
+ await addMessage(
354
+ conversation.id,
355
+ "assistant",
356
+ JSON.stringify([{ type: "text", text: "first" }]),
357
+ );
358
+
359
+ const received: AssistantEvent[] = [];
360
+ const subscription = assistantEventHub.subscribe({
361
+ type: "process",
362
+ callback: (event) => {
363
+ received.push(event);
364
+ },
365
+ });
366
+ try {
367
+ await addMessage(
368
+ conversation.id,
369
+ "assistant",
370
+ JSON.stringify([{ type: "text", text: "second" }]),
371
+ );
372
+ // Brief wait to ensure no event is emitted
373
+ await new Promise((resolve) => setTimeout(resolve, 50));
374
+ const metadataEvents = received.filter(
375
+ (event) =>
376
+ event.message.type === "sync_changed" &&
377
+ (event.message as { tags: string[] }).tags.some((tag: string) =>
378
+ tag.includes(":metadata"),
379
+ ),
380
+ );
381
+ expect(metadataEvents).toHaveLength(0);
382
+ } finally {
383
+ subscription.dispose();
384
+ }
385
+ });
386
+
387
+ test("addMessage('user') does not emit a metadata sync tag", async () => {
388
+ // User messages never affect attention state — only assistant
389
+ // messages advance the attention cursor via projectAssistantMessage.
390
+ const conversation = createConversation("User message");
391
+
392
+ const received: AssistantEvent[] = [];
393
+ const subscription = assistantEventHub.subscribe({
394
+ type: "process",
395
+ callback: (event) => {
396
+ received.push(event);
397
+ },
233
398
  });
399
+ try {
400
+ await addMessage(
401
+ conversation.id,
402
+ "user",
403
+ JSON.stringify([{ type: "text", text: "hello" }]),
404
+ );
405
+ await new Promise((resolve) => setTimeout(resolve, 50));
406
+ const metadataEvents = received.filter(
407
+ (event) =>
408
+ event.message.type === "sync_changed" &&
409
+ (event.message as { tags: string[] }).tags.some((tag: string) =>
410
+ tag.includes(":metadata"),
411
+ ),
412
+ );
413
+ expect(metadataEvents).toHaveLength(0);
414
+ } finally {
415
+ subscription.dispose();
416
+ }
234
417
  });
235
418
  });
@@ -37,6 +37,7 @@ mock.module("../memory/conversation-crud.js", () => ({
37
37
  getConversation: mockGetConversation,
38
38
  getMessages: mockGetMessages,
39
39
  updateConversationTitle: mockUpdateConversationTitle,
40
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
40
41
  }));
41
42
 
42
43
  mock.module("../providers/provider-send-message.js", () => ({
@@ -295,6 +295,36 @@ describe("session-tool-setup app refresh side effects", () => {
295
295
  });
296
296
  });
297
297
 
298
+ test("canonicalizes legacy computer_use_press_key skill_execute alias before dispatch", async () => {
299
+ const ctx = makeCtx({ allowedToolNames: new Set(["computer_use_key"]) });
300
+ const executor = makeFakeExecutor({ content: "ok", isError: false });
301
+
302
+ const toolFn = createToolExecutor(
303
+ executor as unknown as ToolExecutor,
304
+ noopPrompter,
305
+ noopSecretPrompter,
306
+ ctx,
307
+ noopLifecycleHandler,
308
+ );
309
+
310
+ await toolFn("skill_execute", {
311
+ tool: "computer_use_press_key",
312
+ input: {
313
+ key: "Space",
314
+ modifiers: ["Command"],
315
+ reasoning: "Open Spotlight",
316
+ },
317
+ activity: "Opening Spotlight",
318
+ });
319
+
320
+ const calls = executor.execute.mock.calls as unknown[][];
321
+ expect(calls[0][0]).toBe("computer_use_key");
322
+ expect(calls[0][1]).toEqual({
323
+ key: "cmd+space",
324
+ reasoning: "Open Spotlight",
325
+ });
326
+ });
327
+
298
328
  test("preserves exact active create_app skill tool when app_create is also active", async () => {
299
329
  const ctx = makeCtx({
300
330
  allowedToolNames: new Set(["create_app", "app_create"]),
@@ -36,6 +36,7 @@ mock.module("../memory/conversation-crud.js", () => ({
36
36
  estimatedCost,
37
37
  });
38
38
  },
39
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
39
40
  }));
40
41
 
41
42
  import { recordUsage } from "../daemon/conversation-usage.js";
@@ -87,6 +87,7 @@ mock.module("../security/secret-allowlist.js", () => ({
87
87
 
88
88
  mock.module("../memory/conversation-crud.js", () => ({
89
89
  setConversationOriginChannelIfUnset: () => {},
90
+ setConversationHistoryStrippedAt: () => {},
90
91
  provenanceFromTrustContext: () => ({
91
92
  source: "user",
92
93
  trustContext: undefined,
@@ -110,6 +111,7 @@ mock.module("../memory/conversation-crud.js", () => ({
110
111
  updateConversationContextWindow: () => {},
111
112
  deleteMessageById: () => ({ segmentIds: [], deletedSummaryIds: [] }),
112
113
  deleteLastExchange: () => 0,
114
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
113
115
  }));
114
116
 
115
117
  mock.module("../memory/conversation-queries.js", () => ({
@@ -116,6 +116,7 @@ mock.module("../security/secret-allowlist.js", () => ({
116
116
 
117
117
  mock.module("../memory/conversation-crud.js", () => ({
118
118
  setConversationOriginChannelIfUnset: () => {},
119
+ setConversationHistoryStrippedAt: () => {},
119
120
  provenanceFromTrustContext: () => ({
120
121
  source: "user",
121
122
  trustContext: undefined,
@@ -144,7 +145,8 @@ mock.module("../memory/conversation-crud.js", () => ({
144
145
  setLastNotifiedInferenceProfile: () => {},
145
146
  getConversationOverrideProfileFromRow: () => undefined,
146
147
  updateMessageMetadata: () => {},
147
- clearStrippedInjectionMetadataForConversation: () => {},
148
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
149
+ updateMessageContent: mock(() => {}),
148
150
  }));
149
151
 
150
152
  mock.module("../memory/conversation-queries.js", () => ({
@@ -244,6 +246,9 @@ mock.module("../agent/loop.js", () => ({
244
246
  messages: Message[],
245
247
  onEvent: (event: AgentEvent) => void,
246
248
  ): Promise<Message[]> {
249
+ // Prime the assistant row anchor — production code emits this from
250
+ // `AgentLoop.run` just before `provider.sendMessage`.
251
+ await onEvent({ type: "llm_call_started" });
247
252
  runCalls.push(messages);
248
253
  agentLoopScript(onEvent);
249
254
  onEvent({
@@ -114,6 +114,7 @@ mock.module("../security/secret-allowlist.js", () => ({
114
114
 
115
115
  mock.module("../memory/conversation-crud.js", () => ({
116
116
  setConversationOriginChannelIfUnset: () => {},
117
+ setConversationHistoryStrippedAt: () => {},
117
118
  provenanceFromTrustContext: () => ({
118
119
  source: "user",
119
120
  trustContext: undefined,
@@ -141,7 +142,8 @@ mock.module("../memory/conversation-crud.js", () => ({
141
142
  setLastNotifiedInferenceProfile: () => {},
142
143
  getConversationOverrideProfileFromRow: () => undefined,
143
144
  updateMessageMetadata: () => {},
144
- clearStrippedInjectionMetadataForConversation: () => {},
145
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
146
+ updateMessageContent: mock(() => {}),
145
147
  }));
146
148
 
147
149
  mock.module("../memory/conversation-queries.js", () => ({
@@ -228,6 +230,9 @@ mock.module("../agent/loop.js", () => ({
228
230
  messages: Message[],
229
231
  onEvent: (event: AgentEvent) => void,
230
232
  ): Promise<Message[]> {
233
+ // Prime the assistant row anchor — production code emits this from
234
+ // `AgentLoop.run` just before `provider.sendMessage`.
235
+ await onEvent({ type: "llm_call_started" });
231
236
  agentLoopScript(onEvent);
232
237
  onEvent({
233
238
  type: "usage",
@@ -28,8 +28,8 @@ mock.module("../util/logger.js", () => ({
28
28
  // Use encrypted backend with a temp store path
29
29
  // ---------------------------------------------------------------------------
30
30
 
31
- import { _setStorePath } from "../security/encrypted-store.js";
32
31
  import { _resetBackend } from "../security/secure-keys.js";
32
+ import { setStorePathForTesting } from "./encrypted-store-test-helpers.js";
33
33
 
34
34
  const TEST_DIR = join(
35
35
  tmpdir(),
@@ -74,7 +74,7 @@ describe("CredentialBroker.browserFill", () => {
74
74
  for (const entry of readdirSync(TEST_DIR)) {
75
75
  rmSync(join(TEST_DIR, entry), { recursive: true, force: true });
76
76
  }
77
- _setStorePath(STORE_PATH);
77
+ setStorePathForTesting(STORE_PATH);
78
78
  _resetBackend();
79
79
  _setMetadataPath(join(TEST_DIR, "metadata.json"));
80
80
  broker = new CredentialBroker();
@@ -82,7 +82,7 @@ describe("CredentialBroker.browserFill", () => {
82
82
 
83
83
  afterEach(() => {
84
84
  _setMetadataPath(null);
85
- _setStorePath(null);
85
+ setStorePathForTesting(null);
86
86
  _resetBackend();
87
87
  });
88
88
 
@@ -27,8 +27,8 @@ mock.module("../util/logger.js", () => ({
27
27
  // Use encrypted backend with a temp store path
28
28
  // ---------------------------------------------------------------------------
29
29
 
30
- import { _setStorePath } from "../security/encrypted-store.js";
31
30
  import { _resetBackend } from "../security/secure-keys.js";
31
+ import { setStorePathForTesting } from "./encrypted-store-test-helpers.js";
32
32
 
33
33
  const TEST_DIR = join(
34
34
  tmpdir(),
@@ -69,7 +69,7 @@ describe("CredentialBroker.serverUse", () => {
69
69
 
70
70
  beforeEach(() => {
71
71
  mkdirSync(TEST_DIR, { recursive: true });
72
- _setStorePath(STORE_PATH);
72
+ setStorePathForTesting(STORE_PATH);
73
73
  _resetBackend();
74
74
  _setMetadataPath(join(TEST_DIR, "metadata.json"));
75
75
  broker = new CredentialBroker();
@@ -77,7 +77,7 @@ describe("CredentialBroker.serverUse", () => {
77
77
 
78
78
  afterEach(() => {
79
79
  _setMetadataPath(null);
80
- _setStorePath(null);
80
+ setStorePathForTesting(null);
81
81
  _resetBackend();
82
82
  rmSync(TEST_DIR, { recursive: true, force: true });
83
83
  });
@@ -464,7 +464,7 @@ describe("CredentialBroker.serverUseById", () => {
464
464
 
465
465
  beforeEach(() => {
466
466
  mkdirSync(TEST_DIR, { recursive: true });
467
- _setStorePath(STORE_PATH);
467
+ setStorePathForTesting(STORE_PATH);
468
468
  _resetBackend();
469
469
  _setMetadataPath(join(TEST_DIR, "metadata.json"));
470
470
  broker = new CredentialBroker();
@@ -472,7 +472,7 @@ describe("CredentialBroker.serverUseById", () => {
472
472
 
473
473
  afterEach(() => {
474
474
  _setMetadataPath(null);
475
- _setStorePath(null);
475
+ setStorePathForTesting(null);
476
476
  _resetBackend();
477
477
  rmSync(TEST_DIR, { recursive: true, force: true });
478
478
  });
@@ -8,7 +8,15 @@
8
8
  * 4. The CES RPC client correctly frames requests and validates responses.
9
9
  */
10
10
 
11
- import { readdirSync, readFileSync, statSync } from "node:fs";
11
+ import {
12
+ mkdtempSync,
13
+ readdirSync,
14
+ readFileSync,
15
+ rmSync,
16
+ statSync,
17
+ writeFileSync,
18
+ } from "node:fs";
19
+ import { tmpdir } from "node:os";
12
20
  import { join, resolve } from "node:path";
13
21
  import { describe, expect, test } from "bun:test";
14
22
 
@@ -22,6 +30,7 @@ import {
22
30
  createCesClient,
23
31
  } from "../credential-execution/client.js";
24
32
  import {
33
+ discoverCesWithRetry,
25
34
  discoverLocalCes,
26
35
  discoverManagedCes,
27
36
  } from "../credential-execution/executable-discovery.js";
@@ -147,6 +156,68 @@ describe("managed CES discovery", () => {
147
156
  });
148
157
  });
149
158
 
159
+ // ---------------------------------------------------------------------------
160
+ // Managed discovery retry — absorbs the sidecar's socket re-bind window
161
+ // ---------------------------------------------------------------------------
162
+
163
+ describe("discoverCesWithRetry", () => {
164
+ function withManagedEnv(socketPath: string): () => void {
165
+ const savedSocket = process.env["CES_BOOTSTRAP_SOCKET"];
166
+ const savedSocketDir = process.env["CES_BOOTSTRAP_SOCKET_DIR"];
167
+ const savedContainerized = process.env["IS_CONTAINERIZED"];
168
+ delete process.env["CES_BOOTSTRAP_SOCKET_DIR"];
169
+ process.env["CES_BOOTSTRAP_SOCKET"] = socketPath;
170
+ process.env["IS_CONTAINERIZED"] = "true";
171
+ return () => {
172
+ const restore = (key: string, value: string | undefined) => {
173
+ if (value !== undefined) process.env[key] = value;
174
+ else delete process.env[key];
175
+ };
176
+ restore("CES_BOOTSTRAP_SOCKET", savedSocket);
177
+ restore("CES_BOOTSTRAP_SOCKET_DIR", savedSocketDir);
178
+ restore("IS_CONTAINERIZED", savedContainerized);
179
+ };
180
+ }
181
+
182
+ test("returns unavailable after polling when the socket never appears", async () => {
183
+ const socketPath = join(tmpdir(), `ces-retry-missing-${Date.now()}.sock`);
184
+ const restore = withManagedEnv(socketPath);
185
+ try {
186
+ const start = Date.now();
187
+ const result = await discoverCesWithRetry({
188
+ timeoutMs: 200,
189
+ intervalMs: 20,
190
+ });
191
+ expect(result.mode).toBe("unavailable");
192
+ // It must actually have waited rather than failing on the first probe.
193
+ expect(Date.now() - start).toBeGreaterThanOrEqual(150);
194
+ } finally {
195
+ restore();
196
+ }
197
+ });
198
+
199
+ test("resolves to managed once the socket is re-bound mid-poll", async () => {
200
+ const dir = mkdtempSync(join(tmpdir(), "ces-retry-"));
201
+ const socketPath = join(dir, "ces.sock");
202
+ const restore = withManagedEnv(socketPath);
203
+ try {
204
+ // Simulate the sidecar re-binding its bootstrap socket shortly after
205
+ // the assistant begins probing.
206
+ setTimeout(() => writeFileSync(socketPath, ""), 80);
207
+
208
+ const result = await discoverCesWithRetry({
209
+ timeoutMs: 2_000,
210
+ intervalMs: 20,
211
+ });
212
+ expect(result.mode).toBe("managed");
213
+ expect((result as { socketPath: string }).socketPath).toBe(socketPath);
214
+ } finally {
215
+ restore();
216
+ rmSync(dir, { recursive: true, force: true });
217
+ }
218
+ });
219
+ });
220
+
150
221
  // ---------------------------------------------------------------------------
151
222
  // CES client — transport and framing
152
223
  // ---------------------------------------------------------------------------