@vellumai/assistant 0.7.0 → 0.7.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 (666) hide show
  1. package/ARCHITECTURE.md +6 -7
  2. package/Dockerfile +1 -0
  3. package/README.md +2 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
  5. package/bun.lock +3 -0
  6. package/docs/architecture/security.md +18 -16
  7. package/knip.json +1 -0
  8. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
  9. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
  10. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
  11. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
  12. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
  13. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  14. package/node_modules/@vellumai/slack-text/package.json +18 -0
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  16. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  17. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  18. package/openapi.yaml +294 -107
  19. package/package.json +4 -2
  20. package/scripts/generate-openapi.ts +16 -111
  21. package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
  22. package/src/__tests__/anthropic-provider.test.ts +56 -13
  23. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  24. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  25. package/src/__tests__/approval-cascade.test.ts +0 -15
  26. package/src/__tests__/approval-routes-http.test.ts +6 -17
  27. package/src/__tests__/assistant-event-hub.test.ts +126 -77
  28. package/src/__tests__/assistant-event.test.ts +0 -5
  29. package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
  31. package/src/__tests__/background-shell-host-bash.test.ts +34 -43
  32. package/src/__tests__/call-controller.test.ts +1 -1
  33. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  34. package/src/__tests__/channel-approval-routes.test.ts +10 -296
  35. package/src/__tests__/channel-approvals.test.ts +25 -17
  36. package/src/__tests__/channel-guardian.test.ts +100 -146
  37. package/src/__tests__/checker.test.ts +20 -34
  38. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/config-schema.test.ts +6 -48
  41. package/src/__tests__/config-watcher.test.ts +12 -0
  42. package/src/__tests__/connection-policy.test.ts +1 -52
  43. package/src/__tests__/contacts-write.test.ts +2 -64
  44. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  45. package/src/__tests__/context-search-memory-source.test.ts +120 -1
  46. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  47. package/src/__tests__/context-search-pkb-source.test.ts +49 -0
  48. package/src/__tests__/context-search-workspace-source.test.ts +9 -22
  49. package/src/__tests__/context-window-manager.test.ts +46 -0
  50. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
  51. package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
  52. package/src/__tests__/conversation-agent-loop.test.ts +980 -13
  53. package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
  54. package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
  55. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
  56. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  57. package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
  58. package/src/__tests__/conversation-lifecycle.test.ts +4 -4
  59. package/src/__tests__/conversation-process-callsite.test.ts +79 -2
  60. package/src/__tests__/conversation-queue.test.ts +3 -8
  61. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
  62. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
  63. package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
  64. package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
  65. package/src/__tests__/conversation-slash-commands.test.ts +24 -4
  66. package/src/__tests__/conversation-slash-queue.test.ts +2 -0
  67. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  68. package/src/__tests__/conversation-starter-routes.test.ts +79 -2
  69. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  70. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  71. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  72. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
  73. package/src/__tests__/conversation-usage.test.ts +253 -3
  74. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  75. package/src/__tests__/credential-health-service.test.ts +68 -0
  76. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  77. package/src/__tests__/credential-security-invariants.test.ts +1 -5
  78. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  79. package/src/__tests__/cu-unified-flow.test.ts +33 -16
  80. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  81. package/src/__tests__/daemon-credential-client.test.ts +4 -1
  82. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  83. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  84. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  85. package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
  86. package/src/__tests__/document-conversations.test.ts +332 -0
  87. package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
  88. package/src/__tests__/emit-event-signal.test.ts +4 -6
  89. package/src/__tests__/events-client-registration.test.ts +193 -49
  90. package/src/__tests__/filing-service.test.ts +58 -7
  91. package/src/__tests__/first-greeting.test.ts +156 -150
  92. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  93. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  94. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  95. package/src/__tests__/guardian-dispatch.test.ts +1 -1
  96. package/src/__tests__/guardian-grant-minting.test.ts +7 -2
  97. package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
  98. package/src/__tests__/guardian-routing-state.test.ts +1 -1
  99. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
  100. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
  101. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  102. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  103. package/src/__tests__/heartbeat-service.test.ts +289 -7
  104. package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
  105. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  106. package/src/__tests__/host-bash-proxy.test.ts +46 -122
  107. package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
  108. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
  109. package/src/__tests__/host-browser-proxy.test.ts +111 -185
  110. package/src/__tests__/host-browser-routes.test.ts +45 -75
  111. package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
  112. package/src/__tests__/host-cu-proxy.test.ts +56 -111
  113. package/src/__tests__/host-file-proxy.test.ts +44 -98
  114. package/src/__tests__/host-file-read-tool.test.ts +42 -21
  115. package/src/__tests__/host-shell-tool.test.ts +33 -68
  116. package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
  117. package/src/__tests__/host-transfer-proxy.test.ts +43 -53
  118. package/src/__tests__/http-user-message-parity.test.ts +0 -6
  119. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  120. package/src/__tests__/injector-chain.test.ts +10 -5
  121. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  122. package/src/__tests__/inline-command-runner.test.ts +0 -66
  123. package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
  124. package/src/__tests__/install-skill-routing.test.ts +1 -13
  125. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  126. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  127. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  128. package/src/__tests__/llm-resolver.test.ts +80 -12
  129. package/src/__tests__/llm-usage-store.test.ts +269 -4
  130. package/src/__tests__/log-export-routes.test.ts +89 -0
  131. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  132. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
  133. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  134. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  135. package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
  136. package/src/__tests__/migration-export-http.test.ts +33 -26
  137. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  138. package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
  139. package/src/__tests__/migration-import-commit-http.test.ts +66 -21
  140. package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
  141. package/src/__tests__/migration-import-from-url.test.ts +20 -6
  142. package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
  143. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  144. package/src/__tests__/migration-transport.test.ts +115 -23
  145. package/src/__tests__/migration-validate-http.test.ts +105 -80
  146. package/src/__tests__/migration-wizard.test.ts +133 -27
  147. package/src/__tests__/non-member-access-request.test.ts +1 -1
  148. package/src/__tests__/notification-guardian-path.test.ts +1 -1
  149. package/src/__tests__/oauth-store.test.ts +19 -0
  150. package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
  151. package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
  152. package/src/__tests__/pricing.test.ts +68 -4
  153. package/src/__tests__/process-message-background-slack.test.ts +331 -0
  154. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  155. package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
  156. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  157. package/src/__tests__/reaction-persistence.test.ts +9 -6
  158. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  159. package/src/__tests__/recording-handler.test.ts +64 -81
  160. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  161. package/src/__tests__/relay-server.test.ts +18 -13
  162. package/src/__tests__/require-fresh-approval.test.ts +13 -22
  163. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  164. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  165. package/src/__tests__/runtime-events-sse.test.ts +3 -12
  166. package/src/__tests__/search-skills-unified.test.ts +9 -15
  167. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  168. package/src/__tests__/secret-ingress-http.test.ts +0 -4
  169. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  170. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  171. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  172. package/src/__tests__/secret-response-routing.test.ts +29 -15
  173. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
  174. package/src/__tests__/secret-scanner.test.ts +2 -545
  175. package/src/__tests__/send-endpoint-busy.test.ts +9 -24
  176. package/src/__tests__/settings-routes.test.ts +1 -1
  177. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  178. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
  179. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
  180. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  181. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
  182. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  183. package/src/__tests__/slack-inbound-verification.test.ts +1 -62
  184. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  185. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  186. package/src/__tests__/subagent-notify-parent.test.ts +80 -83
  187. package/src/__tests__/system-prompt.test.ts +115 -13
  188. package/src/__tests__/terminal-tools.test.ts +0 -89
  189. package/src/__tests__/thread-backfill.test.ts +945 -31
  190. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
  191. package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
  192. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
  193. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
  194. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
  195. package/src/__tests__/tool-executor.test.ts +12 -19
  196. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  197. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  198. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  199. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  200. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
  201. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
  202. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  203. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  204. package/src/__tests__/usage-attribution.test.ts +247 -0
  205. package/src/__tests__/usage-cli.test.ts +143 -0
  206. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  207. package/src/__tests__/usage-routes.test.ts +150 -0
  208. package/src/__tests__/validation-results-screen.test.ts +39 -16
  209. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  210. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
  211. package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
  212. package/src/__tests__/voice-session-bridge.test.ts +5 -5
  213. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  214. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  215. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  216. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
  217. package/src/acp/index.ts +0 -15
  218. package/src/acp/session-manager.ts +37 -34
  219. package/src/agent/loop.ts +16 -1
  220. package/src/approvals/AGENTS.md +4 -0
  221. package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
  222. package/src/approvals/guardian-request-resolvers.ts +10 -2
  223. package/src/backup/__tests__/backup-worker.test.ts +36 -8
  224. package/src/backup/__tests__/paths.test.ts +2 -2
  225. package/src/backup/__tests__/restore.test.ts +45 -28
  226. package/src/backup/backup-worker.ts +36 -2
  227. package/src/backup/paths.ts +9 -6
  228. package/src/browser-session/events.ts +0 -9
  229. package/src/calls/call-store.ts +1 -34
  230. package/src/calls/guardian-question-copy.ts +0 -108
  231. package/src/calls/relay-server.ts +0 -24
  232. package/src/calls/twilio-rest.ts +0 -38
  233. package/src/calls/twilio-routes.ts +1 -1
  234. package/src/calls/voice-session-bridge.ts +7 -38
  235. package/src/channels/types.ts +1 -36
  236. package/src/cli/commands/__tests__/cache.test.ts +152 -5
  237. package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
  238. package/src/cli/commands/__tests__/trust.test.ts +21 -387
  239. package/src/cli/commands/backup.ts +4 -4
  240. package/src/cli/commands/cache-fs.ts +8 -0
  241. package/src/cli/commands/cache.ts +153 -82
  242. package/src/cli/commands/clients.ts +63 -5
  243. package/src/cli/commands/completions.ts +3 -3
  244. package/src/cli/commands/contacts.ts +231 -76
  245. package/src/cli/commands/keys.ts +4 -1
  246. package/src/cli/commands/memory-v2.ts +24 -52
  247. package/src/cli/commands/oauth/shared.ts +2 -29
  248. package/src/cli/commands/pending.ts +102 -0
  249. package/src/cli/commands/skills.ts +77 -35
  250. package/src/cli/commands/trust.ts +70 -430
  251. package/src/cli/commands/usage.ts +25 -16
  252. package/src/cli/lib/daemon-credential-client.ts +14 -0
  253. package/src/cli/program.ts +2 -0
  254. package/src/cli.ts +0 -21
  255. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  256. package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
  257. package/src/config/env-registry.ts +12 -2
  258. package/src/config/env.ts +3 -14
  259. package/src/config/feature-flag-registry.json +30 -30
  260. package/src/config/llm-callsite-catalog.ts +12 -0
  261. package/src/config/llm-context-resolution.ts +80 -0
  262. package/src/config/llm-resolver.ts +58 -22
  263. package/src/config/loader.ts +3 -3
  264. package/src/config/schema.ts +2 -158
  265. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
  266. package/src/config/schemas/call-site-catalog.ts +271 -0
  267. package/src/config/schemas/calls.ts +5 -5
  268. package/src/config/schemas/inference.ts +1 -1
  269. package/src/config/schemas/ingress.ts +1 -1
  270. package/src/config/schemas/llm.ts +31 -3
  271. package/src/config/schemas/memory-retrieval.ts +2 -2
  272. package/src/config/schemas/memory-v2.ts +9 -0
  273. package/src/config/schemas/security.ts +1 -42
  274. package/src/config/schemas/services.ts +6 -6
  275. package/src/config/schemas/skills.ts +5 -5
  276. package/src/config/schemas/tts.ts +1 -1
  277. package/src/config/seed-inference-profiles.ts +117 -0
  278. package/src/config/skills.ts +0 -90
  279. package/src/config/types.ts +3 -6
  280. package/src/contacts/contact-store.ts +0 -17
  281. package/src/contacts/contacts-write.ts +1 -105
  282. package/src/context/window-manager.ts +44 -5
  283. package/src/credential-execution/process-manager.ts +34 -10
  284. package/src/credential-health/credential-health-service.ts +21 -16
  285. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
  286. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
  287. package/src/daemon/connection-policy.ts +1 -26
  288. package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
  289. package/src/daemon/conversation-agent-loop.ts +277 -36
  290. package/src/daemon/conversation-history.ts +8 -8
  291. package/src/daemon/conversation-launch.ts +20 -135
  292. package/src/daemon/conversation-lifecycle.ts +1 -1
  293. package/src/daemon/conversation-messaging.ts +1 -0
  294. package/src/daemon/conversation-process.ts +83 -163
  295. package/src/daemon/conversation-runtime-assembly.ts +219 -76
  296. package/src/daemon/conversation-slash.ts +47 -5
  297. package/src/daemon/conversation-store.ts +7 -31
  298. package/src/daemon/conversation-surfaces.ts +22 -28
  299. package/src/daemon/conversation-tool-setup.ts +3 -33
  300. package/src/daemon/conversation-usage.ts +36 -0
  301. package/src/daemon/conversation.ts +117 -233
  302. package/src/daemon/daemon-control.ts +3 -71
  303. package/src/daemon/daemon-skill-host.ts +8 -11
  304. package/src/daemon/dictation-profile-store.ts +2 -26
  305. package/src/daemon/first-greeting.ts +44 -156
  306. package/src/daemon/handlers/config-channels.ts +12 -12
  307. package/src/daemon/handlers/config-ingress.ts +4 -165
  308. package/src/daemon/handlers/config-model.ts +1 -1
  309. package/src/daemon/handlers/config-voice.ts +0 -42
  310. package/src/daemon/handlers/conversations.ts +11 -190
  311. package/src/daemon/handlers/recording.ts +26 -158
  312. package/src/daemon/handlers/shared.ts +23 -71
  313. package/src/daemon/handlers/skills.ts +42 -93
  314. package/src/daemon/host-bash-proxy.ts +67 -45
  315. package/src/daemon/host-browser-proxy.ts +65 -27
  316. package/src/daemon/host-cu-proxy.ts +40 -39
  317. package/src/daemon/host-file-proxy.ts +58 -37
  318. package/src/daemon/host-transfer-proxy.ts +84 -46
  319. package/src/daemon/lifecycle.ts +49 -15
  320. package/src/daemon/message-types/conversations.ts +7 -0
  321. package/src/daemon/message-types/host-bash.ts +1 -0
  322. package/src/daemon/message-types/host-cu.ts +1 -0
  323. package/src/daemon/message-types/host-file.ts +1 -0
  324. package/src/daemon/message-types/host-transfer.ts +1 -0
  325. package/src/daemon/message-types/messages.ts +10 -9
  326. package/src/daemon/message-types/workspace.ts +1 -1
  327. package/src/daemon/process-message.ts +102 -239
  328. package/src/daemon/server.ts +13 -462
  329. package/src/daemon/shutdown-handlers.ts +2 -2
  330. package/src/daemon/tool-side-effects.ts +125 -107
  331. package/src/daemon/trust-context.ts +13 -0
  332. package/src/daemon/wake-target-adapter.ts +4 -9
  333. package/src/events/domain-events.ts +0 -8
  334. package/src/events/tool-audit-listener.ts +3 -1
  335. package/src/events/tool-domain-event-publisher.ts +0 -10
  336. package/src/events/tool-metrics-listener.ts +0 -17
  337. package/src/events/tool-trace-listener.ts +0 -14
  338. package/src/filing/filing-service.ts +13 -1
  339. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
  340. package/src/heartbeat/heartbeat-service.ts +23 -5
  341. package/src/home/__tests__/feed-writer.test.ts +0 -4
  342. package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
  343. package/src/home/feed-writer.ts +1 -2
  344. package/src/home/relationship-state-writer.ts +16 -3
  345. package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
  346. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
  347. package/src/ipc/assistant-server.ts +3 -10
  348. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
  349. package/src/ipc/routes/route-adapter.ts +1 -1
  350. package/src/ipc/routes/trust-rules.test.ts +0 -95
  351. package/src/ipc/skill-ipc-types.ts +41 -0
  352. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
  353. package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
  354. package/src/ipc/skill-routes/events.ts +12 -23
  355. package/src/ipc/skill-routes/identity.ts +4 -17
  356. package/src/ipc/skill-routes/index.ts +1 -1
  357. package/src/ipc/skill-server.ts +6 -39
  358. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
  359. package/src/live-voice/protocol.ts +4 -13
  360. package/src/mcp/manager.ts +0 -5
  361. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  362. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  363. package/src/memory/app-git-service.ts +0 -32
  364. package/src/memory/app-store.ts +154 -0
  365. package/src/memory/attachments-store.ts +6 -0
  366. package/src/memory/context-search/sources/memory-v2.ts +578 -0
  367. package/src/memory/context-search/sources/memory.ts +5 -0
  368. package/src/memory/context-search/sources/pkb.ts +10 -1
  369. package/src/memory/context-search/sources/workspace.ts +3 -2
  370. package/src/memory/conversation-crud.ts +29 -4
  371. package/src/memory/conversation-disk-view.ts +1 -5
  372. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  373. package/src/memory/db-connection.ts +62 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +3 -21
  376. package/src/memory/embedding-gemini.ts +0 -2
  377. package/src/memory/embedding-local.ts +6 -6
  378. package/src/memory/embedding-ollama.ts +6 -6
  379. package/src/memory/embedding-openai.ts +6 -6
  380. package/src/memory/embedding-types.ts +21 -0
  381. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
  382. package/src/memory/graph/conversation-graph-memory.ts +35 -13
  383. package/src/memory/graph/injection.test.ts +2 -2
  384. package/src/memory/graph/injection.ts +1 -1
  385. package/src/memory/guardian-action-store.ts +0 -83
  386. package/src/memory/guardian-approvals.ts +0 -48
  387. package/src/memory/indexer.ts +1 -15
  388. package/src/memory/job-handlers/conversation-starters.ts +36 -53
  389. package/src/memory/job-utils.ts +0 -6
  390. package/src/memory/jobs-store.ts +0 -1
  391. package/src/memory/jobs-worker.ts +2 -16
  392. package/src/memory/llm-request-log-store.ts +0 -41
  393. package/src/memory/llm-usage-store.ts +129 -43
  394. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  395. package/src/memory/migrations/233-document-conversations.ts +54 -0
  396. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  397. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  398. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  399. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  400. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  401. package/src/memory/migrations/index.ts +14 -0
  402. package/src/memory/migrations/registry.ts +24 -0
  403. package/src/memory/raw-query.ts +2 -68
  404. package/src/memory/schema/conversations.ts +7 -0
  405. package/src/memory/schema/infrastructure.ts +25 -0
  406. package/src/memory/search/semantic.ts +5 -16
  407. package/src/memory/tool-usage-store.ts +2 -0
  408. package/src/memory/usage-buckets.ts +40 -1
  409. package/src/memory/usage-grouped-buckets.ts +127 -0
  410. package/src/memory/v2/__tests__/activation.test.ts +289 -90
  411. package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
  412. package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
  413. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  414. package/src/memory/v2/__tests__/injection.test.ts +384 -15
  415. package/src/memory/v2/__tests__/migration.test.ts +64 -36
  416. package/src/memory/v2/__tests__/page-store.test.ts +191 -8
  417. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  418. package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
  419. package/src/memory/v2/__tests__/static-context.test.ts +153 -0
  420. package/src/memory/v2/activation.ts +168 -97
  421. package/src/memory/v2/backfill-jobs.ts +15 -100
  422. package/src/memory/v2/consolidation-job.ts +14 -12
  423. package/src/memory/v2/edge-index.ts +191 -0
  424. package/src/memory/v2/injection.ts +182 -58
  425. package/src/memory/v2/migration.ts +57 -64
  426. package/src/memory/v2/now-text.ts +2 -3
  427. package/src/memory/v2/page-store.ts +168 -31
  428. package/src/memory/v2/prompts/consolidation.ts +118 -42
  429. package/src/memory/v2/prompts/sweep.ts +3 -3
  430. package/src/memory/v2/skill-store.ts +55 -7
  431. package/src/memory/v2/static-context.ts +62 -0
  432. package/src/memory/v2/types.ts +10 -20
  433. package/src/memory/validation.ts +0 -11
  434. package/src/messaging/draft-store.ts +0 -6
  435. package/src/messaging/provider-types.ts +8 -0
  436. package/src/messaging/provider.ts +7 -0
  437. package/src/messaging/providers/gmail/client.ts +1 -121
  438. package/src/messaging/providers/outlook/client.ts +0 -73
  439. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  440. package/src/messaging/providers/slack/adapter.ts +122 -21
  441. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  442. package/src/messaging/providers/slack/backfill.ts +89 -11
  443. package/src/messaging/providers/slack/client.ts +10 -124
  444. package/src/messaging/providers/slack/message-metadata.ts +12 -2
  445. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  446. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  447. package/src/messaging/providers/slack/types.ts +1 -0
  448. package/src/oauth/connection-resolver.test.ts +8 -0
  449. package/src/oauth/connection-resolver.ts +8 -16
  450. package/src/oauth/credential-token-resolver.ts +97 -0
  451. package/src/oauth/manual-token-connection.ts +30 -34
  452. package/src/oauth/oauth-store.ts +6 -4
  453. package/src/outbound-proxy/certs.ts +0 -7
  454. package/src/outbound-proxy/config.ts +0 -74
  455. package/src/outbound-proxy/health.ts +0 -44
  456. package/src/outbound-proxy/index.ts +0 -22
  457. package/src/permissions/approval-provenance.test.ts +184 -0
  458. package/src/permissions/approval-provenance.ts +70 -0
  459. package/src/permissions/checker.ts +4 -1
  460. package/src/permissions/gateway-threshold-reader.ts +4 -1
  461. package/src/permissions/prompter.ts +9 -2
  462. package/src/permissions/secret-prompter.ts +21 -48
  463. package/src/permissions/types.ts +33 -0
  464. package/src/permissions/workspace-policy.ts +0 -5
  465. package/src/platform/sync-identity.ts +0 -8
  466. package/src/plugins/defaults/injectors.ts +69 -2
  467. package/src/plugins/defaults/overflow-reduce.ts +3 -2
  468. package/src/plugins/types.ts +8 -0
  469. package/src/prompts/system-prompt.ts +34 -70
  470. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  471. package/src/prompts/update-bulletin-job.ts +2 -0
  472. package/src/providers/__tests__/retry-callsite.test.ts +138 -1
  473. package/src/providers/anthropic/client.ts +72 -33
  474. package/src/providers/call-site-routing.ts +42 -3
  475. package/src/providers/gemini/client.ts +18 -2
  476. package/src/providers/managed-proxy/context.ts +0 -5
  477. package/src/providers/model-catalog.ts +105 -19
  478. package/src/providers/openai/chat-completions-provider.ts +6 -0
  479. package/src/providers/openai/responses-provider.ts +7 -1
  480. package/src/providers/provider-send-message.ts +45 -2
  481. package/src/providers/ratelimit.ts +7 -2
  482. package/src/providers/registry.ts +14 -9
  483. package/src/providers/retry.ts +96 -8
  484. package/src/providers/types.ts +13 -0
  485. package/src/providers/usage-tracking.ts +96 -0
  486. package/src/runtime/AGENTS.md +10 -6
  487. package/src/runtime/__tests__/agent-wake.test.ts +89 -0
  488. package/src/runtime/agent-wake.ts +39 -2
  489. package/src/runtime/assistant-event-hub.ts +541 -45
  490. package/src/runtime/assistant-event.ts +1 -6
  491. package/src/runtime/auth/context.ts +0 -9
  492. package/src/runtime/auth/middleware.ts +1 -1
  493. package/src/runtime/auth/route-policy.ts +11 -9
  494. package/src/runtime/auth/token-service.ts +0 -11
  495. package/src/runtime/channel-approvals.ts +6 -2
  496. package/src/runtime/channel-verification-service.ts +3 -5
  497. package/src/runtime/http-errors.ts +0 -34
  498. package/src/runtime/http-router.ts +6 -3
  499. package/src/runtime/http-server.ts +22 -82
  500. package/src/runtime/http-types.ts +5 -0
  501. package/src/runtime/interactive-ui.ts +0 -1
  502. package/src/runtime/middleware/auth.ts +0 -20
  503. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  504. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  505. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  506. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  507. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  508. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  509. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
  510. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  511. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
  512. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
  513. package/src/runtime/migrations/migration-transport.ts +46 -13
  514. package/src/runtime/migrations/migration-wizard.ts +2 -2
  515. package/src/runtime/migrations/origin-mode.ts +40 -0
  516. package/src/runtime/migrations/vbundle-builder.ts +133 -79
  517. package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
  518. package/src/runtime/migrations/vbundle-importer.ts +7 -7
  519. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  520. package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
  521. package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
  522. package/src/runtime/migrations/vbundle-validator.ts +214 -41
  523. package/src/runtime/pending-interactions.ts +13 -4
  524. package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
  525. package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
  526. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
  527. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  528. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  529. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  530. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  531. package/src/runtime/routes/acp-routes.test.ts +0 -3
  532. package/src/runtime/routes/acp-routes.ts +3 -7
  533. package/src/runtime/routes/app-management-routes.ts +18 -9
  534. package/src/runtime/routes/approval-routes.ts +55 -14
  535. package/src/runtime/routes/avatar-routes.ts +3 -5
  536. package/src/runtime/routes/browser-routes.ts +1 -15
  537. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  538. package/src/runtime/routes/channel-readiness-routes.ts +3 -7
  539. package/src/runtime/routes/channel-route-shared.ts +2 -28
  540. package/src/runtime/routes/client-routes.ts +45 -12
  541. package/src/runtime/routes/consolidation-routes.ts +115 -0
  542. package/src/runtime/routes/conversation-list-routes.ts +12 -29
  543. package/src/runtime/routes/conversation-management-routes.ts +14 -51
  544. package/src/runtime/routes/conversation-query-routes.ts +120 -8
  545. package/src/runtime/routes/conversation-routes.ts +44 -528
  546. package/src/runtime/routes/conversation-starter-routes.ts +19 -40
  547. package/src/runtime/routes/documents-routes.ts +53 -18
  548. package/src/runtime/routes/events-routes.ts +59 -91
  549. package/src/runtime/routes/filing-routes.ts +18 -1
  550. package/src/runtime/routes/guardian-action-routes.ts +4 -9
  551. package/src/runtime/routes/host-bash-routes.ts +3 -2
  552. package/src/runtime/routes/host-browser-routes.ts +9 -33
  553. package/src/runtime/routes/host-cu-routes.ts +6 -1
  554. package/src/runtime/routes/host-file-routes.ts +3 -2
  555. package/src/runtime/routes/host-transfer-routes.ts +11 -15
  556. package/src/runtime/routes/identity-routes.ts +78 -6
  557. package/src/runtime/routes/inbound-message-handler.ts +580 -137
  558. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
  559. package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
  560. package/src/runtime/routes/index.ts +4 -0
  561. package/src/runtime/routes/integrations/slack/channel.ts +0 -24
  562. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  563. package/src/runtime/routes/memory-v2-routes.ts +10 -15
  564. package/src/runtime/routes/migration-routes.ts +188 -31
  565. package/src/runtime/routes/playground/guard.ts +1 -1
  566. package/src/runtime/routes/playground/index.ts +0 -2
  567. package/src/runtime/routes/recording-routes.ts +4 -24
  568. package/src/runtime/routes/rename-conversation-routes.ts +2 -6
  569. package/src/runtime/routes/schedule-routes.ts +3 -6
  570. package/src/runtime/routes/secret-routes.ts +87 -18
  571. package/src/runtime/routes/settings-routes.ts +29 -28
  572. package/src/runtime/routes/skills-routes.ts +12 -31
  573. package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
  574. package/src/runtime/routes/task-routes.ts +6 -6
  575. package/src/runtime/routes/trust-rules-routes.ts +3 -94
  576. package/src/runtime/routes/types.ts +4 -4
  577. package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
  578. package/src/runtime/routes/usage-routes.ts +87 -10
  579. package/src/runtime/routes/user-routes.ts +17 -31
  580. package/src/runtime/routes/work-items-routes.ts +1 -4
  581. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
  582. package/src/runtime/services/analyze-conversation.ts +7 -17
  583. package/src/runtime/services/conversation-serializer.ts +2 -4
  584. package/src/runtime/verification-outbound-actions.ts +1 -1
  585. package/src/runtime/verification-rate-limiter.ts +1 -1
  586. package/src/schedule/schedule-store.ts +0 -16
  587. package/src/security/secret-scanner.ts +14 -547
  588. package/src/security/secure-keys.ts +31 -11
  589. package/src/security/token-manager.ts +7 -3
  590. package/src/signals/cancel.ts +16 -25
  591. package/src/signals/conversation-undo.ts +2 -27
  592. package/src/signals/emit-event.ts +1 -2
  593. package/src/signals/user-message.ts +108 -22
  594. package/src/skills/catalog-install.ts +1 -0
  595. package/src/skills/clawhub.ts +2 -2
  596. package/src/skills/inline-command-runner.ts +1 -7
  597. package/src/subagent/manager.ts +67 -84
  598. package/src/tasks/task-store.ts +1 -28
  599. package/src/telemetry/types.ts +6 -0
  600. package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
  601. package/src/telemetry/usage-telemetry-reporter.ts +3 -5
  602. package/src/tools/acp/spawn.test.ts +1 -2
  603. package/src/tools/acp/steer.test.ts +1 -2
  604. package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
  605. package/src/tools/browser/browser-execution.ts +31 -147
  606. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
  607. package/src/tools/browser/cdp-client/factory.ts +48 -76
  608. package/src/tools/browser/cdp-client/index.ts +1 -14
  609. package/src/tools/executor.ts +44 -31
  610. package/src/tools/host-filesystem/edit.ts +3 -2
  611. package/src/tools/host-filesystem/read.ts +3 -2
  612. package/src/tools/host-filesystem/transfer.test.ts +45 -42
  613. package/src/tools/host-filesystem/transfer.ts +4 -3
  614. package/src/tools/host-filesystem/write.ts +3 -2
  615. package/src/tools/host-terminal/host-shell.ts +4 -3
  616. package/src/tools/network/script-proxy/index.ts +1 -10
  617. package/src/tools/permission-checker.ts +66 -1
  618. package/src/tools/skills/sandbox-runner.ts +1 -6
  619. package/src/tools/skills/skill-tool-factory.ts +32 -0
  620. package/src/tools/terminal/safe-env.ts +1 -0
  621. package/src/tools/terminal/shell.ts +2 -78
  622. package/src/tools/types.ts +12 -39
  623. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  624. package/src/tts/provider-catalog.ts +1 -1
  625. package/src/usage/actors.ts +2 -1
  626. package/src/usage/attribution.ts +185 -0
  627. package/src/usage/pricing.ts +166 -0
  628. package/src/usage/types.ts +14 -0
  629. package/src/util/json.ts +13 -0
  630. package/src/util/logger.ts +3 -3
  631. package/src/util/pricing.ts +50 -3
  632. package/src/work-items/work-item-runner.ts +15 -42
  633. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
  634. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
  635. package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
  636. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
  637. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  638. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  639. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  640. package/src/workspace/migrations/registry.ts +8 -0
  641. package/src/workspace/provider-commit-message-generator.ts +3 -3
  642. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  643. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  644. package/src/__tests__/secret-detection-handler.test.ts +0 -67
  645. package/src/__tests__/secret-scanner-executor.test.ts +0 -450
  646. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  647. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  648. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  649. package/src/context/__tests__/microcompact.test.ts +0 -805
  650. package/src/context/microcompact.ts +0 -443
  651. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  652. package/src/events/tool-notification-listener.ts +0 -17
  653. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
  654. package/src/memory/v2/__tests__/edges.test.ts +0 -435
  655. package/src/memory/v2/edges.ts +0 -217
  656. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
  657. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  658. package/src/runtime/__tests__/client-registry.test.ts +0 -271
  659. package/src/runtime/chrome-extension-registry.ts +0 -368
  660. package/src/runtime/client-registry.ts +0 -254
  661. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
  662. package/src/tools/secret-detection-handler.ts +0 -269
  663. package/src/tools/terminal/backends/native.ts +0 -327
  664. package/src/tools/terminal/backends/types.ts +0 -37
  665. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  666. package/src/tools/terminal/sandbox.ts +0 -40
