@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,198 +0,0 @@
1
- /**
2
- * Tests for macOS TCC-protected directory deny rules in the sandbox profile.
3
- *
4
- * Verifies that the SBPL sandbox profile blocks access to TCC-protected
5
- * directories (Photos, Contacts, Calendar, etc.) to prevent macOS
6
- * permission prompts during filesystem traversal.
7
- */
8
-
9
- import { existsSync, readFileSync, unlinkSync } from "node:fs";
10
- import { join } from "node:path";
11
- import { afterAll, describe, expect, test } from "bun:test";
12
-
13
- import { MACOS_TCC_PROTECTED_PATHS } from "../tools/terminal/backends/native.js";
14
-
15
- // We can't call buildSandboxProfile directly (not exported), but we can
16
- // exercise it through NativeBackend.wrap() on macOS and inspect the
17
- // generated .sb profile file on disk.
18
-
19
- const isMacOS = process.platform === "darwin";
20
-
21
- describe("macOS TCC sandbox deny rules", () => {
22
- // On macOS, generate a profile and inspect it. On other platforms,
23
- // just verify the constant is well-formed.
24
-
25
- test("MACOS_TCC_PROTECTED_PATHS is non-empty", () => {
26
- expect(MACOS_TCC_PROTECTED_PATHS.length).toBeGreaterThan(0);
27
- });
28
-
29
- test("all paths are relative (no leading slash)", () => {
30
- for (const p of MACOS_TCC_PROTECTED_PATHS) {
31
- expect(p.startsWith("/")).toBe(false);
32
- }
33
- });
34
-
35
- test("no duplicate paths", () => {
36
- const unique = new Set(MACOS_TCC_PROTECTED_PATHS);
37
- expect(unique.size).toBe(MACOS_TCC_PROTECTED_PATHS.length);
38
- });
39
-
40
- if (isMacOS) {
41
- const profilePaths: string[] = [];
42
-
43
- // Generate a profile by calling NativeBackend.wrap()
44
- test("generated SBPL profile contains deny rules for all TCC paths", async () => {
45
- const { NativeBackend } =
46
- await import("../tools/terminal/backends/native.js");
47
- const backend = new NativeBackend();
48
- const result = backend.wrap("true", "/tmp/tcc-test", {
49
- networkMode: "off",
50
- });
51
-
52
- // The profile path is the second arg after -f
53
- const profilePath = result.args[1]!;
54
- profilePaths.push(profilePath);
55
- expect(existsSync(profilePath)).toBe(true);
56
-
57
- const profile = readFileSync(profilePath, "utf-8");
58
- const home = process.env.HOME ?? "";
59
- expect(home.length).toBeGreaterThan(0);
60
-
61
- for (const rel of MACOS_TCC_PROTECTED_PATHS) {
62
- const abs = join(home, rel);
63
- expect(profile).toContain(`(deny file-read* (subpath "${abs}")`);
64
- }
65
- });
66
-
67
- test("all TCC deny rules include (with no-log)", async () => {
68
- const { NativeBackend } =
69
- await import("../tools/terminal/backends/native.js");
70
- const backend = new NativeBackend();
71
- const result = backend.wrap("true", "/tmp/tcc-test-nolog", {
72
- networkMode: "off",
73
- });
74
-
75
- const profilePath = result.args[1]!;
76
- profilePaths.push(profilePath);
77
- const profile = readFileSync(profilePath, "utf-8");
78
- const home = process.env.HOME ?? "";
79
-
80
- for (const rel of MACOS_TCC_PROTECTED_PATHS) {
81
- const abs = join(home, rel);
82
- expect(profile).toContain(
83
- `(deny file-read* (subpath "${abs}") (with no-log))`,
84
- );
85
- }
86
- });
87
-
88
- test("TCC deny rules appear after (allow file-read*)", async () => {
89
- const { NativeBackend } =
90
- await import("../tools/terminal/backends/native.js");
91
- const backend = new NativeBackend();
92
- const result = backend.wrap("true", "/tmp/tcc-test-order", {
93
- networkMode: "off",
94
- });
95
-
96
- const profilePath = result.args[1]!;
97
- profilePaths.push(profilePath);
98
- const profile = readFileSync(profilePath, "utf-8");
99
- const home = process.env.HOME ?? "";
100
-
101
- const allowIdx = profile.indexOf("(allow file-read*)");
102
- expect(allowIdx).toBeGreaterThanOrEqual(0);
103
-
104
- for (const rel of MACOS_TCC_PROTECTED_PATHS) {
105
- const abs = join(home, rel);
106
- const denyIdx = profile.indexOf(`(deny file-read* (subpath "${abs}")`);
107
- expect(denyIdx).toBeGreaterThan(allowIdx);
108
- }
109
- });
110
-
111
- test("working directory under TCC path gets file-read re-allowed", async () => {
112
- const { NativeBackend } =
113
- await import("../tools/terminal/backends/native.js");
114
- const backend = new NativeBackend();
115
- const home = process.env.HOME ?? "";
116
- const workDir = join(home, "Documents", "my-project");
117
- const result = backend.wrap("true", workDir, {
118
- networkMode: "off",
119
- });
120
-
121
- const profilePath = result.args[1]!;
122
- profilePaths.push(profilePath);
123
- const profile = readFileSync(profilePath, "utf-8");
124
-
125
- // The deny rule for Documents should still be present
126
- expect(profile).toContain(
127
- `(deny file-read* (subpath "${join(home, "Documents")}") (with no-log))`,
128
- );
129
-
130
- // But the working directory should have a file-read allow AFTER the deny
131
- const denyIdx = profile.indexOf(
132
- `(deny file-read* (subpath "${join(home, "Documents")}")`,
133
- );
134
- const allowWorkDirIdx = profile.indexOf(
135
- `(allow file-read* (subpath "${workDir}"))`,
136
- );
137
- expect(allowWorkDirIdx).toBeGreaterThan(denyIdx);
138
- });
139
-
140
- test("CES deny-read rules override working-dir allow (credential isolation)", async () => {
141
- const { NativeBackend } =
142
- await import("../tools/terminal/backends/native.js");
143
- const backend = new NativeBackend();
144
- const home = process.env.HOME ?? "";
145
- // Simulate a working directory that overlaps with a CES-protected path
146
- const workDir = join(home, "Documents", "my-project");
147
- const cesProtectedPath = join(workDir, ".credentials");
148
- const result = backend.wrap("true", workDir, {
149
- networkMode: "off",
150
- denyReadPaths: [cesProtectedPath],
151
- });
152
-
153
- const profilePath = result.args[1]!;
154
- profilePaths.push(profilePath);
155
- const profile = readFileSync(profilePath, "utf-8");
156
-
157
- // The working-dir allow should be present
158
- const allowWorkDirIdx = profile.indexOf(
159
- `(allow file-read* (subpath "${workDir}"))`,
160
- );
161
- expect(allowWorkDirIdx).toBeGreaterThanOrEqual(0);
162
-
163
- // The CES deny rule should appear AFTER the working-dir allow
164
- const cesDenyIdx = profile.indexOf(
165
- `(deny file-read* (subpath "${cesProtectedPath}")`,
166
- );
167
- expect(cesDenyIdx).toBeGreaterThan(allowWorkDirIdx);
168
- });
169
-
170
- test("paths with spaces are handled correctly", async () => {
171
- const { NativeBackend } =
172
- await import("../tools/terminal/backends/native.js");
173
- const backend = new NativeBackend();
174
- const result = backend.wrap("true", "/tmp/tcc-test-spaces", {
175
- networkMode: "off",
176
- });
177
-
178
- const profilePath = result.args[1]!;
179
- profilePaths.push(profilePath);
180
- const profile = readFileSync(profilePath, "utf-8");
181
- const home = process.env.HOME ?? "";
182
-
183
- // Photos Library.photoslibrary has a space — verify it's in the profile
184
- const photosPath = join(home, "Pictures/Photos Library.photoslibrary");
185
- expect(profile).toContain(`(subpath "${photosPath}")`);
186
- });
187
-
188
- afterAll(() => {
189
- for (const p of profilePaths) {
190
- try {
191
- unlinkSync(p);
192
- } catch {
193
- // ignore cleanup errors
194
- }
195
- }
196
- });
197
- }
198
- });
@@ -1,374 +0,0 @@
1
- import * as realChildProcess from "node:child_process";
2
- import * as realFs from "node:fs";
3
- import { beforeEach, describe, expect, mock, test } from "bun:test";
4
-
5
- import type { SandboxConfig } from "../tools/terminal/sandbox.js";
6
-
7
- let platform = "linux";
8
-
9
- const execSyncMock = mock((_command: string): unknown => {
10
- throw new Error("bwrap unavailable");
11
- });
12
-
13
- mock.module("../util/platform.js", () => ({
14
- isMacOS: () => platform === "darwin",
15
- isLinux: () => platform === "linux",
16
- getSandboxWorkingDir: () => "/tmp/sandbox/fs",
17
- }));
18
-
19
- mock.module("../util/logger.js", () => ({
20
- getLogger: () => ({
21
- error: () => {},
22
- warn: () => {},
23
- info: () => {},
24
- debug: () => {},
25
- }),
26
- }));
27
-
28
- mock.module("node:child_process", () => ({
29
- ...realChildProcess,
30
- execSync: execSyncMock,
31
- }));
32
-
33
- const writeFileSyncMock = mock((..._args: unknown[]) => {});
34
- const existsSyncMock = mock((_path: string) => true);
35
- const mkdirSyncMock = mock((..._args: unknown[]) => {});
36
-
37
- mock.module("node:fs", () => ({
38
- ...realFs,
39
- writeFileSync: writeFileSyncMock,
40
- existsSync: existsSyncMock,
41
- mkdirSync: mkdirSyncMock,
42
- }));
43
-
44
- const { wrapCommand } = await import("../tools/terminal/sandbox.js");
45
- const { ToolError } = await import("../util/errors.js");
46
-
47
- function disabledConfig(): SandboxConfig {
48
- return { enabled: false };
49
- }
50
-
51
- function nativeConfig(): SandboxConfig {
52
- return { enabled: true };
53
- }
54
-
55
- describe("terminal sandbox — disabled behavior", () => {
56
- beforeEach(() => {
57
- platform = "linux";
58
- });
59
-
60
- test("returns unsandboxed bash -c wrapper when disabled", () => {
61
- const result = wrapCommand("pwd", "/tmp", disabledConfig());
62
- expect(result).toEqual({
63
- command: "bash",
64
- args: ["-c", "--", "pwd"],
65
- sandboxed: false,
66
- });
67
- });
68
-
69
- test("sandboxed flag is false when disabled regardless of platform", () => {
70
- for (const p of ["linux", "darwin", "win32"]) {
71
- platform = p;
72
- const result = wrapCommand("echo hi", "/tmp", disabledConfig());
73
- expect(result.sandboxed).toBe(false);
74
- expect(result.command).toBe("bash");
75
- }
76
- });
77
-
78
- test("preserves the original command string in args when disabled", () => {
79
- const cmd = "cat /etc/passwd | wc -l";
80
- const result = wrapCommand(cmd, "/home/user", disabledConfig());
81
- expect(result.args).toEqual(["-c", "--", cmd]);
82
- });
83
- });
84
-
85
- describe("terminal sandbox — enabled fail-closed behavior", () => {
86
- beforeEach(() => {
87
- platform = "linux";
88
- execSyncMock.mockImplementation((_command: string) => {
89
- throw new Error("bwrap unavailable");
90
- });
91
- });
92
-
93
- test("throws ToolError when bwrap is unavailable on linux", () => {
94
- expect(() => wrapCommand("echo hello", "/tmp", nativeConfig())).toThrow(
95
- ToolError,
96
- );
97
- expect(() => wrapCommand("echo hello", "/tmp", nativeConfig())).toThrow(
98
- "Sandbox is enabled but bwrap is not available or cannot create namespaces.",
99
- );
100
- });
101
-
102
- test("returns bwrap wrapper when bwrap is available on linux", () => {
103
- // GIVEN bwrap is available on a linux platform
104
- execSyncMock.mockImplementation(() => undefined);
105
-
106
- // WHEN wrapping a command with the native sandbox config
107
- const result = wrapCommand(
108
- "echo hello",
109
- "/home/user/project",
110
- nativeConfig(),
111
- );
112
-
113
- // THEN the result uses bwrap with network isolation
114
- expect(result.command).toBe("bwrap");
115
- expect(result.sandboxed).toBe(true);
116
- expect(result.args).toContain("--ro-bind");
117
- expect(result.args).toContain("--unshare-net");
118
- expect(result.args).toContain("--unshare-pid");
119
-
120
- // AND the user command runs via bash inside the sandbox
121
- const bashIdx = result.args.indexOf("bash");
122
- expect(bashIdx).toBeGreaterThan(0);
123
- expect(result.args.slice(bashIdx)).toEqual([
124
- "bash",
125
- "-c",
126
- "--",
127
- "echo hello",
128
- ]);
129
- });
130
-
131
- test("bind-mounts working directory read-write in bwrap args", () => {
132
- execSyncMock.mockImplementation(() => undefined);
133
- const workDir = "/home/user/my-project";
134
- const result = wrapCommand("ls", workDir, nativeConfig());
135
- // The args should contain --bind workDir workDir for read-write access
136
- const bindIdx = result.args.indexOf("--bind");
137
- expect(bindIdx).toBeGreaterThan(-1);
138
- expect(result.args[bindIdx + 1]).toBe(workDir);
139
- expect(result.args[bindIdx + 2]).toBe(workDir);
140
- });
141
- });
142
-
143
- describe("terminal sandbox — unsupported platform fail-closed behavior", () => {
144
- test("throws ToolError on unsupported platforms when enabled", () => {
145
- platform = "win32";
146
- expect(() => wrapCommand("pwd", "/tmp", nativeConfig())).toThrow(ToolError);
147
- expect(() => wrapCommand("pwd", "/tmp", nativeConfig())).toThrow(
148
- "Sandbox is enabled but not supported on this platform (",
149
- );
150
- });
151
-
152
- test("error message includes refusing to execute unsandboxed", () => {
153
- platform = "win32";
154
- try {
155
- wrapCommand("pwd", "/tmp", nativeConfig());
156
- throw new Error("should have thrown");
157
- } catch (err) {
158
- expect(err).toBeInstanceOf(ToolError);
159
- expect((err as Error).message).toContain(
160
- "Refusing to execute unsandboxed",
161
- );
162
- }
163
- });
164
- });
165
-
166
- describe("terminal sandbox — macOS sandbox-exec behavior", () => {
167
- beforeEach(() => {
168
- platform = "darwin";
169
- writeFileSyncMock.mockClear();
170
- existsSyncMock.mockImplementation(() => true);
171
- });
172
-
173
- test("returns sandbox-exec wrapper on macOS when enabled", () => {
174
- // GIVEN the platform is macOS
175
- // (set in beforeEach)
176
-
177
- // WHEN wrapping a command with the native sandbox config
178
- const result = wrapCommand("echo hello", "/tmp/project", nativeConfig());
179
-
180
- // THEN the result uses sandbox-exec
181
- expect(result.command).toBe("sandbox-exec");
182
- expect(result.sandboxed).toBe(true);
183
- expect(result.args[0]).toBe("-f");
184
-
185
- // AND the profile path is the second arg
186
- expect(result.args[1]).toContain("sandbox-profile-");
187
-
188
- // AND bash -c -- command follows the profile
189
- expect(result.args.slice(2)).toEqual(["bash", "-c", "--", "echo hello"]);
190
- });
191
-
192
- test("escapes SBPL metacharacters in working dirs instead of throwing", () => {
193
- // The sandbox now escapes metacharacters rather than rejecting them
194
- const result1 = wrapCommand("pwd", '/tmp/bad"dir', nativeConfig());
195
- expect(result1.sandboxed).toBe(true);
196
- const result2 = wrapCommand("pwd", "/tmp/bad(dir", nativeConfig());
197
- expect(result2.sandboxed).toBe(true);
198
- const result3 = wrapCommand("pwd", "/tmp/bad;dir", nativeConfig());
199
- expect(result3.sandboxed).toBe(true);
200
- });
201
-
202
- test("SBPL profile escapes metacharacters in working dir path", () => {
203
- // Verify the sandbox profile is written with escaped chars
204
- wrapCommand("pwd", '/tmp/bad"dir', nativeConfig());
205
- const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
206
- expect(profileContent).toContain('bad\\"dir');
207
- });
208
-
209
- test("SBPL profile allows writes to /dev/null", () => {
210
- wrapCommand("git status", "/tmp/project", nativeConfig());
211
- const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
212
- expect(profileContent).toContain('(literal "/dev/null")');
213
- });
214
- });
215
-
216
- describe("terminal sandbox — backend selection", () => {
217
- beforeEach(() => {
218
- platform = "darwin";
219
- writeFileSyncMock.mockClear();
220
- existsSyncMock.mockImplementation(() => true);
221
- });
222
-
223
- test('uses native backend when backend is "native"', () => {
224
- const result = wrapCommand("echo hello", "/tmp/project", nativeConfig());
225
- expect(result.command).toBe("sandbox-exec");
226
- expect(result.sandboxed).toBe(true);
227
- });
228
-
229
- test("disabled config returns unsandboxed wrapper", () => {
230
- const config: SandboxConfig = { enabled: false };
231
- const result = wrapCommand("echo hello", "/tmp/project", config);
232
- expect(result.command).toBe("bash");
233
- expect(result.sandboxed).toBe(false);
234
- });
235
- });
236
-
237
- describe("terminal sandbox — proxied network mode on Linux", () => {
238
- beforeEach(() => {
239
- platform = "linux";
240
- execSyncMock.mockImplementation(() => undefined);
241
- });
242
-
243
- test("omits --unshare-net when networkMode is proxied", () => {
244
- /**
245
- * Tests that bwrap args omit --unshare-net in proxied mode so the process
246
- * can reach the local credential proxy on 127.0.0.1.
247
- */
248
-
249
- // GIVEN bwrap is available on linux
250
- // (set in beforeEach)
251
-
252
- // WHEN wrapping a command with proxied network mode
253
- const result = wrapCommand(
254
- "curl https://example.com",
255
- "/home/user/project",
256
- nativeConfig(),
257
- { networkMode: "proxied" },
258
- );
259
-
260
- // THEN the result uses bwrap
261
- expect(result.command).toBe("bwrap");
262
- expect(result.sandboxed).toBe(true);
263
-
264
- // AND --unshare-net is NOT present (network is allowed)
265
- expect(result.args).not.toContain("--unshare-net");
266
-
267
- // AND --unshare-pid is still present (PID isolation remains)
268
- expect(result.args).toContain("--unshare-pid");
269
- });
270
-
271
- test("includes --unshare-net when networkMode is off", () => {
272
- /**
273
- * Tests that bwrap args include --unshare-net when network is off (default).
274
- */
275
-
276
- // GIVEN bwrap is available on linux
277
- // (set in beforeEach)
278
-
279
- // WHEN wrapping a command with network mode off
280
- const result = wrapCommand(
281
- "echo hello",
282
- "/home/user/project",
283
- nativeConfig(),
284
- { networkMode: "off" },
285
- );
286
-
287
- // THEN --unshare-net is present (network is blocked)
288
- expect(result.args).toContain("--unshare-net");
289
- });
290
-
291
- test("includes --unshare-net when no options are provided", () => {
292
- /**
293
- * Tests that the default behavior (no options) blocks network access.
294
- */
295
-
296
- // GIVEN bwrap is available on linux
297
- // (set in beforeEach)
298
-
299
- // WHEN wrapping a command without any options
300
- const result = wrapCommand(
301
- "echo hello",
302
- "/home/user/project",
303
- nativeConfig(),
304
- );
305
-
306
- // THEN --unshare-net is present (network is blocked by default)
307
- expect(result.args).toContain("--unshare-net");
308
- });
309
- });
310
-
311
- describe("terminal sandbox — proxied network mode on macOS", () => {
312
- beforeEach(() => {
313
- platform = "darwin";
314
- writeFileSyncMock.mockClear();
315
- existsSyncMock.mockImplementation(() => true);
316
- });
317
-
318
- test("writes SBPL profile with allow network when networkMode is proxied", () => {
319
- /**
320
- * Tests that the macOS sandbox profile allows network access in proxied mode
321
- * so the process can reach the local credential proxy.
322
- */
323
-
324
- // GIVEN the platform is macOS
325
- // (set in beforeEach)
326
-
327
- // WHEN wrapping a command with proxied network mode
328
- wrapCommand("curl https://example.com", "/tmp/project", nativeConfig(), {
329
- networkMode: "proxied",
330
- });
331
-
332
- // THEN the written profile contains (allow network*) instead of (deny network*)
333
- const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
334
- expect(profileContent).toContain("(allow network*)");
335
- expect(profileContent).not.toContain("(deny network*)");
336
- });
337
-
338
- test("writes SBPL profile with deny network when networkMode is off", () => {
339
- /**
340
- * Tests that the macOS sandbox profile blocks network access when network
341
- * mode is off (the default behavior).
342
- */
343
-
344
- // GIVEN the platform is macOS
345
- // (set in beforeEach)
346
-
347
- // WHEN wrapping a command with network mode off
348
- wrapCommand("echo hello", "/tmp/project", nativeConfig(), {
349
- networkMode: "off",
350
- });
351
-
352
- // THEN the written profile contains (deny network*)
353
- const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
354
- expect(profileContent).toContain("(deny network*)");
355
- expect(profileContent).not.toContain("(allow network*)");
356
- });
357
-
358
- test("writes SBPL profile with deny network when no options are provided", () => {
359
- /**
360
- * Tests that the default behavior (no options) blocks network access on macOS.
361
- */
362
-
363
- // GIVEN the platform is macOS
364
- // (set in beforeEach)
365
-
366
- // WHEN wrapping a command without any options
367
- wrapCommand("echo hello", "/tmp/project", nativeConfig());
368
-
369
- // THEN the written profile contains (deny network*)
370
- const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
371
- expect(profileContent).toContain("(deny network*)");
372
- expect(profileContent).not.toContain("(allow network*)");
373
- });
374
- });
@@ -1,65 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
-
3
- import type { ServerMessage } from "../daemon/message-protocol.js";
4
- import { EventBus } from "../events/bus.js";
5
- import type { AssistantDomainEvents } from "../events/domain-events.js";
6
- import { registerToolNotificationListener } from "../events/tool-notification-listener.js";
7
-
8
- describe("registerToolNotificationListener", () => {
9
- test("forwards tool.secret.detected events to secret_detected messages", async () => {
10
- const bus = new EventBus<AssistantDomainEvents>();
11
- const messages: ServerMessage[] = [];
12
- registerToolNotificationListener(bus, (msg) => messages.push(msg));
13
-
14
- await bus.emit("tool.secret.detected", {
15
- conversationId: "conversation-1",
16
- toolName: "file_read",
17
- action: "warn",
18
- matches: [
19
- {
20
- type: "AWS Access Key",
21
- redactedValue: '<redacted type="AWS Access Key" />',
22
- },
23
- ],
24
- detectedAtMs: 123,
25
- });
26
-
27
- expect(messages).toEqual([
28
- {
29
- type: "secret_detected",
30
- toolName: "file_read",
31
- action: "warn",
32
- matches: [
33
- {
34
- type: "AWS Access Key",
35
- redactedValue: '<redacted type="AWS Access Key" />',
36
- },
37
- ],
38
- },
39
- ]);
40
- });
41
-
42
- test("stops forwarding after subscription is disposed", async () => {
43
- const bus = new EventBus<AssistantDomainEvents>();
44
- const messages: ServerMessage[] = [];
45
- const subscription = registerToolNotificationListener(bus, (msg) =>
46
- messages.push(msg),
47
- );
48
-
49
- subscription.dispose();
50
- await bus.emit("tool.secret.detected", {
51
- conversationId: "conversation-1",
52
- toolName: "file_read",
53
- action: "warn",
54
- matches: [
55
- {
56
- type: "AWS Access Key",
57
- redactedValue: '<redacted type="AWS Access Key" />',
58
- },
59
- ],
60
- detectedAtMs: 123,
61
- });
62
-
63
- expect(messages).toHaveLength(0);
64
- });
65
- });