@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
@@ -1,269 +0,0 @@
1
- import { getConfig } from "../config/loader.js";
2
- import { PermissionPrompter } from "../permissions/prompter.js";
3
- import { RiskLevel } from "../permissions/types.js";
4
- import type { SecretPattern } from "../security/secret-scanner.js";
5
- import {
6
- compileCustomPatterns,
7
- redactSecrets,
8
- scanText,
9
- } from "../security/secret-scanner.js";
10
- import type {
11
- ExecutionTarget,
12
- ToolContext,
13
- ToolExecutionResult,
14
- ToolLifecycleEvent,
15
- } from "./types.js";
16
-
17
- /**
18
- * Encapsulates post-execution secret detection, redaction, and action handling.
19
- * Extracted from ToolExecutor to isolate the secret-scanning concern.
20
- */
21
- export class SecretDetectionHandler {
22
- private prompter: PermissionPrompter;
23
-
24
- constructor(prompter: PermissionPrompter) {
25
- this.prompter = prompter;
26
- }
27
-
28
- /**
29
- * Scan a tool execution result for secrets and apply the configured action
30
- * (redact, block, or prompt). Returns the (possibly modified) result, or
31
- * a blocked result if secrets were blocked. Returns `null` when no secret
32
- * handling was needed and the caller should continue normally.
33
- */
34
- async handle(
35
- execResult: ToolExecutionResult,
36
- name: string,
37
- input: Record<string, unknown>,
38
- context: ToolContext,
39
- executionTarget: ExecutionTarget,
40
- riskLevel: string,
41
- decision: string,
42
- startTime: number,
43
- emitLifecycleEvent: (
44
- context: ToolContext,
45
- event: ToolLifecycleEvent,
46
- ) => void,
47
- ): Promise<{ result: ToolExecutionResult; earlyReturn: boolean }> {
48
- const sdConfig = getConfig().secretDetection;
49
- if (!sdConfig.enabled || execResult.isError) {
50
- return { result: execResult, earlyReturn: false };
51
- }
52
-
53
- const entropyConfig = {
54
- enabled: true,
55
- base64Threshold: sdConfig.entropyThreshold,
56
- };
57
- const compiledCustom = sdConfig.customPatterns?.length
58
- ? compileCustomPatterns(sdConfig.customPatterns)
59
- : undefined;
60
-
61
- const allMatches = this.collectMatches(
62
- execResult,
63
- entropyConfig,
64
- compiledCustom,
65
- );
66
-
67
- if (allMatches.length === 0) {
68
- return { result: execResult, earlyReturn: false };
69
- }
70
-
71
- const matchSummary = allMatches.map((m) => ({
72
- type: m.type,
73
- redactedValue: m.redactedValue,
74
- }));
75
-
76
- emitLifecycleEvent(context, {
77
- type: "secret_detected",
78
- toolName: name,
79
- executionTarget,
80
- input,
81
- workingDir: context.workingDir,
82
- conversationId: context.conversationId,
83
- requestId: context.requestId,
84
- matches: matchSummary,
85
- action: sdConfig.action,
86
- detectedAtMs: Date.now(),
87
- });
88
-
89
- if (sdConfig.action === "redact") {
90
- this.redactResult(execResult, entropyConfig, compiledCustom);
91
- return { result: execResult, earlyReturn: false };
92
- }
93
-
94
- if (sdConfig.action === "block") {
95
- return this.handleBlock(
96
- allMatches,
97
- name,
98
- input,
99
- context,
100
- executionTarget,
101
- riskLevel,
102
- decision,
103
- startTime,
104
- emitLifecycleEvent,
105
- );
106
- }
107
-
108
- if (sdConfig.action === "prompt") {
109
- return this.handlePrompt(
110
- allMatches,
111
- execResult,
112
- name,
113
- input,
114
- context,
115
- executionTarget,
116
- riskLevel,
117
- decision,
118
- startTime,
119
- emitLifecycleEvent,
120
- );
121
- }
122
-
123
- return { result: execResult, earlyReturn: false };
124
- }
125
-
126
- private collectMatches(
127
- execResult: ToolExecutionResult,
128
- entropyConfig: { enabled: boolean; base64Threshold: number },
129
- compiledCustom: SecretPattern[] | undefined,
130
- ) {
131
- const contentMatches = scanText(
132
- execResult.content,
133
- entropyConfig,
134
- compiledCustom,
135
- );
136
- const diffMatches = execResult.diff
137
- ? scanText(execResult.diff.newContent, entropyConfig, compiledCustom)
138
- : [];
139
- const blockMatches = (execResult.contentBlocks ?? []).flatMap((block) => {
140
- if (block.type === "text")
141
- return scanText(block.text, entropyConfig, compiledCustom);
142
- if (block.type === "file" && block.extracted_text)
143
- return scanText(block.extracted_text, entropyConfig, compiledCustom);
144
- return [];
145
- });
146
- return [...contentMatches, ...diffMatches, ...blockMatches];
147
- }
148
-
149
- private redactResult(
150
- execResult: ToolExecutionResult,
151
- entropyConfig: { enabled: boolean; base64Threshold: number },
152
- compiledCustom: SecretPattern[] | undefined,
153
- ): void {
154
- execResult.content = redactSecrets(
155
- execResult.content,
156
- entropyConfig,
157
- compiledCustom,
158
- );
159
- if (execResult.diff) {
160
- execResult.diff = {
161
- ...execResult.diff,
162
- newContent: redactSecrets(
163
- execResult.diff.newContent,
164
- entropyConfig,
165
- compiledCustom,
166
- ),
167
- };
168
- }
169
- if (execResult.contentBlocks) {
170
- execResult.contentBlocks = execResult.contentBlocks.map((block) => {
171
- if (block.type === "text") {
172
- return {
173
- ...block,
174
- text: redactSecrets(block.text, entropyConfig, compiledCustom),
175
- };
176
- }
177
- if (block.type === "file" && block.extracted_text) {
178
- return {
179
- ...block,
180
- extracted_text: redactSecrets(
181
- block.extracted_text,
182
- entropyConfig,
183
- compiledCustom,
184
- ),
185
- };
186
- }
187
- return block;
188
- });
189
- }
190
- }
191
-
192
- private handleBlock(
193
- allMatches: Array<{ type: string; redactedValue: string }>,
194
- name: string,
195
- input: Record<string, unknown>,
196
- context: ToolContext,
197
- executionTarget: ExecutionTarget,
198
- riskLevel: string,
199
- decision: string,
200
- startTime: number,
201
- emitLifecycleEvent: (
202
- context: ToolContext,
203
- event: ToolLifecycleEvent,
204
- ) => void,
205
- ): { result: ToolExecutionResult; earlyReturn: boolean } {
206
- const types = [...new Set(allMatches.map((m) => m.type))].join(", ");
207
- const blockedContent = `Tool output blocked: detected ${allMatches.length} potential secret(s) (${types}). Configure secretDetection.action to "redact" or "prompt" to allow output.`;
208
- const durationMs = Date.now() - startTime;
209
- const blockedResult: ToolExecutionResult = {
210
- content: blockedContent,
211
- isError: true,
212
- };
213
-
214
- emitLifecycleEvent(context, {
215
- type: "executed",
216
- toolName: name,
217
- executionTarget,
218
- input,
219
- workingDir: context.workingDir,
220
- conversationId: context.conversationId,
221
- requestId: context.requestId,
222
- riskLevel,
223
- decision,
224
- durationMs,
225
- result: blockedResult,
226
- });
227
-
228
- return { result: blockedResult, earlyReturn: true };
229
- }
230
-
231
- private async handlePrompt(
232
- allMatches: Array<{ type: string; redactedValue: string }>,
233
- _execResult: ToolExecutionResult,
234
- name: string,
235
- input: Record<string, unknown>,
236
- context: ToolContext,
237
- executionTarget: ExecutionTarget,
238
- _riskLevel: string,
239
- _decision: string,
240
- startTime: number,
241
- emitLifecycleEvent: (
242
- context: ToolContext,
243
- event: ToolLifecycleEvent,
244
- ) => void,
245
- ): Promise<{ result: ToolExecutionResult; earlyReturn: boolean }> {
246
- const types = [...new Set(allMatches.map((m) => m.type))].join(", ");
247
- const blockedContent = `Tool output blocked: detected ${allMatches.length} potential secret(s) (${types}). Ask the user for confirmation conversationally before retrying.`;
248
- const durationMs = Date.now() - startTime;
249
-
250
- emitLifecycleEvent(context, {
251
- type: "permission_denied",
252
- toolName: name,
253
- executionTarget,
254
- input,
255
- workingDir: context.workingDir,
256
- conversationId: context.conversationId,
257
- requestId: context.requestId,
258
- riskLevel: RiskLevel.High,
259
- decision: "deny",
260
- reason: "Secret output blocked without deterministic prompt",
261
- durationMs,
262
- });
263
-
264
- return {
265
- result: { content: blockedContent, isError: true },
266
- earlyReturn: true,
267
- };
268
- }
269
- }
@@ -1,327 +0,0 @@
1
- import { execSync } from "node:child_process";
2
- import { createHash } from "node:crypto";
3
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
4
- import { join } from "node:path";
5
-
6
- import { ToolError } from "../../../util/errors.js";
7
- import { getLogger } from "../../../util/logger.js";
8
- import { isLinux, isMacOS } from "../../../util/platform.js";
9
- import type { SandboxBackend, SandboxResult, WrapOptions } from "./types.js";
10
-
11
- const log = getLogger("sandbox");
12
-
13
- const HASH_DISPLAY_LENGTH = 12;
14
-
15
- /**
16
- * macOS TCC-protected directories that trigger permission prompts when accessed.
17
- * Unconditionally denied in the SBPL sandbox profile to prevent the assistant
18
- * from triggering Photos, Contacts, Calendar, etc. dialogs during filesystem
19
- * traversal (e.g. `find ~ -name .git`).
20
- *
21
- * Paths are relative to $HOME. Includes both TCC-protected directories that
22
- * trigger prompts for all apps and directories like ~/Desktop and ~/Documents
23
- * that are TCC-protected under App Sandbox or Full Disk Access checks.
24
- */
25
- export const MACOS_TCC_PROTECTED_PATHS = [
26
- "Desktop",
27
- "Documents",
28
- "Pictures/Photos Library.photoslibrary",
29
- "Library/Photos",
30
- "Library/Calendars",
31
- "Library/Reminders",
32
- "Library/Application Support/AddressBook",
33
- "Library/Messages",
34
- "Library/Mail",
35
- "Library/Safari",
36
- "Library/Cookies",
37
- "Library/HomeKit",
38
- "Library/IdentityServices",
39
- "Library/Metadata/CoreSpotlight",
40
- "Library/PersonalizationPortrait",
41
- "Library/Suggestions",
42
- ];
43
-
44
- /**
45
- * Build a macOS sandbox-exec SBPL profile.
46
- *
47
- * The profile restricts shell commands:
48
- * - Denies all by default
49
- * - Allows read access to most of the filesystem (needed for toolchains)
50
- * - Allows write access only to the working directory and temp dirs
51
- * - Blocks outbound network access (unless proxied)
52
- * - Blocks process debugging (ptrace)
53
- * - Optionally blocks read access to specific protected paths (CES lockdown)
54
- *
55
- * When `allowNetwork` is true the `(deny network*)` rule is replaced with
56
- * `(allow network*)` so the process can reach the local credential proxy.
57
- */
58
- function buildSandboxProfile(
59
- allowNetwork: boolean,
60
- denyReadPaths?: string[],
61
- ): string {
62
- const networkRule = allowNetwork
63
- ? ";; Allow network access (proxied mode - needed to reach the credential proxy)\n(allow network*)"
64
- : ";; Block network access\n(deny network*)";
65
-
66
- // Block macOS TCC-protected directories to prevent permission prompts
67
- // during filesystem traversal. Placed AFTER (allow file-read*) because
68
- // SBPL uses last-match-wins semantics.
69
- const home = process.env.HOME ?? "";
70
- const tccDenyRules = home
71
- ? "\n;; Block macOS TCC-protected directories to prevent permission prompts\n" +
72
- MACOS_TCC_PROTECTED_PATHS.map(
73
- (rel) =>
74
- `(deny file-read* (subpath "${escapeSBPL(join(home, rel))}") (with no-log))`,
75
- ).join("\n")
76
- : "";
77
-
78
- // Build deny-read rules for protected paths (CES shell lockdown).
79
- // These are placed AFTER the allow file-read* rule because SBPL uses
80
- // last-match-wins semantics - the more specific deny overrides the
81
- // general allow.
82
- const denyReadRules =
83
- denyReadPaths && denyReadPaths.length > 0
84
- ? "\n;; CES shell lockdown: block reads of protected credential/transport paths\n" +
85
- denyReadPaths
86
- .map(
87
- (p) =>
88
- `(deny file-read* (subpath "${escapeSBPL(p)}") (with no-log))`,
89
- )
90
- .join("\n")
91
- : "";
92
-
93
- return `
94
- (version 1)
95
- (deny default)
96
-
97
- ;; Allow read access to the filesystem (tools, libraries, etc.)
98
- (allow file-read*)
99
- ${tccDenyRules}
100
-
101
- ;; Re-allow reads for the working directory even if it falls under a TCC-denied
102
- ;; subtree (e.g. ~/Desktop/my-project). SBPL is last-match-wins, so this
103
- ;; override must come after the TCC deny rules above but BEFORE the CES
104
- ;; deny-read rules below — credential isolation always takes precedence.
105
- (allow file-read* (subpath "__WORKING_DIR__"))
106
- ${denyReadRules}
107
-
108
- ;; Allow write access to the working directory and its children
109
- (allow file-write*
110
- (literal "/dev/null")
111
- (subpath "__WORKING_DIR__")
112
- (subpath "/private/tmp")
113
- (subpath "/tmp")
114
- (subpath "/var/folders"))
115
-
116
- ;; Allow process execution (needed to run commands)
117
- (allow process-exec*)
118
- (allow process-fork)
119
-
120
- ;; Allow signal delivery between parent and child
121
- (allow signal (target others))
122
-
123
- ;; Allow sysctl reads (needed by many tools)
124
- (allow sysctl-read)
125
-
126
- ;; Allow mach lookups (IPC, needed for basic process operation)
127
- (allow mach-lookup)
128
- (allow mach-register)
129
-
130
- ;; Allow IOKit (needed for some system calls)
131
- (allow iokit-open)
132
-
133
- ${networkRule}
134
-
135
- ;; Block process debugging
136
- (deny process-info-pidinfo (target others))
137
- `.trim();
138
- }
139
-
140
- /**
141
- * Escape a path for safe embedding inside an SBPL quoted string.
142
- * Backslash-escapes characters that are meaningful in SBPL syntax.
143
- * Newlines/carriage returns are rejected since they cannot appear in real paths.
144
- */
145
- function escapeSBPL(path: string): string {
146
- if (/[\n\r]/.test(path)) {
147
- throw new ToolError(
148
- "Working directory path contains newline characters, which cannot be used in a sandbox profile.",
149
- "bash",
150
- );
151
- }
152
- return path.replace(/[\\";()]/g, (ch) => `\\${ch}`);
153
- }
154
-
155
- /**
156
- * Get the path to the sandbox profile file, creating it if needed.
157
- *
158
- * Each distinct working directory gets its own profile file (keyed by
159
- * a hash of the path) to avoid race conditions when concurrent commands
160
- * use different working directories.
161
- */
162
- function getProfilePath(
163
- workingDir: string,
164
- allowNetwork: boolean,
165
- denyReadPaths?: string[],
166
- ): string {
167
- const dir = join(process.env.HOME ?? "/tmp", ".vellum");
168
- if (!existsSync(dir)) {
169
- mkdirSync(dir, { recursive: true });
170
- }
171
- // Include the network flag, deny-read paths, and HOME in the hash so
172
- // profiles with different configurations don't collide.
173
- let hashInput = allowNetwork ? `${workingDir}:proxied` : workingDir;
174
- if (denyReadPaths && denyReadPaths.length > 0) {
175
- hashInput += `:deny-read:${denyReadPaths.sort().join(",")}`;
176
- }
177
- hashInput += `:home:${process.env.HOME ?? ""}`;
178
- const hash = createHash("sha256")
179
- .update(hashInput)
180
- .digest("hex")
181
- .slice(0, HASH_DISPLAY_LENGTH);
182
- const path = join(dir, `sandbox-profile-${hash}.sb`);
183
-
184
- const profile = buildSandboxProfile(allowNetwork, denyReadPaths).replace(
185
- /__WORKING_DIR__/g,
186
- () => escapeSBPL(workingDir),
187
- );
188
- writeFileSync(path, profile + "\n");
189
- return path;
190
- }
191
-
192
- /**
193
- * Cache positive bwrap results only. Negative results are not cached so that
194
- * installing bwrap after the daemon starts takes effect without a restart.
195
- */
196
- let bwrapAvailable = false;
197
-
198
- /**
199
- * Check whether bwrap is installed AND functional (can create namespaces).
200
- *
201
- * Just testing `bwrap --version` is not enough - the binary may exist but
202
- * namespace creation can be blocked by the kernel (e.g. inside containers
203
- * or when user namespaces are disabled). We run a minimal sandbox that
204
- * exercises all namespace types used by buildBwrapArgs() (mount, network,
205
- * PID) to verify end-to-end functionality.
206
- *
207
- * Only positive results are cached - if bwrap is unavailable, we re-check
208
- * on every call so that a mid-session install is picked up immediately.
209
- */
210
- function isBwrapAvailable(): boolean {
211
- if (bwrapAvailable) return true;
212
- try {
213
- execSync("bwrap --ro-bind / / --unshare-net --unshare-pid true", {
214
- stdio: "ignore",
215
- timeout: 5000,
216
- });
217
- bwrapAvailable = true;
218
- return true;
219
- } catch {
220
- return false;
221
- }
222
- }
223
-
224
- /**
225
- * Build bwrap arguments for Linux sandboxing.
226
- *
227
- * Strategy mirrors the macOS sandbox-exec profile:
228
- * - Read-only bind-mount of the root filesystem (toolchains, libs, etc.)
229
- * - Read-write bind-mount of the working directory
230
- * - Read-write tmpfs for /tmp
231
- * - /proc mounted for basic process operation
232
- * - /dev bind-mounted for device access (needed by many tools)
233
- * - Network access blocked (--unshare-net)
234
- * - PID namespace isolated (--unshare-pid)
235
- * - Optional tmpfs overlays on protected paths (CES lockdown)
236
- */
237
- function buildBwrapArgs(
238
- workingDir: string,
239
- command: string,
240
- allowNetwork: boolean,
241
- denyReadPaths?: string[],
242
- ): string[] {
243
- const args = [
244
- // Filesystem: read-only root, writable working dir and temp
245
- "--ro-bind",
246
- "/",
247
- "/",
248
- "--bind",
249
- workingDir,
250
- workingDir,
251
- "--bind",
252
- "/tmp",
253
- "/tmp",
254
- "--dev",
255
- "/dev",
256
- "--proc",
257
- "/proc",
258
- ];
259
-
260
- // CES shell lockdown: overlay protected paths with empty tmpfs mounts
261
- // so the subprocess cannot read credential data, bootstrap sockets, or
262
- // toolstore contents. The tmpfs mount hides the real directory contents.
263
- if (denyReadPaths && denyReadPaths.length > 0) {
264
- for (const p of denyReadPaths) {
265
- args.push("--tmpfs", p);
266
- }
267
- }
268
-
269
- // Only isolate the network namespace when network access is not needed.
270
- // In proxied mode the process must be able to reach 127.0.0.1:<proxy-port>.
271
- if (!allowNetwork) {
272
- args.push("--unshare-net");
273
- }
274
-
275
- args.push(
276
- "--unshare-pid",
277
- // Run bash inside the sandbox
278
- "bash",
279
- "-c",
280
- "--",
281
- command,
282
- );
283
-
284
- return args;
285
- }
286
-
287
- /**
288
- * Native sandbox backend using OS-level sandboxing:
289
- * macOS sandbox-exec (SBPL profiles) and Linux bwrap (bubblewrap).
290
- */
291
- export class NativeBackend implements SandboxBackend {
292
- wrap(
293
- command: string,
294
- workingDir: string,
295
- options?: WrapOptions,
296
- ): SandboxResult {
297
- const allowNetwork = options?.networkMode === "proxied";
298
- const denyReadPaths = options?.denyReadPaths;
299
-
300
- if (isMacOS()) {
301
- const profile = getProfilePath(workingDir, allowNetwork, denyReadPaths);
302
- return {
303
- command: "sandbox-exec",
304
- args: ["-f", profile, "bash", "-c", "--", command],
305
- sandboxed: true,
306
- };
307
- }
308
-
309
- if (isLinux()) {
310
- if (!isBwrapAvailable()) {
311
- const msg =
312
- "Sandbox is enabled but bwrap is not available or cannot create namespaces. Refusing to execute unsandboxed. Install bubblewrap (for example: apt install bubblewrap), or disable sandboxing.";
313
- log.error(msg);
314
- throw new ToolError(msg, "bash");
315
- }
316
- return {
317
- command: "bwrap",
318
- args: buildBwrapArgs(workingDir, command, allowNetwork, denyReadPaths),
319
- sandboxed: true,
320
- };
321
- }
322
-
323
- const msg = `Sandbox is enabled but not supported on this platform (${process.platform}). Refusing to execute unsandboxed. Disable sandboxing to run shell commands.`;
324
- log.error(msg);
325
- throw new ToolError(msg, "bash");
326
- }
327
- }
@@ -1,37 +0,0 @@
1
- export interface SandboxResult {
2
- /** The command/args to use for spawning. */
3
- command: string;
4
- args: string[];
5
- /** Whether sandboxing was applied. */
6
- sandboxed: boolean;
7
- }
8
-
9
- /** Per-invocation options that override backend defaults. */
10
- export interface WrapOptions {
11
- /**
12
- * Network mode for this invocation.
13
- * - 'off': network access is blocked (sandbox-exec deny network / bwrap --unshare-net). This is the default.
14
- * - 'proxied': network access is allowed so the process can reach the local credential proxy.
15
- */
16
- networkMode?: "off" | "proxied";
17
-
18
- /**
19
- * Absolute paths that should be blocked from read access inside the sandbox.
20
- * Used by CES shell lockdown to prevent untrusted shell commands from reading
21
- * protected credential data, bootstrap sockets, and toolstore paths.
22
- */
23
- denyReadPaths?: string[];
24
- }
25
-
26
- /**
27
- * A sandbox backend knows how to wrap a shell command so it runs
28
- * inside an OS-level sandbox (macOS sandbox-exec, Linux bwrap, etc.).
29
- */
30
- export interface SandboxBackend {
31
- /** Wrap a command for sandboxed execution in the given working directory. */
32
- wrap(
33
- command: string,
34
- workingDir: string,
35
- options?: WrapOptions,
36
- ): SandboxResult;
37
- }