@@ -7,12 +7,19 @@
7
7
  * registry entry instead of another if/else branch.
8
8
  */
9
9
 
10
+ import { isAbsolute, resolve, sep } from "node:path";
11
+
10
12
  import { generateAppIcon } from "../media/app-icon-generator.js";
13
+ import { addAppConversationId } from "../memory/app-store.js";
14
+ import { invalidateEdgeIndex } from "../memory/v2/edge-index.js";
15
+ import { getConceptsDir } from "../memory/v2/page-store.js";
16
+ import { broadcastMessage } from "../runtime/assistant-event-hub.js";
11
17
  import { findActiveSession } from "../runtime/channel-verification-service.js";
12
18
  import { deliverVerificationSlack } from "../runtime/verification-outbound-actions.js";
13
19
  import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
14
20
  import type { ToolExecutionResult } from "../tools/types.js";
15
21
  import { getLogger } from "../util/logger.js";
22
+ import { getWorkspaceDir } from "../util/platform.js";
16
23
  import { ensureAppSourceWatcher } from "./app-source-watcher.js";
17
24
  import { refreshSurfacesForApp } from "./conversation-surfaces.js";
18
25
  import type { ToolSetupContext } from "./conversation-tool-setup.js";
@@ -25,7 +32,6 @@ const log = getLogger("tool-side-effects");
25
32
 
