@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
@@ -32,15 +32,10 @@ const mockConfig = {
32
32
  rateLimit: { maxRequestsPerMinute: 0 },
33
33
  secretDetection: {
34
34
  enabled: true,
35
- action: "warn" as const,
36
- entropyThreshold: 4.0,
37
35
  },
38
36
  auditLog: { retentionDays: 0 },
39
37
  };
40
38
 
41
- // Track whether wrapCommand was ever called — host_bash must never invoke it
42
- let wrapCommandCallCount = 0;
43
-
44
39
  mock.module("../config/loader.js", () => ({
45
40
  getConfig: () => mockConfig,
46
41
  loadConfig: () => mockConfig,
@@ -59,10 +54,22 @@ mock.module("../util/logger.js", () => ({
59
54
  }),
60
55
  }));
61
56
 
62
- mock.module("../tools/terminal/sandbox.js", () => ({
63
- wrapCommand: (...args: unknown[]) => {
64
- wrapCommandCallCount++;
65
- return { command: "bash", args: ["-c", "--", args[0]], sandboxed: false };
57
+ // Mock the host-bash-proxy singleton so proxy delegation tests can control it.
58
+ let mockProxyAvailable = false;
59
+ let mockProxyRequestFn: (
60
+ input: { command: string; working_dir?: string; timeout_seconds?: number; env?: Record<string, string> },
61
+ conversationId: string,
62
+ signal?: AbortSignal,
63
+ ) => Promise<ToolExecutionResult> = () => Promise.resolve({ content: "", isError: false });
64
+
65
+ mock.module("../daemon/host-bash-proxy.js", () => ({
66
+ HostBashProxy: {
67
+ get instance() {
68
+ return {
69
+ isAvailable: () => mockProxyAvailable,
70
+ request: mockProxyRequestFn,
71
+ };
72
+ },
66
73
  },
67
74
  }));
68
75
 
@@ -83,6 +90,8 @@ afterEach(() => {
83
90
  for (const dir of testDirs.splice(0)) {
84
91
  rmSync(dir, { recursive: true, force: true });
85
92
  }
93
+ mockProxyAvailable = false;
94
+ mockProxyRequestFn = () => Promise.resolve({ content: "", isError: false });
86
95
  });
87
96
 
88
97
  describe("host_bash tool", () => {
@@ -125,8 +134,6 @@ describe("host_bash tool", () => {
125
134
  });
126
135
 
127
136
  test("does not route through sandbox wrapCommand", async () => {
128
- wrapCommandCallCount = 0;
129
-
130
137
  const dir = mkdtempSync(join(tmpdir(), "host-shell-nosandbox-"));
131
138
  testDirs.push(dir);
132
139
 
@@ -140,8 +147,6 @@ describe("host_bash tool", () => {
140
147
 
141
148
  expect(result.isError).toBe(false);
142
149
  expect(result.content.trim()).toBe("isolation-test");
143
- // The sandbox wrapCommand must never be called for host_bash
144
- expect(wrapCommandCallCount).toBe(0);
145
150
  });
146
151
 
147
152
  test("spawns plain bash without sandbox-exec or bwrap", async () => {
@@ -236,7 +241,6 @@ describe("host_bash — baseline: no sandbox isolation", () => {
236
241
  testDirs.push(dir);
237
242
 
238
243
  spawnCalls.length = 0;
239
- wrapCommandCallCount = 0;
240
244
 
241
245
  const result = await hostShellTool.execute(
242
246
  {
@@ -247,7 +251,6 @@ describe("host_bash — baseline: no sandbox isolation", () => {
247
251
  );
248
252
 
249
253
  expect(result.isError).toBe(false);
250
- expect(wrapCommandCallCount).toBe(0);
251
254
  expect(spawnCalls[0].command).toBe("bash");
252
255
  });
253
256
  });
@@ -289,7 +292,6 @@ describe("host_bash — regression: no proxied-mode additions", () => {
289
292
  testDirs.push(dir);
290
293
 
291
294
  spawnCalls.length = 0;
292
- wrapCommandCallCount = 0;
293
295
 
294
296
  // Pass network_mode as if the model hallucinated the parameter —
295
297
  // host_bash must ignore it and run the command normally.
@@ -308,7 +310,6 @@ describe("host_bash — regression: no proxied-mode additions", () => {
308
310
  expect(spawnCalls.length).toBe(1);
309
311
  expect(spawnCalls[0].command).toBe("bash");
310
312
  // Must never route through sandbox wrapCommand, even with proxied-mode input
311
- expect(wrapCommandCallCount).toBe(0);
312
313
  });
313
314
 
314
315
  test("execute ignores credential_ids even if supplied in input", async () => {
@@ -316,7 +317,6 @@ describe("host_bash — regression: no proxied-mode additions", () => {
316
317
  testDirs.push(dir);
317
318
 
318
319
  spawnCalls.length = 0;
319
- wrapCommandCallCount = 0;
320
320
 
321
321
  const result = await hostShellTool.execute(
322
322
  {
@@ -332,7 +332,6 @@ describe("host_bash — regression: no proxied-mode additions", () => {
332
332
  expect(spawnCalls.length).toBe(1);
333
333
  expect(spawnCalls[0].command).toBe("bash");
334
334
  // Must never route through sandbox wrapCommand, even with credential inputs
335
- expect(wrapCommandCallCount).toBe(0);
336
335
  });
337
336
 
338
337
  test("tool name is host_bash (not bash)", () => {
@@ -721,7 +720,7 @@ describe("host_bash — proxy delegation", () => {
721
720
  }
722
721
  }
723
722
 
724
- function makeMockProxy(result: ToolExecutionResult) {
723
+ function setupMockProxy(result: ToolExecutionResult) {
725
724
  const calls: Array<{
726
725
  input: {
727
726
  command: string;
@@ -732,41 +731,24 @@ describe("host_bash — proxy delegation", () => {
732
731
  conversationId: string;
733
732
  }> = [];
734
733
 
735
- return {
736
- proxy: {
737
- isAvailable: () => true,
738
- request: async (
739
- input: {
740
- command: string;
741
- working_dir?: string;
742
- timeout_seconds?: number;
743
- env?: Record<string, string>;
744
- },
745
- conversationId: string,
746
- _signal?: AbortSignal,
747
- ) => {
748
- calls.push({ input, conversationId });
749
- return result;
750
- },
751
- updateSender: () => {},
752
- dispose: () => {},
753
- resolve: () => {},
754
- hasPendingRequest: () => false,
755
- },
756
- calls,
734
+ mockProxyAvailable = true;
735
+ mockProxyRequestFn = async (input, conversationId) => {
736
+ calls.push({ input, conversationId });
737
+ return result;
757
738
  };
739
+
740
+ return calls;
758
741
  }
759
742
 
760
- test("delegates to proxy when hostBashProxy is available", async () => {
743
+ test("delegates to proxy when proxy is available", async () => {
761
744
  const proxyResult: ToolExecutionResult = {
762
745
  content: "proxied output",
763
746
  isError: false,
764
747
  };
765
- const { proxy, calls } = makeMockProxy(proxyResult);
748
+ const calls = setupMockProxy(proxyResult);
766
749
 
767
750
  const ctx: ToolContext = {
768
751
  ...makeContext(),
769
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
770
752
  };
771
753
 
772
754
  spawnCalls.length = 0;
@@ -790,11 +772,10 @@ describe("host_bash — proxy delegation", () => {
790
772
  content: "proxied",
791
773
  isError: false,
792
774
  };
793
- const { proxy, calls } = makeMockProxy(proxyResult);
775
+ const calls = setupMockProxy(proxyResult);
794
776
 
795
777
  const ctx: ToolContext = {
796
778
  ...makeContext(),
797
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
798
779
  };
799
780
 
800
781
  const result = await hostShellTool.execute({ command: "echo \0evil" }, ctx);
@@ -810,11 +791,10 @@ describe("host_bash — proxy delegation", () => {
810
791
  content: "proxied",
811
792
  isError: false,
812
793
  };
813
- const { proxy, calls } = makeMockProxy(proxyResult);
794
+ const calls = setupMockProxy(proxyResult);
814
795
 
815
796
  const ctx: ToolContext = {
816
797
  ...makeContext(),
817
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
818
798
  };
819
799
 
820
800
  const result = await hostShellTool.execute(
@@ -828,24 +808,12 @@ describe("host_bash — proxy delegation", () => {
828
808
  });
829
809
 
830
810
  test("falls back to local execution when proxy is not available", async () => {
831
- const unavailableProxy = {
832
- isAvailable: () => false,
833
- request: async () => {
834
- throw new Error("should not be called");
835
- },
836
- updateSender: () => {},
837
- dispose: () => {},
838
- resolve: () => {},
839
- hasPendingRequest: () => false,
840
- };
841
-
811
+ // mockProxyAvailable defaults to false, so isAvailable() returns false
842
812
  const dir = mkdtempSync(join(tmpdir(), "host-shell-proxy-fallback-"));
843
813
  testDirs.push(dir);
844
814
 
845
815
  const ctx: ToolContext = {
846
816
  ...makeContext(),
847
- hostBashProxy:
848
- unavailableProxy as unknown as ToolContext["hostBashProxy"],
849
817
  };
850
818
 
851
819
  spawnCalls.length = 0;
@@ -894,12 +862,11 @@ describe("host_bash — proxy delegation", () => {
894
862
  content: "proxied",
895
863
  isError: false,
896
864
  };
897
- const { proxy, calls } = makeMockProxy(proxyResult);
865
+ const calls = setupMockProxy(proxyResult);
898
866
 
899
867
  const ctx: ToolContext = {
900
868
  ...makeContext(),
901
869
  trustClass: "trusted_contact", // untrusted actor
902
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
903
870
  };
904
871
 
905
872
  const result = await hostShellTool.execute(
@@ -930,12 +897,11 @@ describe("host_bash — proxy delegation", () => {
930
897
  content: "proxied",
931
898
  isError: false,
932
899
  };
933
- const { proxy, calls } = makeMockProxy(proxyResult);
900
+ const calls = setupMockProxy(proxyResult);
934
901
 
935
902
  const ctx: ToolContext = {
936
903
  ...makeContext(),
937
904
  trustClass: "guardian", // trusted actor — no lockdown
938
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
939
905
  };
940
906
 
941
907
  const result = await hostShellTool.execute(
@@ -969,12 +935,11 @@ describe("host_bash — proxy delegation", () => {
969
935
  content: "proxied",
970
936
  isError: false,
971
937
  };
972
- const { proxy, calls } = makeMockProxy(proxyResult);
938
+ const calls = setupMockProxy(proxyResult);
973
939
 
974
940
  const ctx: ToolContext = {
975
941
  ...makeContext(),
976
942
  trustClass: "guardian", // trusted actor — no lockdown
977
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
978
943
  };
979
944
 
980
945
  const result = await hostShellTool.execute(
@@ -9,7 +9,6 @@
9
9
  */
10
10
  import { beforeEach, describe, expect, test } from "bun:test";
11
11
 
12
- import type { Conversation } from "../daemon/conversation.js";
13
12
  import type {
14
13
  HostTransferCancelRequest,
15
14
  HostTransferRequest,
@@ -19,14 +18,6 @@ import type {
19
18
  } from "../daemon/message-protocol.js";
20
19
  import * as pendingInteractions from "../runtime/pending-interactions.js";
21
20
 
22
- // ---------------------------------------------------------------------------
23
- // Helpers
24
- // ---------------------------------------------------------------------------
25
-
26
- function stubConversation(id: string): Conversation {
27
- return { id } as unknown as Conversation;
28
- }
29
-
30
21
  // ---------------------------------------------------------------------------
31
22
  // Message type compilation checks
32
23
  // ---------------------------------------------------------------------------
@@ -65,6 +56,7 @@ describe("HostTransfer message types", () => {
65
56
  const msg: HostTransferCancelRequest = {
66
57
  type: "host_transfer_cancel",
67
58
  requestId: "req-3",
59
+ conversationId: "conv-1",
68
60
  };
69
61
  const _sm: ServerMessage = msg;
70
62
  expect(_sm.type).toBe("host_transfer_cancel");
@@ -105,9 +97,7 @@ describe("host_transfer pending interactions", () => {
105
97
  });
106
98
 
107
99
  test("host_transfer can be registered as a pending interaction", () => {
108
- const conv = stubConversation("conv-1");
109
100
  pendingInteractions.register("req-1", {
110
- conversation: conv,
111
101
  conversationId: "conv-1",
112
102
  kind: "host_transfer",
113
103
  });
@@ -119,21 +109,17 @@ describe("host_transfer pending interactions", () => {
119
109
  });
120
110
 
121
111
  test("host_transfer interactions survive removeByConversation", () => {
122
- const conv = stubConversation("conv-1");
123
-
124
112
  // Register a confirmation (should be removed) and a host_transfer (should survive)
125
113
  pendingInteractions.register("confirm-1", {
126
- conversation: conv,
127
114
  conversationId: "conv-1",
128
115
  kind: "confirmation",
129
116
  });
130
117
  pendingInteractions.register("transfer-1", {
131
- conversation: conv,
132
118
  conversationId: "conv-1",
133
119
  kind: "host_transfer",
134
120
  });
135
121
 
136
- pendingInteractions.removeByConversation(conv);
122
+ pendingInteractions.removeByConversation("conv-1");
137
123
 
138
124
  // Confirmation should be gone
139
125
  expect(pendingInteractions.get("confirm-1")).toBeUndefined();
@@ -143,9 +129,7 @@ describe("host_transfer pending interactions", () => {
143
129
  });
144
130
 
145
131
  test("host_transfer interactions can be resolved", () => {
146
- const conv = stubConversation("conv-1");
147
132
  pendingInteractions.register("req-1", {
148
- conversation: conv,
149
133
  conversationId: "conv-1",
150
134
  kind: "host_transfer",
151
135
  });
@@ -2,7 +2,30 @@ import { createHash } from "node:crypto";
2
2
  import { mkdtemp, readFile, rm } from "node:fs/promises";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
- import { afterAll, afterEach, describe, expect, test } from "bun:test";
5
+ import { afterAll, afterEach, describe, expect, mock, test } from "bun:test";
6
+
7
+ const sentMessages: unknown[] = [];
8
+ const resolvedInteractionIds: string[] = [];
9
+ let mockHasClient = false;
10
+
11
+ mock.module("../runtime/assistant-event-hub.js", () => ({
12
+ broadcastMessage: (msg: unknown) => sentMessages.push(msg),
13
+ assistantEventHub: {
14
+ getMostRecentClientByCapability: (cap: string) =>
15
+ cap === "host_file" && mockHasClient ? { id: "mock-client" } : null,
16
+ },
17
+ }));
18
+
19
+ mock.module("../runtime/pending-interactions.js", () => ({
20
+ resolve: (requestId: string) => {
21
+ resolvedInteractionIds.push(requestId);
22
+ return undefined;
23
+ },
24
+ get: () => undefined,
25
+ getByKind: () => [],
26
+ getByConversation: () => [],
27
+ removeByConversation: () => {},
28
+ }));
6
29
 
7
30
  const { HostTransferProxy } = await import("../daemon/host-transfer-proxy.js");
8
31
 
@@ -29,18 +52,18 @@ async function waitForMessages(
29
52
 
30
53
  describe("HostTransferProxy", () => {
31
54
  let proxy: InstanceType<typeof HostTransferProxy>;
32
- let sentMessages: unknown[];
33
- let sendToClient: (msg: unknown) => void;
34
55
  let tempDir: string;
35
56
 
36
- function setup(onInternalResolve?: (requestId: string) => void) {
37
- sentMessages = [];
38
- sendToClient = (msg: unknown) => sentMessages.push(msg);
39
- proxy = new HostTransferProxy(sendToClient, onInternalResolve);
57
+ function setup() {
58
+ sentMessages.length = 0;
59
+ resolvedInteractionIds.length = 0;
60
+ mockHasClient = false;
61
+ proxy = new (HostTransferProxy as any)();
40
62
  }
41
63
 
42
64
  afterEach(async () => {
43
65
  proxy?.dispose();
66
+ HostTransferProxy.reset();
44
67
  if (tempDir) {
45
68
  await rm(tempDir, { recursive: true, force: true }).catch(() => {});
46
69
  }
@@ -533,24 +556,17 @@ describe("HostTransferProxy", () => {
533
556
  });
534
557
 
535
558
  describe("isAvailable", () => {
536
- test("returns false by default (no client connected)", () => {
559
+ test("returns false when no client with host_file capability is connected", () => {
537
560
  setup();
561
+ mockHasClient = false;
538
562
  expect(proxy.isAvailable()).toBe(false);
539
563
  });
540
564
 
541
- test("returns true after updateSender with clientConnected=true", () => {
565
+ test("returns true when a client with host_file capability is connected", () => {
542
566
  setup();
543
- proxy.updateSender(sendToClient, true);
567
+ mockHasClient = true;
544
568
  expect(proxy.isAvailable()).toBe(true);
545
569
  });
546
-
547
- test("returns false after updateSender with clientConnected=false", () => {
548
- setup();
549
- proxy.updateSender(sendToClient, true);
550
- expect(proxy.isAvailable()).toBe(true);
551
- proxy.updateSender(sendToClient, false);
552
- expect(proxy.isAvailable()).toBe(false);
553
- });
554
570
  });
555
571
 
556
572
  describe("dispose", () => {
@@ -626,33 +642,9 @@ describe("HostTransferProxy", () => {
626
642
  });
627
643
  });
628
644
 
629
- describe("updateSender", () => {
630
- test("uses updated sender for new requests", async () => {
631
- setup();
632
-
633
- const newMessages: unknown[] = [];
634
- proxy.updateSender((msg) => newMessages.push(msg), true);
635
-
636
- const resultPromise = proxy.requestToSandbox({
637
- sourcePath: "/host/source.txt",
638
- destPath: "/sandbox/dest.txt",
639
- conversationId: "conv-123",
640
- });
641
-
642
- expect(sentMessages).toHaveLength(0);
643
- expect(newMessages).toHaveLength(1);
644
-
645
- // Cancel to avoid hanging
646
- const sent = newMessages[0] as Record<string, unknown>;
647
- proxy.cancel(sent.requestId as string);
648
- await resultPromise;
649
- });
650
- });
651
-
652
- describe("onInternalResolve callback", () => {
645
+ describe("pendingInteractions.resolve callback", () => {
653
646
  test("fires on abort", async () => {
654
- const resolvedIds: string[] = [];
655
- setup((id) => resolvedIds.push(id));
647
+ setup();
656
648
 
657
649
  const controller = new AbortController();
658
650
  const resultPromise = proxy.requestToSandbox(
@@ -670,12 +662,11 @@ describe("HostTransferProxy", () => {
670
662
  controller.abort();
671
663
  await resultPromise;
672
664
 
673
- expect(resolvedIds).toEqual([requestId]);
665
+ expect(resolvedInteractionIds).toContain(requestId);
674
666
  });
675
667
 
676
668
  test("fires for each pending request on dispose", () => {
677
- const resolvedIds: string[] = [];
678
- setup((id) => resolvedIds.push(id));
669
+ setup();
679
670
 
680
671
  const p1 = proxy.requestToSandbox({
681
672
  sourcePath: "/host/a.txt",
@@ -697,14 +688,13 @@ describe("HostTransferProxy", () => {
697
688
 
698
689
  proxy.dispose();
699
690
 
700
- expect(resolvedIds).toHaveLength(2);
701
- expect(resolvedIds).toContain(ids[0]);
702
- expect(resolvedIds).toContain(ids[1]);
691
+ expect(resolvedInteractionIds).toHaveLength(2);
692
+ expect(resolvedInteractionIds).toContain(ids[0]);
693
+ expect(resolvedInteractionIds).toContain(ids[1]);
703
694
  });
704
695
 
705
696
  test("does not fire on normal resolveTransferResult", async () => {
706
- const resolvedIds: string[] = [];
707
- setup((id) => resolvedIds.push(id));
697
+ setup();
708
698
  tempDir = await mkdtemp(join(tmpdir(), "htp-test-"));
709
699
  const srcPath = join(tempDir, "source.txt");
710
700
  await globalThis.Bun.write(srcPath, "content");
@@ -727,7 +717,7 @@ describe("HostTransferProxy", () => {
727
717
  });
728
718
 
729
719
  await resultPromise;
730
- expect(resolvedIds).toEqual([]);
720
+ expect(resolvedInteractionIds).toEqual([]);
731
721
  });
732
722
  });
733
723
  });
@@ -124,8 +124,6 @@ mock.module("../config/loader.js", () => ({
124
124
  getConfig: () => ({
125
125
  secretDetection: {
126
126
  enabled: true,
127
- customPatterns: [],
128
- entropyThreshold: 3.5,
129
127
  },
130
128
  model: "test",
131
129
  provider: "test",
@@ -206,11 +204,7 @@ function makeConversation(overrides: Record<string, unknown> = {}) {
206
204
  return {
207
205
  setTrustContext: () => {},
208
206
  updateClient: () => {},
209
- setHostBashProxy: () => {},
210
207
  setHostBrowserProxy: () => {},
211
- setHostFileProxy: () => {},
212
- setHostTransferProxy: () => {},
213
- getHostTransferProxy: () => undefined,
214
208
  setHostCuProxy: () => {},
215
209
  addPreactivatedSkillId: () => {},
216
210
  emitConfirmationStateChanged: () => {},
@@ -194,6 +194,37 @@ describe("PR 11 — inbound Slack message metadata persistence", () => {
194
194
  expect(slackMeta!.displayName).toBe("Bob");
195
195
  });
196
196
 
197
+ test("Slack normalized content is persisted with raw channelTs in slackMeta", async () => {
198
+ const ctx = createTestContext({
199
+ userMessageChannel: "slack",
200
+ assistantMessageChannel: "slack",
201
+ });
202
+
203
+ await persistQueuedMessageBody(
204
+ ctx,
205
+ "@leo can you check this?",
206
+ [],
207
+ "req-normalized-content",
208
+ {
209
+ slackInbound: {
210
+ channelId: "C0123CHANNEL",
211
+ channelTs: "1700000015.123456",
212
+ displayName: "Alice",
213
+ },
214
+ },
215
+ undefined,
216
+ );
217
+
218
+ expect(JSON.parse(addMessageCalls.at(-1)!.content)).toEqual([
219
+ { type: "text", text: "@leo can you check this?" },
220
+ ]);
221
+
222
+ const slackMeta = readPersistedSlackMeta();
223
+ expect(slackMeta).not.toBeNull();
224
+ expect(slackMeta!.channelTs).toBe("1700000015.123456");
225
+ expect(slackMeta!.displayName).toBe("Alice");
226
+ });
227
+
197
228
  test("Slack message without displayName omits the field", async () => {
198
229
  const ctx = createTestContext({
199
230
  userMessageChannel: "slack",
@@ -4,10 +4,10 @@
4
4
  *
5
5
  * Covers:
6
6
  *
7
- * 1. The eight default injectors registered by `defaultInjectorsPlugin` come
7
+ * 1. The nine default injectors registered by `defaultInjectorsPlugin` come
8
8
  * back from `getInjectors()` in the documented order (workspace-context →
9
- * unified-turn-context → pkb-context → pkb-reminder → now-md
10
- * subagent-status → slack-messages → thread-focus).
9
+ * unified-turn-context → pkb-context → pkb-reminder → memory-v2-static
10
+ * now-md → subagent-status → slack-messages → thread-focus).
11
11
  * 2. A third-party-registered injector at `order: 25` slots between
12
12
  * `unified-turn-context` (order 20) and `pkb` (order 30), proving the
13
13
  * extensibility contract.
@@ -76,7 +76,7 @@ describe("injector chain", () => {
76
76
  resetPluginRegistryForTests();
77
77
  });
78
78
 
79
- test("defaultInjectorsPlugin registers the eight defaults in the documented order", () => {
79
+ test("defaultInjectorsPlugin registers the nine defaults in the documented order", () => {
80
80
  registerPlugin(defaultInjectorsPlugin);
81
81
 
82
82
  const names = getInjectors().map((i) => i.name);
@@ -85,6 +85,7 @@ describe("injector chain", () => {
85
85
  "unified-turn-context",
86
86
  "pkb-context",
87
87
  "pkb-reminder",
88
+ "memory-v2-static",
88
89
  "now-md",
89
90
  "subagent-status",
90
91
  "slack-messages",
@@ -104,6 +105,9 @@ describe("injector chain", () => {
104
105
  );
105
106
  expect(byName.get("pkb-context")).toBe(DEFAULT_INJECTOR_ORDER.pkbContext);
106
107
  expect(byName.get("pkb-reminder")).toBe(DEFAULT_INJECTOR_ORDER.pkbReminder);
108
+ expect(byName.get("memory-v2-static")).toBe(
109
+ DEFAULT_INJECTOR_ORDER.memoryV2Static,
110
+ );
107
111
  expect(byName.get("now-md")).toBe(DEFAULT_INJECTOR_ORDER.nowMd);
108
112
  expect(byName.get("subagent-status")).toBe(
109
113
  DEFAULT_INJECTOR_ORDER.subagentStatus,
@@ -133,6 +137,7 @@ describe("injector chain", () => {
133
137
  "plugin-25", // 25 — slots in
134
138
  "pkb-context", // 30
135
139
  "pkb-reminder", // 35
140
+ "memory-v2-static", // 38
136
141
  "now-md", // 40
137
142
  "subagent-status", // 50
138
143
  "slack-messages", // 60
@@ -141,7 +146,7 @@ describe("injector chain", () => {
141
146
  });
142
147
 
143
148
  test("composeInjectorChain returns empty string when every injector opts out", async () => {
144
- // The default chain is the golden-path: all eight defaults return `null`
149
+ // The default chain is the golden-path: all nine defaults return `null`
145
150
  // on an empty turn context, so the composed block is an empty string.
146
151
  registerPlugin(defaultInjectorsPlugin);
147
152