26
33
  export interface SideEffectContext {
27
34
  ctx: ToolSetupContext;
28
- broadcastToAllClients?: (msg: ServerMessage) => void;
29
35
  }
30
36
 
31
37
  export type PostExecutionHook = (
@@ -50,11 +56,10 @@ export type PostExecutionHook = (
50
56
  function notifyAppChanged(
51
57
  ctx: ToolSetupContext,
52
58
  appId: string,
53
- broadcastToAllClients: ((msg: ServerMessage) => void) | undefined,
54
59
  opts?: { fileChange?: boolean; status?: string },
55
60
  ): void {
56
61
  refreshSurfacesForApp(ctx, appId, opts);
57
- broadcastToAllClients?.({ type: "app_files_changed", appId });
62
+ broadcastMessage({ type: "app_files_changed", appId });
58
63
  void updatePublishedAppDeployment(appId);
59
64
  }
60
65
 
@@ -79,121 +84,106 @@ function registerHook(
79
84
  // Broadcast app_files_changed when a new app is created so clients
80
85
  // (e.g. macOS "Things" sidebar) refresh their app list immediately.
81
86
  // Also kicks off async icon generation via Gemini.
82
- registerHook(
83
- "app_create",
84
- (_name, _input, result, { ctx, broadcastToAllClients }) => {
85
- try {
86
- const parsed = JSON.parse(result.content) as {
87
- id?: string;
88
- name?: string;
89
- description?: string;
90
- };
91
- if (parsed.id) {
92
- // The apps directory may have just been created — ensure the
93
- // filesystem watcher is running so subsequent file edits
94
- // trigger live reload.
95
- ensureAppSourceWatcher();
87
+ registerHook("app_create", (_name, _input, result, { ctx }) => {
88
+ try {
89
+ const parsed = JSON.parse(result.content) as {
90
+ id?: string;
91
+ name?: string;
92
+ description?: string;
93
+ };
94
+ if (parsed.id) {
95
+ try {
96
+ addAppConversationId(parsed.id, ctx.conversationId);
97
+ } catch (err) {
98
+ log.warn(
99
+ { err, appId: parsed.id },
100
+ "Failed to track conversation ID on app_create",
101
+ );
102
+ }
103
+
104
+ ensureAppSourceWatcher();
96
105
 
97
- notifyAppChanged(ctx, parsed.id, broadcastToAllClients);
106
+ notifyAppChanged(ctx, parsed.id);
98
107
 
99
- // Fire-and-forget: generate an app icon in the background.
100
- // When complete, broadcast again so clients pick up the new icon.
101
- if (parsed.name) {
102
- void generateAppIcon(parsed.id, parsed.name, parsed.description)
103
- .then(() => {
104
- broadcastToAllClients?.({
105
- type: "app_files_changed",
106
- appId: parsed.id!,
107
- });
108
- })
109
- .catch((err) => {
110
- log.warn(
111
- { err, appId: parsed.id },
112
- "Background icon generation failed",
113
- );
108
+ if (parsed.name) {
109
+ void generateAppIcon(parsed.id, parsed.name, parsed.description)
110
+ .then(() => {
111
+ broadcastMessage({
112
+ type: "app_files_changed",
113
+ appId: parsed.id!,
114
114
  });
115
- }
115
+ })
116
+ .catch((err) => {
117
+ log.warn(
118
+ { err, appId: parsed.id },
119
+ "Background icon generation failed",
120
+ );
121
+ });
116
122
  }
117
- } catch {
118
- // Result wasn't valid JSON — skip the broadcast.
119
123
  }
120
- },
121
- );
124
+ } catch {
125
+ // Result wasn't valid JSON — skip the broadcast.
126
+ }
127
+ });
122
128
 
123
- // Broadcast app_files_changed when an icon is (re)generated so clients refresh.
124
- registerHook(
125
- "app_generate_icon",
126
- (_name, input, _result, { broadcastToAllClients }) => {
127
- const appId = input.app_id as string | undefined;
128
- if (appId) {
129
- broadcastToAllClients?.({ type: "app_files_changed", appId });
130
- }
131
- },
132
- );
129
+ registerHook("app_generate_icon", (_name, input) => {
130
+ const appId = input.app_id as string | undefined;
131
+ if (appId) {
132
+ broadcastMessage({ type: "app_files_changed", appId });
133
+ }
134
+ });
133
135
 
134
- // Broadcast app_files_changed when an app is deleted so clients remove it
135
- // from their cached app lists.
136
- registerHook(
137
- "app_delete",
138
- (_name, input, _result, { broadcastToAllClients }) => {
139
- const appId = input.app_id as string | undefined;
140
- if (appId) {
141
- broadcastToAllClients?.({ type: "app_files_changed", appId });
142
- }
143
- },
144
- );
136
+ registerHook("app_delete", (_name, input) => {
137
+ const appId = input.app_id as string | undefined;
138
+ if (appId) {
139
+ broadcastMessage({ type: "app_files_changed", appId });
140
+ }
141
+ });
145
142
 
146
- // Trigger surface refresh + broadcast when an app is refreshed.
147
- registerHook(
148
- "app_refresh",
149
- (_name, input, _result, { ctx, broadcastToAllClients }) => {
150
- const appId = input.app_id as string | undefined;
151
- if (!appId) return;
152
- notifyAppChanged(ctx, appId, broadcastToAllClients, { fileChange: true });
153
- },
154
- );
143
+ registerHook("app_refresh", (_name, input, _result, { ctx }) => {
144
+ const appId = input.app_id as string | undefined;
145
+ if (!appId) return;
146
+ try {
147
+ addAppConversationId(appId, ctx.conversationId);
148
+ } catch (err) {
149
+ log.warn({ err, appId }, "Failed to track conversation ID on app_refresh");
150
+ }
151
+ notifyAppChanged(ctx, appId, { fileChange: true });
152
+ });
155
153
 
156
- // Broadcast voice config changes to all connected clients so every window
157
- // picks up the updated UserDefaults value immediately.
158
- registerHook(
159
- "voice_config_update",
160
- (_name, input, _result, { broadcastToAllClients }) => {
161
- const setting = input.setting as string | undefined;
162
- if (!setting) return;
154
+ registerHook("voice_config_update", (_name, input) => {
155
+ const setting = input.setting as string | undefined;
156
+ if (!setting) return;
163
157
 
164
- const SETTING_TO_KEY: Record<string, string> = {
165
- activation_key: "pttActivationKey",
166
- tts_voice_id: "ttsVoiceId",
167
- tts_provider: "ttsProvider",
168
- conversation_timeout: "voiceConversationTimeoutSeconds",
169
- fish_audio_reference_id: "fishAudioReferenceId",
170
- };
171
- const key = SETTING_TO_KEY[setting];
172
- if (!key) return;
158
+ const SETTING_TO_KEY: Record<string, string> = {
159
+ activation_key: "pttActivationKey",
160
+ tts_voice_id: "ttsVoiceId",
161
+ tts_provider: "ttsProvider",
162
+ conversation_timeout: "voiceConversationTimeoutSeconds",
163
+ fish_audio_reference_id: "fishAudioReferenceId",
164
+ };
165
+ const key = SETTING_TO_KEY[setting];
166
+ if (!key) return;
173
167
 
174
- // Coerce the value to the correct type before broadcasting, matching
175
- // the validation logic in the tool's execute method.
176
- const raw = input.value;
177
- let coerced: string | boolean | number = raw as string;
178
- if (setting === "conversation_timeout") {
179
- coerced = typeof raw === "number" ? raw : Number(raw);
180
- } else if (setting === "tts_voice_id" && typeof raw === "string") {
181
- coerced = raw.trim();
182
- } else if (
183
- setting === "fish_audio_reference_id" &&
184
- typeof raw === "string"
185
- ) {
186
- coerced = raw.trim();
187
- } else if (setting === "tts_provider" && typeof raw === "string") {
188
- coerced = raw.trim();
189
- }
190
- broadcastToAllClients?.({
191
- type: "client_settings_update",
192
- key,
193
- value: coerced,
194
- } as unknown as ServerMessage);
195
- },
196
- );
168
+ // Coerce the value to the correct type before broadcasting, matching
169
+ // the validation logic in the tool's execute method.
170
+ const raw = input.value;
171
+ let coerced: string | boolean | number = raw as string;
172
+ if (setting === "conversation_timeout") {
173
+ coerced = typeof raw === "number" ? raw : Number(raw);
174
+ } else if (setting === "tts_voice_id" && typeof raw === "string") {
175
+ coerced = raw.trim();
176
+ } else if (setting === "fish_audio_reference_id" && typeof raw === "string") {
177
+ coerced = raw.trim();
178
+ } else if (setting === "tts_provider" && typeof raw === "string") {
179
+ coerced = raw.trim();
180
+ }
181
+ broadcastMessage({
182
+ type: "client_settings_update",
183
+ key,
184
+ value: coerced,
185
+ } as unknown as ServerMessage);
186
+ });
197
187
 
198
188
  // Dispatch pending Slack DM delivery when a CLI verification command
199
189
  // completes. The CLI subprocess is sandboxed and cannot reach the
@@ -255,6 +245,34 @@ registerHook("bash", (_name, input, result) => {
255
245
  }
256
246
  });
257
247
 
248
+ // Invalidate the in-memory v2 edge index when the LLM writes or edits a file
249
+ // under `memory/concepts/`. The page-store invalidates on programmatic writes;
250
+ // this hook covers consolidation, where the LLM edits page frontmatter through
251
+ // the file tools rather than through `writePage`.
252
+ function invalidateEdgeIndexIfConceptPage(
253
+ input: Record<string, unknown>,
254
+ ): void {
255
+ const rawPath = input.path;
256
+ if (typeof rawPath !== "string" || rawPath.length === 0) return;
257
+ const workspaceDir = getWorkspaceDir();
258
+ const conceptsRoot = getConceptsDir(workspaceDir);
259
+ const absPath = isAbsolute(rawPath)
260
+ ? resolve(rawPath)
261
+ : resolve(workspaceDir, rawPath);
262
+ const rootWithSep = conceptsRoot.endsWith(sep)
263
+ ? conceptsRoot
264
+ : conceptsRoot + sep;
265
+ if (absPath.startsWith(rootWithSep)) {
266
+ invalidateEdgeIndex(workspaceDir);
267
+ }
268
+ }
269
+ registerHook("file_write", (_name, input) =>
270
+ invalidateEdgeIndexIfConceptPage(input),
271
+ );
272
+ registerHook("file_edit", (_name, input) =>
273
+ invalidateEdgeIndexIfConceptPage(input),
274
+ );
275
+
258
276
  // ── Runner ───────────────────────────────────────────────────────────
259
277
 
260
278
  /**
@@ -30,3 +30,16 @@ export interface TrustContext {
30
30
  /** Chat/conversation ID the requester is interacting through. */
31
31
  requesterChatId?: string;
32
32
  }
33
+
34
+ /**
35
+ * Trust context used by internal background jobs (memory consolidation,
36
+ * update bulletin, scheduled tasks) when invoking the agent loop without
37
+ * an inbound actor identity. The assistant is the guardian over its own
38
+ * internal state, so self-maintenance flows clear the side-effect
39
+ * approval gate. Inbound message conversations resolve trust per-actor
40
+ * via `resolveTrustContext()` and must not use this constant.
41
+ */
42
+ export const INTERNAL_GUARDIAN_TRUST_CONTEXT = {
43
+ sourceChannel: "vellum",
44
+ trustClass: "guardian",
45
+ } as const satisfies TrustContext;
@@ -15,6 +15,7 @@ import {
15
15
  } from "../memory/conversation-crud.js";
16
16
  import { syncMessageToDisk } from "../memory/conversation-disk-view.js";
17
17
  import type { WakeTarget } from "../runtime/agent-wake.js";
18
+ import { broadcastMessage } from "../runtime/assistant-event-hub.js";
18
19
  import { getLogger } from "../util/logger.js";
19
20
  import type { Conversation } from "./conversation.js";
20
21
  import type { ServerMessage } from "./message-protocol.js";
@@ -152,10 +153,7 @@ export function conversationToWakeTarget(
152
153
  conversation.messages.push(msg);
153
154
  },
154
155
  onWakeProducedOutput: (source, hint, surfaceId) => {
155
- const emit =
156
- conversation.broadcastToAllClients ??
157
- conversation.sendToClient.bind(conversation);
158
- emit({
156
+ broadcastMessage({
159
157
  type: "ui_surface_show",
160
158
  conversationId: conversation.conversationId,
161
159
  surfaceId,
@@ -174,16 +172,13 @@ export function conversationToWakeTarget(
174
172
  conversation.conversationId,
175
173
  );
176
174
  if (!frame) return;
177
- if (conversation.broadcastToAllClients) {
178
- conversation.broadcastToAllClients(frame);
179
- } else {
180
- conversation.sendToClient(frame);
181
- }
175
+ broadcastMessage(frame);
182
176
  },
183
177
  isProcessing: () => conversation.isProcessing(),
184
178
  markProcessing: (on) => {
185
179
  conversation.processing = on;
186
180
  },
181
+ setTrustContext: (ctx) => conversation.setTrustContext(ctx),
187
182
  persistTailMessage: async (message) => {
188
183
  const turnChannelCtx = conversation.getTurnChannelContext();
189
184
  const turnInterfaceCtx = conversation.getTurnInterfaceContext();
@@ -21,14 +21,6 @@ export interface ToolDomainEvents {
21
21
  riskLevel: string;
22
22
  decidedAtMs: number;
23
23
  };
24
- "tool.secret.detected": {
25
- conversationId: string;
26
- requestId?: string;
27
- toolName: string;
28
- action: "redact" | "warn" | "block" | "prompt";
29
- matches: Array<{ type: string; redactedValue: string }>;
30
- detectedAtMs: number;
31
- };
32
24
  "tool.execution.finished": {
33
25
  conversationId: string;
34
26
  requestId?: string;
@@ -43,6 +43,7 @@ function toInvocationRecord(
43
43
  result: event.result.content.slice(0, RESULT_PREVIEW_LIMIT),
44
44
  decision: event.decision,
45
45
  riskLevel: event.riskLevel,
46
+ matchedTrustRuleId: event.matchedTrustRuleId,
46
47
  durationMs: event.durationMs,
47
48
  };
48
49
  case "error":
@@ -53,6 +54,7 @@ function toInvocationRecord(
53
54
  result: `error: ${event.errorMessage}`,
54
55
  decision: "error",
55
56
  riskLevel: event.riskLevel,
57
+ matchedTrustRuleId: event.matchedTrustRuleId,
56
58
  durationMs: event.durationMs,
57
59
  };
58
60
  case "permission_denied":
@@ -63,11 +65,11 @@ function toInvocationRecord(
63
65
  result: formatDeniedResult(event.reason),
64
66
  decision: "denied",
65
67
  riskLevel: event.riskLevel,
68
+ matchedTrustRuleId: event.matchedTrustRuleId,
66
69
  durationMs: event.durationMs,
67
70
  };
68
71
  case "start":
69
72
  case "permission_prompt":
70
- case "secret_detected":
71
73
  return null;
72
74
  }
73
75
  }
@@ -85,16 +85,6 @@ export function createToolDomainEventPublisher(
85
85
  failedAtMs: Date.now(),
86
86
  });
87
87
  break;
88
- case "secret_detected":
89
- await eventBus.emit("tool.secret.detected", {
90
- conversationId: event.conversationId,
91
- requestId: event.requestId,
92
- toolName: event.toolName,
93
- action: event.action,
94
- matches: event.matches,
95
- detectedAtMs: event.detectedAtMs,
96
- });
97
- break;
98
88
  }
99
89
  };
100
90
  }
@@ -69,23 +69,6 @@ export function registerToolMetricsLoggingListener(
69
69
  }
70
70
  return;
71
71
  }
72
- case "tool.secret.detected": {
73
- const types = [
74
- ...new Set(event.payload.matches.map((match) => match.type)),
75
- ];
76
- logger.warn(
77
- {
78
- toolName: event.payload.toolName,
79
- matchCount: event.payload.matches.length,
80
- types,
81
- action: event.payload.action,
82
- conversationId: event.payload.conversationId,
83
- requestId: event.payload.requestId,
84
- },
85
- "Secrets detected in tool output",
86
- );
87
- return;
88
- }
89
72
  case "tool.execution.finished":
90
73
  if (!debugEnabled()) return;
91
74
  logger.debug(
@@ -78,20 +78,6 @@ export function registerToolTraceListener(
78
78
  );
79
79
  return;
80
80
 
81
- case "tool.secret.detected":
82
- traceEmitter.emit(
83
- "secret_detected",
84
- `Secret detected in ${event.payload.toolName} output`,
85
- {
86
- requestId: event.payload.requestId,
87
- status: "warning",
88
- attributes: {
89
- toolName: event.payload.toolName,
90
- },
91
- },
92
- );
93
- return;
94
-
95
81
  default:
96
82
  return;
97
83
  }
@@ -1,6 +1,7 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
+ import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
4
5
  import { getConfig } from "../config/loader.js";
5
6
  import type { LLMCallSite } from "../config/schemas/llm.js";
6
7
  import { processMessage } from "../daemon/process-message.js";
@@ -108,7 +109,18 @@ export class FilingService {
108
109
  }
109
110
 
110
111
  start(): void {
111
- const config = getConfig().filing;
112
+ const fullConfig = getConfig();
113
+ if (
114
+ isAssistantFeatureFlagEnabled("memory-v2-enabled", fullConfig) &&
115
+ fullConfig.memory.v2.enabled
116
+ ) {
117
+ log.info("Filing service disabled — memory v2 is active");
118
+ this._nextRunAt = null;
119
+ this._nextCompactionAt = null;
120
+ return;
121
+ }
122
+
123
+ const config = fullConfig.filing;
112
124
 
113
125
  if (config.enabled && !this.timer) {
114
126
  log.info({ intervalMs: config.intervalMs }, "Filing service started");
@@ -14,6 +14,7 @@ mock.module("../../runtime/assistant-event-hub.js", () => ({
14
14
  publish: publishSpy,
15
15
  subscribe: () => () => {},
16
16
  },
17
+ broadcastMessage: () => {},
17
18
  }));
18
19
 
19
20
  // Stub workspace prompt reads so the heartbeat service doesn't try to
@@ -100,19 +101,22 @@ mock.module("../../prompts/system-prompt.js", () => ({
100
101
  buildCliReferenceSection: () => "",
101
102
  ensurePromptFiles: () => {},
102
103
  stripCommentLines: (s: string) => s,
104
+ readPromptFile: () => null,
103
105
  }));
104
106
 
105
107
  // Mock processMessage — HeartbeatService now imports it directly.
106
- let _testProcessMessage: ((...args: unknown[]) => Promise<{ messageId: string }>) | undefined;
108
+ let _testProcessMessage:
109
+ | ((...args: unknown[]) => Promise<{ messageId: string }>)
110
+ | undefined;
107
111
 
108
112
  mock.module("../../daemon/process-message.js", () => ({
109
113
  processMessage: async (...args: unknown[]) => {
110
114
  if (_testProcessMessage) return _testProcessMessage(...args);
111
115
  return { messageId: `mock-msg-${Date.now()}` };
112
116
  },
117
+ processMessageInBackground: async () => ({ messageId: "mock-bg" }),
113
118
  resolveTurnChannel: () => "vellum",
114
119
  resolveTurnInterface: () => "vellum",
115
- makePendingInteractionRegistrar: () => () => {},
116
120
  prepareConversationForMessage: async () => ({}),
117
121
  }));
118
122
 
@@ -274,11 +274,25 @@ export class HeartbeatService {
274
274
  await import("../credential-health/credential-health-service.js");
275
275
  const report = await checkAllCredentials();
276
276
  if (report.unhealthy.length > 0) {
277
- await this.notifyUnhealthyCredentials(report.unhealthy);
278
- // Only block providers for hard-failure statuses expiring and ping_failed
279
- // are transient/still-usable and should not disable provider tools.
280
- // missing_scopes is a hard failure because required scopes are absent and
281
- // provider tools will predictably fail.
277
+ // Filter out unreachable results — CES wake/startup blips should not
278
+ // produce user-facing credential alerts. Only actionable failures notify.
279
+ const notifiable = report.unhealthy.filter(
280
+ (r) => r.status !== "unreachable",
281
+ );
282
+ const unreachableCount = report.unhealthy.length - notifiable.length;
283
+ if (unreachableCount > 0) {
284
+ log.warn(
285
+ { unreachableCount },
286
+ "Credential backend unreachable — skipping health alerts for affected providers",
287
+ );
288
+ }
289
+ if (notifiable.length > 0) {
290
+ await this.notifyUnhealthyCredentials(notifiable);
291
+ }
292
+ // Only block providers for hard-failure statuses — expiring, ping_failed,
293
+ // and unreachable are transient/still-usable and should not disable
294
+ // provider tools. missing_scopes is a hard failure because required
295
+ // scopes are absent and provider tools will predictably fail.
282
296
  const hardFailureStatuses = new Set([
283
297
  "revoked",
284
298
  "missing_token",
@@ -355,6 +369,10 @@ export class HeartbeatService {
355
369
  missingScopes: result.missingScopes,
356
370
  },
357
371
  routingIntent: "single_channel",
372
+ conversationMetadata: {
373
+ source: "heartbeat",
374
+ groupId: "system:background",
375
+ },
358
376
  });
359
377
  } catch (err) {
360
378
  log.error(
@@ -18,8 +18,6 @@ import {
18
18
  test,
19
19
  } from "bun:test";
20
20
 
21
- import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../runtime/assistant-scope.js";
22
-
23
21
  // ─── assistantEventHub mock ────────────────────────────────────────────
24
22
  // We spy on `publish` so the SSE-publish test can assert the writer
25
23
  // fires a `home_feed_updated` event with the correct `newItemCount`.
@@ -651,14 +649,12 @@ describe("feed-writer", () => {
651
649
  // Inspect the LAST publish — it reflects the final on-disk state.
652
650
  const lastCall = publishSpy.mock.calls[publishSpy.mock.calls.length - 1]!;
653
651
  const event = lastCall[0] as {
654
- assistantId: string;
655
652
  message: {
656
653
  type: string;
657
654
  updatedAt: string;
658
655
  newItemCount: number;
659
656
  };
660
657
  };
661
- expect(event.assistantId).toBe(DAEMON_INTERNAL_ASSISTANT_ID);
662
658
  expect(event.message.type).toBe("home_feed_updated");
663
659
  expect(event.message.newItemCount).toBe(2);
664
660
  expect(Number.isNaN(Date.parse(event.message.updatedAt))).toBe(false);
@@ -704,6 +704,36 @@ describe("relationship-state-writer", () => {
704
704
  expect(state.facts[0]?.source).toBe("onboarding");
705
705
  });
706
706
 
707
+ test("tone group ID 'warm' maps to descriptive voice fact 'Warm and easy'", async () => {
708
+ writeOnboardingSidecar({
709
+ tools: [],
710
+ tasks: [],
711
+ tone: "warm",
712
+ });
713
+
714
+ const state = (await computeRelationshipState()) as RelationshipStateLike;
715
+ const voiceFacts = state.facts.filter(
716
+ (f) => f.category === "voice" && f.source === "onboarding",
717
+ );
718
+ expect(voiceFacts).toHaveLength(1);
719
+ expect(voiceFacts[0]!.text).toBe("Warm and easy");
720
+ });
721
+
722
+ test("unrecognized tone value passes through verbatim (backwards-compatible)", async () => {
723
+ writeOnboardingSidecar({
724
+ tools: [],
725
+ tasks: [],
726
+ tone: "balanced",
727
+ });
728
+
729
+ const state = (await computeRelationshipState()) as RelationshipStateLike;
730
+ const voiceFacts = state.facts.filter(
731
+ (f) => f.category === "voice" && f.source === "onboarding",
732
+ );
733
+ expect(voiceFacts).toHaveLength(1);
734
+ expect(voiceFacts[0]!.text).toBe("balanced");
735
+ });
736
+
707
737
  test("missing sidecar produces no onboarding-sourced facts", async () => {
708
738
  writeFile("USER.md", "- Preferred name: Alex");
709
739
  const state = (await computeRelationshipState()) as RelationshipStateLike;
@@ -54,7 +54,6 @@ import { join } from "node:path";
54
54
 
55
55
  import { buildAssistantEvent } from "../runtime/assistant-event.js";
56
56
  import { assistantEventHub } from "../runtime/assistant-event-hub.js";
57
- import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
58
57
  import { getLogger } from "../util/logger.js";
59
58
  import { getDataDir } from "../util/platform.js";
60
59
  import {
@@ -457,7 +456,7 @@ function compareFeedItems(a: FeedItem, b: FeedItem): number {
457
456
  function publishHomeFeedUpdated(updatedAt: string, newItemCount: number): void {
458
457
  assistantEventHub
459
458
  .publish(
460
- buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
459
+ buildAssistantEvent({
461
460
  type: "home_feed_updated",
462
461
  updatedAt,
463
462
  newItemCount,