@vellumai/assistant 0.4.17 → 0.4.18

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 (515) hide show
  1. package/eslint.config.mjs +2 -2
  2. package/package.json +1 -1
  3. package/src/__tests__/access-request-decision.test.ts +128 -120
  4. package/src/__tests__/account-registry.test.ts +121 -110
  5. package/src/__tests__/active-skill-tools.test.ts +200 -172
  6. package/src/__tests__/actor-token-service.test.ts +341 -274
  7. package/src/__tests__/agent-loop-thinking.test.ts +28 -19
  8. package/src/__tests__/agent-loop.test.ts +798 -378
  9. package/src/__tests__/anthropic-provider.test.ts +405 -247
  10. package/src/__tests__/app-builder-tool-scripts.test.ts +97 -97
  11. package/src/__tests__/app-bundler.test.ts +112 -79
  12. package/src/__tests__/app-executors.test.ts +205 -178
  13. package/src/__tests__/app-git-history.test.ts +90 -73
  14. package/src/__tests__/app-git-service.test.ts +67 -53
  15. package/src/__tests__/app-open-proxy.test.ts +29 -25
  16. package/src/__tests__/approval-conversation-turn.test.ts +100 -81
  17. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +45 -17
  18. package/src/__tests__/approval-message-composer.test.ts +119 -119
  19. package/src/__tests__/approval-primitive.test.ts +264 -233
  20. package/src/__tests__/approval-routes-http.test.ts +4 -3
  21. package/src/__tests__/asset-materialize-tool.test.ts +250 -178
  22. package/src/__tests__/asset-search-tool.test.ts +251 -191
  23. package/src/__tests__/assistant-attachment-directive.test.ts +187 -142
  24. package/src/__tests__/assistant-attachments.test.ts +254 -186
  25. package/src/__tests__/assistant-event-hub.test.ts +105 -63
  26. package/src/__tests__/assistant-event.test.ts +66 -58
  27. package/src/__tests__/assistant-events-sse-hardening.test.ts +113 -73
  28. package/src/__tests__/assistant-feature-flag-guard.test.ts +78 -52
  29. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +48 -45
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +118 -77
  31. package/src/__tests__/assistant-id-boundary-guard.test.ts +158 -104
  32. package/src/__tests__/attachments-store.test.ts +240 -183
  33. package/src/__tests__/attachments.test.ts +70 -62
  34. package/src/__tests__/audit-log-rotation.test.ts +50 -35
  35. package/src/__tests__/browser-fill-credential.test.ts +169 -101
  36. package/src/__tests__/browser-manager.test.ts +97 -75
  37. package/src/__tests__/browser-runtime-check.test.ts +16 -15
  38. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +12 -10
  39. package/src/__tests__/browser-skill-endstate.test.ts +97 -72
  40. package/src/__tests__/bundle-scanner.test.ts +47 -22
  41. package/src/__tests__/bundled-asset.test.ts +74 -47
  42. package/src/__tests__/call-constants.test.ts +19 -19
  43. package/src/__tests__/call-controller.test.ts +0 -1
  44. package/src/__tests__/call-conversation-messages.test.ts +90 -65
  45. package/src/__tests__/call-domain.test.ts +149 -121
  46. package/src/__tests__/call-pointer-message-composer.test.ts +113 -83
  47. package/src/__tests__/call-pointer-messages.test.ts +213 -154
  48. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +9 -10
  49. package/src/__tests__/call-recovery.test.ts +232 -212
  50. package/src/__tests__/call-routes-http.test.ts +0 -1
  51. package/src/__tests__/call-start-guardian-guard.test.ts +32 -30
  52. package/src/__tests__/call-state-machine.test.ts +62 -51
  53. package/src/__tests__/call-state.test.ts +89 -75
  54. package/src/__tests__/call-store.test.ts +387 -316
  55. package/src/__tests__/callback-handoff-copy.test.ts +84 -82
  56. package/src/__tests__/canonical-guardian-store.test.ts +331 -280
  57. package/src/__tests__/channel-approval-routes.test.ts +1643 -1115
  58. package/src/__tests__/channel-approval.test.ts +139 -137
  59. package/src/__tests__/channel-approvals.test.ts +0 -1
  60. package/src/__tests__/channel-delivery-store.test.ts +232 -194
  61. package/src/__tests__/channel-guardian.test.ts +5 -3
  62. package/src/__tests__/channel-invite-transport.test.ts +107 -92
  63. package/src/__tests__/channel-policy.test.ts +42 -38
  64. package/src/__tests__/channel-readiness-service.test.ts +119 -102
  65. package/src/__tests__/channel-reply-delivery.test.ts +147 -118
  66. package/src/__tests__/channel-retry-sweep.test.ts +153 -110
  67. package/src/__tests__/checker.test.ts +3309 -1850
  68. package/src/__tests__/clarification-resolver.test.ts +91 -79
  69. package/src/__tests__/classifier.test.ts +64 -54
  70. package/src/__tests__/claude-code-skill-regression.test.ts +42 -37
  71. package/src/__tests__/claude-code-tool-profiles.test.ts +31 -29
  72. package/src/__tests__/clawhub.test.ts +92 -82
  73. package/src/__tests__/cli.test.ts +30 -30
  74. package/src/__tests__/clipboard.test.ts +53 -46
  75. package/src/__tests__/commit-guarantee.test.ts +59 -52
  76. package/src/__tests__/commit-message-enrichment-service.test.ts +203 -75
  77. package/src/__tests__/compaction.benchmark.test.ts +33 -31
  78. package/src/__tests__/computer-use-session-compaction.test.ts +60 -50
  79. package/src/__tests__/computer-use-session-lifecycle.test.ts +145 -117
  80. package/src/__tests__/computer-use-session-working-dir.test.ts +62 -48
  81. package/src/__tests__/computer-use-skill-baseline.test.ts +22 -19
  82. package/src/__tests__/computer-use-skill-endstate.test.ts +45 -31
  83. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +121 -88
  84. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +65 -42
  85. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +33 -18
  86. package/src/__tests__/computer-use-tools.test.ts +121 -98
  87. package/src/__tests__/config-schema.test.ts +443 -347
  88. package/src/__tests__/config-watcher.test.ts +96 -81
  89. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +148 -133
  90. package/src/__tests__/conflict-intent-tokenization.test.ts +96 -78
  91. package/src/__tests__/conflict-policy.test.ts +151 -80
  92. package/src/__tests__/conflict-store.test.ts +203 -157
  93. package/src/__tests__/connection-policy.test.ts +89 -59
  94. package/src/__tests__/contacts-tools.test.ts +247 -178
  95. package/src/__tests__/context-memory-e2e.test.ts +306 -214
  96. package/src/__tests__/context-token-estimator.test.ts +114 -74
  97. package/src/__tests__/context-window-manager.test.ts +269 -167
  98. package/src/__tests__/contradiction-checker.test.ts +161 -135
  99. package/src/__tests__/conversation-attention-store.test.ts +350 -290
  100. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  101. package/src/__tests__/conversation-pairing.test.ts +220 -113
  102. package/src/__tests__/conversation-store.test.ts +390 -235
  103. package/src/__tests__/credential-broker-browser-fill.test.ts +325 -250
  104. package/src/__tests__/credential-broker-server-use.test.ts +283 -243
  105. package/src/__tests__/credential-broker.test.ts +128 -74
  106. package/src/__tests__/credential-host-pattern-match.test.ts +64 -44
  107. package/src/__tests__/credential-metadata-store.test.ts +360 -311
  108. package/src/__tests__/credential-policy-validate.test.ts +81 -65
  109. package/src/__tests__/credential-resolve.test.ts +212 -145
  110. package/src/__tests__/credential-security-e2e.test.ts +144 -103
  111. package/src/__tests__/credential-security-invariants.test.ts +253 -208
  112. package/src/__tests__/credential-selection.test.ts +254 -146
  113. package/src/__tests__/credential-vault-unit.test.ts +531 -341
  114. package/src/__tests__/credential-vault.test.ts +761 -484
  115. package/src/__tests__/daemon-assistant-events.test.ts +91 -66
  116. package/src/__tests__/daemon-lifecycle.test.ts +258 -190
  117. package/src/__tests__/daemon-server-session-init.test.ts +0 -1
  118. package/src/__tests__/date-context.test.ts +314 -249
  119. package/src/__tests__/db-migration-rollback.test.ts +259 -130
  120. package/src/__tests__/db-schedule-syntax-migration.test.ts +78 -41
  121. package/src/__tests__/delete-managed-skill-tool.test.ts +77 -53
  122. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
  123. package/src/__tests__/dictation-mode-detection.test.ts +77 -55
  124. package/src/__tests__/dictation-profile-store.test.ts +70 -56
  125. package/src/__tests__/dictation-text-processing.test.ts +53 -35
  126. package/src/__tests__/diff.test.ts +102 -98
  127. package/src/__tests__/domain-normalize.test.ts +54 -54
  128. package/src/__tests__/domain-policy.test.ts +71 -55
  129. package/src/__tests__/dynamic-page-surface.test.ts +31 -33
  130. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +69 -69
  131. package/src/__tests__/edit-engine.test.ts +56 -56
  132. package/src/__tests__/elevenlabs-client.test.ts +117 -91
  133. package/src/__tests__/elevenlabs-config.test.ts +32 -31
  134. package/src/__tests__/email-classifier.test.ts +15 -12
  135. package/src/__tests__/email-cli.test.ts +121 -108
  136. package/src/__tests__/emit-signal-routing-intent.test.ts +76 -69
  137. package/src/__tests__/encrypted-store.test.ts +180 -154
  138. package/src/__tests__/entity-extractor.test.ts +108 -87
  139. package/src/__tests__/entity-search.test.ts +664 -258
  140. package/src/__tests__/ephemeral-permissions.test.ts +224 -188
  141. package/src/__tests__/event-bus.test.ts +81 -77
  142. package/src/__tests__/extract-email.test.ts +29 -20
  143. package/src/__tests__/file-edit-tool.test.ts +62 -44
  144. package/src/__tests__/file-ops-service.test.ts +131 -114
  145. package/src/__tests__/file-read-tool.test.ts +48 -31
  146. package/src/__tests__/file-write-tool.test.ts +43 -37
  147. package/src/__tests__/filesystem-tools.test.ts +238 -209
  148. package/src/__tests__/followup-tools.test.ts +237 -162
  149. package/src/__tests__/forbidden-legacy-symbols.test.ts +19 -20
  150. package/src/__tests__/frontmatter.test.ts +96 -81
  151. package/src/__tests__/fuzzy-match-property.test.ts +75 -81
  152. package/src/__tests__/fuzzy-match.test.ts +71 -65
  153. package/src/__tests__/gateway-client-managed-outbound.test.ts +76 -57
  154. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  155. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  156. package/src/__tests__/gemini-image-service.test.ts +113 -100
  157. package/src/__tests__/gemini-provider.test.ts +297 -220
  158. package/src/__tests__/get-weather.test.ts +188 -114
  159. package/src/__tests__/gmail-integration.test.ts +0 -1
  160. package/src/__tests__/guardian-action-conversation-turn.test.ts +226 -171
  161. package/src/__tests__/guardian-action-copy-generator.test.ts +111 -93
  162. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
  163. package/src/__tests__/guardian-action-followup-store.test.ts +199 -167
  164. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +297 -250
  165. package/src/__tests__/guardian-action-late-reply.test.ts +462 -316
  166. package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +23 -18
  167. package/src/__tests__/guardian-action-store.test.ts +158 -109
  168. package/src/__tests__/guardian-action-sweep.test.ts +114 -100
  169. package/src/__tests__/guardian-actions-endpoint.test.ts +440 -256
  170. package/src/__tests__/guardian-control-plane-policy.test.ts +497 -331
  171. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +217 -215
  172. package/src/__tests__/guardian-dispatch.test.ts +316 -256
  173. package/src/__tests__/guardian-grant-minting.test.ts +247 -178
  174. package/src/__tests__/guardian-outbound-http.test.ts +5 -3
  175. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +99 -96
  176. package/src/__tests__/guardian-question-copy.test.ts +17 -17
  177. package/src/__tests__/guardian-question-mode.test.ts +134 -100
  178. package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
  179. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  180. package/src/__tests__/guardian-verification-intent-routing.test.ts +94 -88
  181. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  182. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +0 -1
  183. package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -1
  184. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +92 -76
  185. package/src/__tests__/handlers-cu-observation-blob.test.ts +103 -70
  186. package/src/__tests__/handlers-ipc-blob-probe.test.ts +77 -51
  187. package/src/__tests__/handlers-slack-config.test.ts +63 -54
  188. package/src/__tests__/handlers-task-submit-slash.test.ts +18 -18
  189. package/src/__tests__/handlers-telegram-config.test.ts +662 -329
  190. package/src/__tests__/handlers-twitter-config.test.ts +525 -298
  191. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +3 -2
  192. package/src/__tests__/headless-browser-interactions.test.ts +444 -280
  193. package/src/__tests__/headless-browser-navigate.test.ts +116 -79
  194. package/src/__tests__/headless-browser-read-tools.test.ts +123 -86
  195. package/src/__tests__/headless-browser-snapshot.test.ts +71 -56
  196. package/src/__tests__/heartbeat-service.test.ts +76 -58
  197. package/src/__tests__/history-repair-observability.test.ts +14 -14
  198. package/src/__tests__/history-repair.test.ts +171 -167
  199. package/src/__tests__/home-base-bootstrap.test.ts +30 -27
  200. package/src/__tests__/hooks-blocking.test.ts +86 -37
  201. package/src/__tests__/hooks-cli.test.ts +104 -68
  202. package/src/__tests__/hooks-config.test.ts +81 -43
  203. package/src/__tests__/hooks-discovery.test.ts +106 -96
  204. package/src/__tests__/hooks-integration.test.ts +78 -72
  205. package/src/__tests__/hooks-manager.test.ts +99 -61
  206. package/src/__tests__/hooks-runner.test.ts +94 -71
  207. package/src/__tests__/hooks-settings.test.ts +69 -64
  208. package/src/__tests__/hooks-templates.test.ts +85 -54
  209. package/src/__tests__/hooks-ts-runner.test.ts +82 -45
  210. package/src/__tests__/hooks-watch.test.ts +32 -22
  211. package/src/__tests__/host-file-edit-tool.test.ts +190 -148
  212. package/src/__tests__/host-file-read-tool.test.ts +86 -63
  213. package/src/__tests__/host-file-write-tool.test.ts +98 -64
  214. package/src/__tests__/host-shell-tool.test.ts +342 -233
  215. package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
  216. package/src/__tests__/ingress-member-store.test.ts +163 -159
  217. package/src/__tests__/ingress-reconcile.test.ts +0 -1
  218. package/src/__tests__/ingress-routes-http.test.ts +441 -356
  219. package/src/__tests__/ingress-url-consistency.test.ts +125 -64
  220. package/src/__tests__/integration-status.test.ts +93 -73
  221. package/src/__tests__/intent-routing.test.ts +148 -118
  222. package/src/__tests__/invite-redemption-service.test.ts +163 -121
  223. package/src/__tests__/ipc-blob-store.test.ts +104 -91
  224. package/src/__tests__/ipc-contract-inventory.test.ts +27 -15
  225. package/src/__tests__/ipc-contract.test.ts +24 -23
  226. package/src/__tests__/ipc-protocol.test.ts +52 -46
  227. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +61 -50
  228. package/src/__tests__/ipc-snapshot.test.ts +1135 -1056
  229. package/src/__tests__/ipc-validate.test.ts +240 -179
  230. package/src/__tests__/key-migration.test.ts +123 -90
  231. package/src/__tests__/keychain.test.ts +150 -123
  232. package/src/__tests__/lifecycle-docs-guard.test.ts +65 -64
  233. package/src/__tests__/llm-usage-store.test.ts +112 -87
  234. package/src/__tests__/managed-skill-lifecycle.test.ts +147 -108
  235. package/src/__tests__/managed-store.test.ts +411 -360
  236. package/src/__tests__/mcp-cli.test.ts +189 -123
  237. package/src/__tests__/mcp-health-check.test.ts +26 -21
  238. package/src/__tests__/media-generate-image.test.ts +122 -99
  239. package/src/__tests__/media-reuse-story.e2e.test.ts +282 -214
  240. package/src/__tests__/media-visibility-policy.test.ts +86 -38
  241. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +146 -100
  242. package/src/__tests__/memory-lifecycle-e2e.test.ts +385 -297
  243. package/src/__tests__/memory-query-builder.test.ts +32 -33
  244. package/src/__tests__/memory-recall-quality.test.ts +761 -407
  245. package/src/__tests__/memory-regressions.experimental.test.ts +443 -380
  246. package/src/__tests__/memory-regressions.test.ts +3725 -2642
  247. package/src/__tests__/memory-retrieval-budget.test.ts +7 -8
  248. package/src/__tests__/memory-retrieval.benchmark.test.ts +144 -109
  249. package/src/__tests__/memory-upsert-concurrency.test.ts +292 -201
  250. package/src/__tests__/messaging-send-tool.test.ts +36 -29
  251. package/src/__tests__/migration-cli-flows.test.ts +69 -53
  252. package/src/__tests__/migration-ordering.test.ts +103 -86
  253. package/src/__tests__/mime-builder.test.ts +55 -32
  254. package/src/__tests__/mock-signup-server.test.ts +384 -246
  255. package/src/__tests__/model-intents.test.ts +61 -37
  256. package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +9 -12
  257. package/src/__tests__/no-is-trusted-guard.test.ts +24 -21
  258. package/src/__tests__/non-member-access-request.test.ts +3 -2
  259. package/src/__tests__/notification-broadcaster.test.ts +99 -81
  260. package/src/__tests__/notification-decision-fallback.test.ts +223 -178
  261. package/src/__tests__/notification-decision-strategy.test.ts +375 -337
  262. package/src/__tests__/notification-deep-link.test.ts +67 -61
  263. package/src/__tests__/notification-guardian-path.test.ts +248 -206
  264. package/src/__tests__/notification-routing-intent.test.ts +166 -93
  265. package/src/__tests__/notification-thread-candidate-validation.test.ts +78 -75
  266. package/src/__tests__/notification-thread-candidates.test.ts +64 -61
  267. package/src/__tests__/oauth-callback-registry.test.ts +40 -30
  268. package/src/__tests__/oauth-connect-handler.test.ts +109 -89
  269. package/src/__tests__/oauth-scope-policy.test.ts +63 -55
  270. package/src/__tests__/oauth2-gateway-transport.test.ts +252 -174
  271. package/src/__tests__/onboarding-starter-tasks.test.ts +93 -89
  272. package/src/__tests__/onboarding-template-contract.test.ts +93 -94
  273. package/src/__tests__/openai-provider.test.ts +366 -274
  274. package/src/__tests__/pairing-concurrent.test.ts +18 -12
  275. package/src/__tests__/pairing-routes.test.ts +45 -41
  276. package/src/__tests__/parallel-tool.benchmark.test.ts +108 -58
  277. package/src/__tests__/parser.test.ts +316 -226
  278. package/src/__tests__/path-classifier.test.ts +24 -25
  279. package/src/__tests__/path-policy.test.ts +187 -147
  280. package/src/__tests__/phone.test.ts +36 -36
  281. package/src/__tests__/platform-move-helper.test.ts +48 -40
  282. package/src/__tests__/platform-socket-path.test.ts +23 -24
  283. package/src/__tests__/platform-workspace-migration.test.ts +464 -414
  284. package/src/__tests__/platform.test.ts +61 -53
  285. package/src/__tests__/playbook-execution.test.ts +397 -265
  286. package/src/__tests__/playbook-tools.test.ts +267 -196
  287. package/src/__tests__/prebuilt-home-base-seed.test.ts +30 -27
  288. package/src/__tests__/pricing.test.ts +316 -136
  289. package/src/__tests__/profile-compiler.test.ts +206 -188
  290. package/src/__tests__/provider-commit-message-generator.test.ts +114 -106
  291. package/src/__tests__/provider-error-scenarios.test.ts +212 -158
  292. package/src/__tests__/provider-fail-open-selection.test.ts +51 -44
  293. package/src/__tests__/provider-registry-ollama.test.ts +13 -9
  294. package/src/__tests__/provider-streaming.benchmark.test.ts +232 -183
  295. package/src/__tests__/proxy-approval-callback.test.ts +180 -119
  296. package/src/__tests__/public-ingress-urls.test.ts +112 -94
  297. package/src/__tests__/qdrant-manager.test.ts +147 -98
  298. package/src/__tests__/ratelimit.test.ts +152 -82
  299. package/src/__tests__/recording-handler.test.ts +273 -151
  300. package/src/__tests__/recording-intent-fallback.test.ts +94 -75
  301. package/src/__tests__/recording-intent-handler.test.ts +0 -1
  302. package/src/__tests__/recording-intent.test.ts +578 -379
  303. package/src/__tests__/recording-state-machine.test.ts +530 -316
  304. package/src/__tests__/recurrence-engine-rruleset.test.ts +150 -92
  305. package/src/__tests__/recurrence-engine.test.ts +81 -41
  306. package/src/__tests__/recurrence-types.test.ts +63 -44
  307. package/src/__tests__/relay-server.test.ts +2131 -1602
  308. package/src/__tests__/reminder-store.test.ts +158 -80
  309. package/src/__tests__/reminder.test.ts +113 -109
  310. package/src/__tests__/remote-skill-policy.test.ts +96 -72
  311. package/src/__tests__/request-file-tool.test.ts +74 -67
  312. package/src/__tests__/response-tier.test.ts +131 -74
  313. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  314. package/src/__tests__/runtime-events-sse-parity.test.ts +167 -145
  315. package/src/__tests__/runtime-events-sse.test.ts +0 -1
  316. package/src/__tests__/sandbox-diagnostics.test.ts +66 -56
  317. package/src/__tests__/sandbox-host-parity.test.ts +377 -301
  318. package/src/__tests__/scaffold-managed-skill-tool.test.ts +213 -161
  319. package/src/__tests__/schedule-store.test.ts +268 -205
  320. package/src/__tests__/schedule-tools.test.ts +702 -524
  321. package/src/__tests__/scheduler-recurrence.test.ts +240 -130
  322. package/src/__tests__/scoped-approval-grants.test.ts +258 -168
  323. package/src/__tests__/scoped-grant-security-matrix.test.ts +160 -146
  324. package/src/__tests__/script-proxy-certs.test.ts +38 -35
  325. package/src/__tests__/script-proxy-connect-tunnel.test.ts +71 -46
  326. package/src/__tests__/script-proxy-decision-trace.test.ts +161 -84
  327. package/src/__tests__/script-proxy-http-forwarder.test.ts +146 -129
  328. package/src/__tests__/script-proxy-injection-runtime.test.ts +139 -113
  329. package/src/__tests__/script-proxy-mitm-handler.test.ts +226 -142
  330. package/src/__tests__/script-proxy-policy-runtime.test.ts +126 -86
  331. package/src/__tests__/script-proxy-policy.test.ts +308 -153
  332. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +74 -62
  333. package/src/__tests__/script-proxy-router.test.ts +111 -77
  334. package/src/__tests__/script-proxy-session-manager.test.ts +156 -113
  335. package/src/__tests__/script-proxy-session-runtime.test.ts +28 -24
  336. package/src/__tests__/secret-allowlist.test.ts +105 -90
  337. package/src/__tests__/secret-ingress-handler.test.ts +41 -30
  338. package/src/__tests__/secret-onetime-send.test.ts +67 -50
  339. package/src/__tests__/secret-prompt-log-hygiene.test.ts +35 -31
  340. package/src/__tests__/secret-response-routing.test.ts +50 -41
  341. package/src/__tests__/secret-scanner-executor.test.ts +152 -111
  342. package/src/__tests__/secret-scanner.test.ts +495 -413
  343. package/src/__tests__/secure-keys.test.ts +132 -121
  344. package/src/__tests__/send-endpoint-busy.test.ts +0 -1
  345. package/src/__tests__/send-notification-tool.test.ts +43 -42
  346. package/src/__tests__/sensitive-output-placeholders.test.ts +72 -64
  347. package/src/__tests__/sequence-store.test.ts +335 -167
  348. package/src/__tests__/server-history-render.test.ts +341 -202
  349. package/src/__tests__/session-abort-tool-results.test.ts +133 -70
  350. package/src/__tests__/session-confirmation-signals.test.ts +252 -160
  351. package/src/__tests__/session-conflict-gate.test.ts +775 -585
  352. package/src/__tests__/session-error.test.ts +222 -191
  353. package/src/__tests__/session-evictor.test.ts +79 -62
  354. package/src/__tests__/session-init.benchmark.test.ts +170 -108
  355. package/src/__tests__/session-load-history-repair.test.ts +273 -139
  356. package/src/__tests__/session-messaging-secret-redirect.test.ts +130 -90
  357. package/src/__tests__/session-pre-run-repair.test.ts +106 -59
  358. package/src/__tests__/session-profile-injection.test.ts +198 -130
  359. package/src/__tests__/session-provider-retry-repair.test.ts +223 -141
  360. package/src/__tests__/session-queue.test.ts +624 -321
  361. package/src/__tests__/session-runtime-assembly.test.ts +425 -329
  362. package/src/__tests__/session-runtime-workspace.test.ts +69 -61
  363. package/src/__tests__/session-skill-tools.test.ts +973 -678
  364. package/src/__tests__/session-slash-known.test.ts +185 -133
  365. package/src/__tests__/session-slash-queue.test.ts +147 -81
  366. package/src/__tests__/session-slash-unknown.test.ts +135 -90
  367. package/src/__tests__/session-surfaces-task-progress.test.ts +122 -87
  368. package/src/__tests__/session-tool-setup-app-refresh.test.ts +338 -177
  369. package/src/__tests__/session-tool-setup-memory-scope.test.ts +63 -40
  370. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +60 -37
  371. package/src/__tests__/session-tool-setup-tools-disabled.test.ts +28 -26
  372. package/src/__tests__/session-undo.test.ts +43 -30
  373. package/src/__tests__/session-workspace-cache-state.test.ts +108 -67
  374. package/src/__tests__/session-workspace-injection.test.ts +245 -117
  375. package/src/__tests__/session-workspace-tool-tracking.test.ts +260 -93
  376. package/src/__tests__/shared-filesystem-errors.test.ts +47 -47
  377. package/src/__tests__/shell-credential-ref.test.ts +126 -90
  378. package/src/__tests__/shell-identity.test.ts +134 -111
  379. package/src/__tests__/shell-parser-fuzz.test.ts +263 -179
  380. package/src/__tests__/shell-parser-property.test.ts +435 -288
  381. package/src/__tests__/shell-tool-proxy-mode.test.ts +142 -70
  382. package/src/__tests__/size-guard.test.ts +42 -44
  383. package/src/__tests__/skill-feature-flags-integration.test.ts +79 -52
  384. package/src/__tests__/skill-feature-flags.test.ts +75 -47
  385. package/src/__tests__/skill-include-graph.test.ts +143 -148
  386. package/src/__tests__/skill-load-feature-flag.test.ts +94 -59
  387. package/src/__tests__/skill-load-tool.test.ts +371 -199
  388. package/src/__tests__/skill-projection-feature-flag.test.ts +131 -88
  389. package/src/__tests__/skill-projection.benchmark.test.ts +93 -65
  390. package/src/__tests__/skill-script-runner-host.test.ts +460 -250
  391. package/src/__tests__/skill-script-runner-sandbox.test.ts +168 -108
  392. package/src/__tests__/skill-script-runner.test.ts +115 -74
  393. package/src/__tests__/skill-tool-factory.test.ts +140 -96
  394. package/src/__tests__/skill-tool-manifest.test.ts +306 -210
  395. package/src/__tests__/skill-version-hash.test.ts +70 -56
  396. package/src/__tests__/skills.test.ts +0 -1
  397. package/src/__tests__/slack-channel-config.test.ts +127 -84
  398. package/src/__tests__/slack-skill.test.ts +60 -47
  399. package/src/__tests__/slash-commands-catalog.test.ts +37 -31
  400. package/src/__tests__/slash-commands-parser.test.ts +71 -64
  401. package/src/__tests__/slash-commands-resolver.test.ts +143 -107
  402. package/src/__tests__/slash-commands-rewrite.test.ts +22 -22
  403. package/src/__tests__/speaker-identification.test.ts +28 -25
  404. package/src/__tests__/starter-bundle.test.ts +27 -23
  405. package/src/__tests__/starter-task-flow.test.ts +67 -52
  406. package/src/__tests__/subagent-manager-notify.test.ts +154 -108
  407. package/src/__tests__/subagent-tools.test.ts +311 -270
  408. package/src/__tests__/subagent-types.test.ts +40 -40
  409. package/src/__tests__/surface-mutex-cleanup.test.ts +42 -30
  410. package/src/__tests__/swarm-dag-pathological.test.ts +122 -111
  411. package/src/__tests__/swarm-orchestrator.test.ts +135 -101
  412. package/src/__tests__/swarm-plan-validator.test.ts +125 -73
  413. package/src/__tests__/swarm-recursion.test.ts +58 -46
  414. package/src/__tests__/swarm-router-planner.test.ts +99 -74
  415. package/src/__tests__/swarm-session-integration.test.ts +148 -91
  416. package/src/__tests__/swarm-tool.test.ts +65 -45
  417. package/src/__tests__/swarm-worker-backend.test.ts +59 -45
  418. package/src/__tests__/swarm-worker-runner.test.ts +133 -118
  419. package/src/__tests__/system-prompt.test.ts +290 -256
  420. package/src/__tests__/task-compiler.test.ts +176 -120
  421. package/src/__tests__/task-management-tools.test.ts +561 -456
  422. package/src/__tests__/task-memory-cleanup.test.ts +627 -362
  423. package/src/__tests__/task-runner.test.ts +117 -94
  424. package/src/__tests__/task-scheduler.test.ts +113 -84
  425. package/src/__tests__/task-tools.test.ts +349 -264
  426. package/src/__tests__/terminal-sandbox.test.ts +138 -108
  427. package/src/__tests__/terminal-tools.test.ts +350 -305
  428. package/src/__tests__/thread-seed-composer.test.ts +307 -180
  429. package/src/__tests__/tool-approval-handler.test.ts +238 -137
  430. package/src/__tests__/tool-audit-listener.test.ts +69 -69
  431. package/src/__tests__/tool-domain-event-publisher.test.ts +142 -132
  432. package/src/__tests__/tool-execution-abort-cleanup.test.ts +153 -146
  433. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +136 -105
  434. package/src/__tests__/tool-executor-lifecycle-events.test.ts +355 -239
  435. package/src/__tests__/tool-executor-redaction.test.ts +112 -109
  436. package/src/__tests__/tool-executor-shell-integration.test.ts +130 -79
  437. package/src/__tests__/tool-executor.test.ts +1274 -674
  438. package/src/__tests__/tool-grant-request-escalation.test.ts +401 -283
  439. package/src/__tests__/tool-metrics-listener.test.ts +97 -85
  440. package/src/__tests__/tool-notification-listener.test.ts +42 -25
  441. package/src/__tests__/tool-permission-simulate-handler.test.ts +137 -113
  442. package/src/__tests__/tool-policy.test.ts +44 -25
  443. package/src/__tests__/tool-profiling-listener.test.ts +99 -93
  444. package/src/__tests__/tool-result-truncation.test.ts +5 -4
  445. package/src/__tests__/tool-trace-listener.test.ts +131 -111
  446. package/src/__tests__/top-level-renderer.test.ts +62 -58
  447. package/src/__tests__/top-level-scanner.test.ts +68 -64
  448. package/src/__tests__/trace-emitter.test.ts +56 -56
  449. package/src/__tests__/trust-context-guards.test.ts +65 -65
  450. package/src/__tests__/trust-store.test.ts +1239 -806
  451. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  452. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  453. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +3 -2
  454. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -2
  455. package/src/__tests__/trusted-contact-verification.test.ts +251 -231
  456. package/src/__tests__/turn-commit.test.ts +259 -200
  457. package/src/__tests__/twilio-provider.test.ts +140 -126
  458. package/src/__tests__/twilio-rest.test.ts +22 -18
  459. package/src/__tests__/twilio-routes-elevenlabs.test.ts +0 -1
  460. package/src/__tests__/twilio-routes-twiml.test.ts +55 -55
  461. package/src/__tests__/twilio-routes.test.ts +0 -1
  462. package/src/__tests__/twitter-auth-handler.test.ts +184 -139
  463. package/src/__tests__/twitter-cli-error-shaping.test.ts +88 -73
  464. package/src/__tests__/twitter-cli-routing.test.ts +146 -99
  465. package/src/__tests__/twitter-oauth-client.test.ts +82 -65
  466. package/src/__tests__/update-bulletin-format.test.ts +69 -66
  467. package/src/__tests__/update-bulletin-state.test.ts +66 -60
  468. package/src/__tests__/update-bulletin.test.ts +150 -114
  469. package/src/__tests__/update-template-contract.test.ts +15 -10
  470. package/src/__tests__/url-safety.test.ts +288 -265
  471. package/src/__tests__/user-reference.test.ts +32 -32
  472. package/src/__tests__/view-image-tool.test.ts +118 -96
  473. package/src/__tests__/voice-invite-redemption.test.ts +111 -106
  474. package/src/__tests__/voice-quality.test.ts +117 -102
  475. package/src/__tests__/voice-scoped-grant-consumer.test.ts +204 -146
  476. package/src/__tests__/voice-session-bridge.test.ts +351 -216
  477. package/src/__tests__/weather-skill-regression.test.ts +170 -120
  478. package/src/__tests__/web-fetch.test.ts +664 -526
  479. package/src/__tests__/web-search.test.ts +379 -213
  480. package/src/__tests__/work-item-output.test.ts +90 -53
  481. package/src/__tests__/workspace-git-service.test.ts +437 -356
  482. package/src/__tests__/workspace-heartbeat-service.test.ts +125 -91
  483. package/src/__tests__/workspace-lifecycle.test.ts +98 -64
  484. package/src/__tests__/workspace-policy.test.ts +139 -71
  485. package/src/commands/__tests__/cc-command-registry.test.ts +142 -134
  486. package/src/config/__tests__/feature-flag-registry-guard.test.ts +48 -39
  487. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +25 -10
  488. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +0 -1
  489. package/src/config/bundled-skills/messaging/SKILL.md +4 -3
  490. package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +15 -5
  491. package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +16 -5
  492. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +34 -32
  493. package/src/config/bundled-tool-registry.ts +2 -0
  494. package/src/config/env.ts +3 -4
  495. package/src/memory/db-connection.ts +16 -10
  496. package/src/messaging/providers/gmail/adapter.ts +10 -3
  497. package/src/messaging/providers/gmail/client.ts +280 -72
  498. package/src/runtime/auth/__tests__/context.test.ts +75 -65
  499. package/src/runtime/auth/__tests__/credential-service.test.ts +137 -114
  500. package/src/runtime/auth/__tests__/guard-tests.test.ts +84 -90
  501. package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +40 -40
  502. package/src/runtime/auth/__tests__/middleware.test.ts +80 -74
  503. package/src/runtime/auth/__tests__/policy.test.ts +9 -9
  504. package/src/runtime/auth/__tests__/route-policy.test.ts +76 -65
  505. package/src/runtime/auth/__tests__/scopes.test.ts +68 -60
  506. package/src/runtime/auth/__tests__/subject.test.ts +54 -54
  507. package/src/runtime/auth/__tests__/token-service.test.ts +115 -108
  508. package/src/runtime/auth/scopes.ts +3 -0
  509. package/src/runtime/auth/token-service.ts +4 -1
  510. package/src/runtime/auth/types.ts +2 -1
  511. package/src/runtime/http-server.ts +2 -1
  512. package/src/security/secure-keys.ts +103 -53
  513. package/src/tools/browser/__tests__/auth-cache.test.ts +69 -63
  514. package/src/tools/browser/__tests__/auth-detector.test.ts +218 -157
  515. package/src/tools/browser/__tests__/jit-auth.test.ts +83 -99
@@ -1,68 +1,74 @@
1
- import { describe, expect,test } from 'bun:test';
1
+ import { describe, expect, test } from "bun:test";
2
2
 
3
- import { attachmentsToContentBlocks } from '../agent/attachments.js';
4
- import { createUserMessage } from '../agent/message-types.js';
3
+ import { attachmentsToContentBlocks } from "../agent/attachments.js";
4
+ import { createUserMessage } from "../agent/message-types.js";
5
5
 
6
6
  // ---------------------------------------------------------------------------
7
7
  // attachmentsToContentBlocks
8
8
  // ---------------------------------------------------------------------------
9
9
 
10
- describe('attachmentsToContentBlocks', () => {
11
- test('creates image content block for image/jpeg', () => {
10
+ describe("attachmentsToContentBlocks", () => {
11
+ test("creates image content block for image/jpeg", () => {
12
12
  const blocks = attachmentsToContentBlocks([
13
- { filename: 'photo.jpg', mimeType: 'image/jpeg', data: 'base64data' },
13
+ { filename: "photo.jpg", mimeType: "image/jpeg", data: "base64data" },
14
14
  ]);
15
15
 
16
16
  expect(blocks).toHaveLength(1);
17
- expect(blocks[0].type).toBe('image');
18
- const block = blocks[0] as { type: 'image'; source: { type: string; media_type: string; data: string } };
19
- expect(block.source.type).toBe('base64');
20
- expect(block.source.media_type).toBe('image/jpeg');
21
- expect(block.source.data).toBe('base64data');
17
+ expect(blocks[0].type).toBe("image");
18
+ const block = blocks[0] as {
19
+ type: "image";
20
+ source: { type: string; media_type: string; data: string };
21
+ };
22
+ expect(block.source.type).toBe("base64");
23
+ expect(block.source.media_type).toBe("image/jpeg");
24
+ expect(block.source.data).toBe("base64data");
22
25
  });
23
26
 
24
- test('creates image content block for image/png', () => {
27
+ test("creates image content block for image/png", () => {
25
28
  const blocks = attachmentsToContentBlocks([
26
- { filename: 'screenshot.png', mimeType: 'image/png', data: 'pngdata' },
29
+ { filename: "screenshot.png", mimeType: "image/png", data: "pngdata" },
27
30
  ]);
28
31
 
29
32
  expect(blocks).toHaveLength(1);
30
- expect(blocks[0].type).toBe('image');
33
+ expect(blocks[0].type).toBe("image");
31
34
  });
32
35
 
33
- test('creates image content block for image/webp', () => {
36
+ test("creates image content block for image/webp", () => {
34
37
  const blocks = attachmentsToContentBlocks([
35
- { filename: 'sticker.webp', mimeType: 'image/webp', data: 'webpdata' },
38
+ { filename: "sticker.webp", mimeType: "image/webp", data: "webpdata" },
36
39
  ]);
37
40
 
38
41
  expect(blocks).toHaveLength(1);
39
- expect(blocks[0].type).toBe('image');
42
+ expect(blocks[0].type).toBe("image");
40
43
  });
41
44
 
42
- test('creates file content block for non-image mime types', () => {
45
+ test("creates file content block for non-image mime types", () => {
43
46
  const blocks = attachmentsToContentBlocks([
44
- { filename: 'doc.pdf', mimeType: 'application/pdf', data: 'pdfdata' },
47
+ { filename: "doc.pdf", mimeType: "application/pdf", data: "pdfdata" },
45
48
  ]);
46
49
 
47
50
  expect(blocks).toHaveLength(1);
48
- expect(blocks[0].type).toBe('file');
49
- const block = blocks[0] as { type: 'file'; source: { filename: string; media_type: string; data: string } };
50
- expect(block.source.filename).toBe('doc.pdf');
51
- expect(block.source.media_type).toBe('application/pdf');
51
+ expect(blocks[0].type).toBe("file");
52
+ const block = blocks[0] as {
53
+ type: "file";
54
+ source: { filename: string; media_type: string; data: string };
55
+ };
56
+ expect(block.source.filename).toBe("doc.pdf");
57
+ expect(block.source.media_type).toBe("application/pdf");
52
58
  });
53
59
 
54
- test('handles multiple attachments including mixed types', () => {
60
+ test("handles multiple attachments including mixed types", () => {
55
61
  const blocks = attachmentsToContentBlocks([
56
- { filename: 'photo.jpg', mimeType: 'image/jpeg', data: 'imgdata' },
57
- { filename: 'notes.txt', mimeType: 'text/plain', data: 'txtdata' },
62
+ { filename: "photo.jpg", mimeType: "image/jpeg", data: "imgdata" },
63
+ { filename: "notes.txt", mimeType: "text/plain", data: "txtdata" },
58
64
  ]);
59
65
 
60
66
  expect(blocks).toHaveLength(2);
61
- expect(blocks[0].type).toBe('image');
62
- expect(blocks[1].type).toBe('file');
67
+ expect(blocks[0].type).toBe("image");
68
+ expect(blocks[1].type).toBe("file");
63
69
  });
64
70
 
65
- test('returns empty array for no attachments', () => {
71
+ test("returns empty array for no attachments", () => {
66
72
  const blocks = attachmentsToContentBlocks([]);
67
73
  expect(blocks).toHaveLength(0);
68
74
  });
@@ -72,64 +78,66 @@ describe('attachmentsToContentBlocks', () => {
72
78
  // createUserMessage with image attachments
73
79
  // ---------------------------------------------------------------------------
74
80
 
75
- describe('createUserMessage with image attachments', () => {
76
- test('includes both text and image blocks', () => {
77
- const msg = createUserMessage('what is this?', [
78
- { filename: 'photo.jpg', mimeType: 'image/jpeg', data: 'base64img' },
81
+ describe("createUserMessage with image attachments", () => {
82
+ test("includes both text and image blocks", () => {
83
+ const msg = createUserMessage("what is this?", [
84
+ { filename: "photo.jpg", mimeType: "image/jpeg", data: "base64img" },
79
85
  ]);
80
86
 
81
- expect(msg.role).toBe('user');
87
+ expect(msg.role).toBe("user");
82
88
  expect(msg.content).toHaveLength(2);
83
- expect(msg.content[0].type).toBe('text');
84
- expect((msg.content[0] as { type: 'text'; text: string }).text).toBe('what is this?');
85
- expect(msg.content[1].type).toBe('image');
89
+ expect(msg.content[0].type).toBe("text");
90
+ expect((msg.content[0] as { type: "text"; text: string }).text).toBe(
91
+ "what is this?",
92
+ );
93
+ expect(msg.content[1].type).toBe("image");
86
94
  });
87
95
 
88
- test('includes only image block when text is empty', () => {
89
- const msg = createUserMessage('', [
90
- { filename: 'photo.jpg', mimeType: 'image/jpeg', data: 'base64img' },
96
+ test("includes only image block when text is empty", () => {
97
+ const msg = createUserMessage("", [
98
+ { filename: "photo.jpg", mimeType: "image/jpeg", data: "base64img" },
91
99
  ]);
92
100
 
93
- expect(msg.role).toBe('user');
101
+ expect(msg.role).toBe("user");
94
102
  expect(msg.content).toHaveLength(1);
95
- expect(msg.content[0].type).toBe('image');
103
+ expect(msg.content[0].type).toBe("image");
96
104
  });
97
105
 
98
- test('includes only image block when text is whitespace', () => {
99
- const msg = createUserMessage(' ', [
100
- { filename: 'photo.jpg', mimeType: 'image/jpeg', data: 'base64img' },
106
+ test("includes only image block when text is whitespace", () => {
107
+ const msg = createUserMessage(" ", [
108
+ { filename: "photo.jpg", mimeType: "image/jpeg", data: "base64img" },
101
109
  ]);
102
110
 
103
- expect(msg.role).toBe('user');
111
+ expect(msg.role).toBe("user");
104
112
  expect(msg.content).toHaveLength(1);
105
- expect(msg.content[0].type).toBe('image');
113
+ expect(msg.content[0].type).toBe("image");
106
114
  });
107
115
 
108
- test('includes multiple image blocks', () => {
109
- const msg = createUserMessage('compare these', [
110
- { filename: 'a.jpg', mimeType: 'image/jpeg', data: 'img1' },
111
- { filename: 'b.png', mimeType: 'image/png', data: 'img2' },
116
+ test("includes multiple image blocks", () => {
117
+ const msg = createUserMessage("compare these", [
118
+ { filename: "a.jpg", mimeType: "image/jpeg", data: "img1" },
119
+ { filename: "b.png", mimeType: "image/png", data: "img2" },
112
120
  ]);
113
121
 
114
- expect(msg.role).toBe('user');
122
+ expect(msg.role).toBe("user");
115
123
  expect(msg.content).toHaveLength(3);
116
- expect(msg.content[0].type).toBe('text');
117
- expect(msg.content[1].type).toBe('image');
118
- expect(msg.content[2].type).toBe('image');
124
+ expect(msg.content[0].type).toBe("text");
125
+ expect(msg.content[1].type).toBe("image");
126
+ expect(msg.content[2].type).toBe("image");
119
127
  });
120
128
 
121
- test('preserves base64 data in image content block', () => {
122
- const base64 = 'dGVzdC1pbWFnZS1kYXRh';
123
- const msg = createUserMessage('test', [
124
- { filename: 'photo.jpg', mimeType: 'image/jpeg', data: base64 },
129
+ test("preserves base64 data in image content block", () => {
130
+ const base64 = "dGVzdC1pbWFnZS1kYXRh";
131
+ const msg = createUserMessage("test", [
132
+ { filename: "photo.jpg", mimeType: "image/jpeg", data: base64 },
125
133
  ]);
126
134
 
127
135
  const imageBlock = msg.content[1] as {
128
- type: 'image';
136
+ type: "image";
129
137
  source: { type: string; media_type: string; data: string };
130
138
  };
131
139
  expect(imageBlock.source.data).toBe(base64);
132
- expect(imageBlock.source.media_type).toBe('image/jpeg');
133
- expect(imageBlock.source.type).toBe('base64');
140
+ expect(imageBlock.source.media_type).toBe("image/jpeg");
141
+ expect(imageBlock.source.type).toBe("base64");
134
142
  });
135
143
  });
@@ -1,28 +1,31 @@
1
- import { randomBytes } from 'node:crypto';
2
- import { existsSync,mkdirSync } from 'node:fs';
3
- import { tmpdir } from 'node:os';
4
- import { join } from 'node:path';
5
-
6
- import { Database } from 'bun:sqlite';
7
- import { beforeAll, beforeEach, describe, expect, mock,test } from 'bun:test';
1
+ import { randomBytes } from "node:crypto";
2
+ import { existsSync, mkdirSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { Database } from "bun:sqlite";
6
+ import { beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
8
7
 
9
8
  // ---------------------------------------------------------------------------
10
9
  // Test setup — temp directory and mock modules
11
10
  // ---------------------------------------------------------------------------
12
11
 
13
- const TEST_DIR = join(tmpdir(), `vellum-rotation-test-${randomBytes(4).toString('hex')}`);
14
- const DB_PATH = join(TEST_DIR, 'assistant.db');
15
-
16
- mock.module('../util/logger.js', () => ({
17
- getLogger: () => new Proxy({} as Record<string, unknown>, {
18
- get: () => () => {},
19
- }),
12
+ const TEST_DIR = join(
13
+ tmpdir(),
14
+ `vellum-rotation-test-${randomBytes(4).toString("hex")}`,
15
+ );
16
+ const DB_PATH = join(TEST_DIR, "assistant.db");
17
+
18
+ mock.module("../util/logger.js", () => ({
19
+ getLogger: () =>
20
+ new Proxy({} as Record<string, unknown>, {
21
+ get: () => () => {},
22
+ }),
20
23
  }));
21
24
 
22
- mock.module('../util/platform.js', () => ({
25
+ mock.module("../util/platform.js", () => ({
23
26
  getDataDir: () => TEST_DIR,
24
27
  getDbPath: () => DB_PATH,
25
- getLogPath: () => join(TEST_DIR, 'logs', 'vellum.log'),
28
+ getLogPath: () => join(TEST_DIR, "logs", "vellum.log"),
26
29
  ensureDataDir: () => {
27
30
  if (!existsSync(TEST_DIR)) mkdirSync(TEST_DIR, { recursive: true });
28
31
  },
@@ -31,11 +34,11 @@ mock.module('../util/platform.js', () => ({
31
34
  isWindows: () => false,
32
35
  }));
33
36
 
34
- import { initializeDb, resetDb } from '../memory/db.js';
37
+ import { initializeDb, resetDb } from "../memory/db.js";
35
38
  import {
36
39
  getRecentInvocations,
37
40
  rotateToolInvocations,
38
- } from '../memory/tool-usage-store.js';
41
+ } from "../memory/tool-usage-store.js";
39
42
 
40
43
  // ---------------------------------------------------------------------------
41
44
  // Helpers
@@ -44,18 +47,28 @@ import {
44
47
  function addInvocation(ageMs: number): void {
45
48
  // Insert directly with a specific timestamp in the past
46
49
  const db = new Database(DB_PATH);
47
- const id = randomBytes(8).toString('hex');
50
+ const id = randomBytes(8).toString("hex");
48
51
  const createdAt = Date.now() - ageMs;
49
52
  db.prepare(
50
53
  `INSERT INTO tool_invocations (id, conversation_id, tool_name, input, result, decision, risk_level, duration_ms, created_at)
51
54
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
52
- ).run(id, 'conv-1', 'bash', '{"command":"echo hi"}', 'hi', 'allow', 'Low', 100, createdAt);
55
+ ).run(
56
+ id,
57
+ "conv-1",
58
+ "bash",
59
+ '{"command":"echo hi"}',
60
+ "hi",
61
+ "allow",
62
+ "Low",
63
+ 100,
64
+ createdAt,
65
+ );
53
66
  db.close();
54
67
  }
55
68
 
56
69
  function clearTable(): void {
57
70
  const db = new Database(DB_PATH);
58
- db.run('DELETE FROM tool_invocations');
71
+ db.run("DELETE FROM tool_invocations");
59
72
  db.close();
60
73
  }
61
74
 
@@ -65,14 +78,16 @@ const ONE_DAY_MS = 24 * 60 * 60 * 1000;
65
78
  // Tests
66
79
  // ---------------------------------------------------------------------------
67
80
 
68
- describe('audit log rotation', () => {
81
+ describe("audit log rotation", () => {
69
82
  beforeAll(() => {
70
- mkdirSync(join(TEST_DIR, 'logs'), { recursive: true });
83
+ mkdirSync(join(TEST_DIR, "logs"), { recursive: true });
71
84
  resetDb();
72
85
  initializeDb();
73
86
  // Insert a conversations row so FK-enforced ORM inserts succeed
74
87
  const db = new Database(DB_PATH);
75
- db.run(`INSERT INTO conversations (id, title, created_at, updated_at) VALUES ('conv-1', 'test', ${Date.now()}, ${Date.now()})`);
88
+ db.run(
89
+ `INSERT INTO conversations (id, title, created_at, updated_at) VALUES ('conv-1', 'test', ${Date.now()}, ${Date.now()})`,
90
+ );
76
91
  db.close();
77
92
  });
78
93
 
@@ -84,31 +99,31 @@ describe('audit log rotation', () => {
84
99
  // Deleting it here would trigger ENOENT in other test files because
85
100
  // the platform.js mock leaks getDataDir() → TEST_DIR globally.
86
101
 
87
- test('returns 0 when retentionDays is 0 (retain forever)', () => {
102
+ test("returns 0 when retentionDays is 0 (retain forever)", () => {
88
103
  addInvocation(100 * ONE_DAY_MS); // 100 days old
89
104
  const deleted = rotateToolInvocations(0);
90
105
  expect(deleted).toBe(0);
91
106
  expect(getRecentInvocations(100).length).toBe(1);
92
107
  });
93
108
 
94
- test('returns 0 when retentionDays is negative', () => {
109
+ test("returns 0 when retentionDays is negative", () => {
95
110
  addInvocation(100 * ONE_DAY_MS);
96
111
  const deleted = rotateToolInvocations(-5);
97
112
  expect(deleted).toBe(0);
98
113
  expect(getRecentInvocations(100).length).toBe(1);
99
114
  });
100
115
 
101
- test('deletes records older than retentionDays', () => {
116
+ test("deletes records older than retentionDays", () => {
102
117
  addInvocation(10 * ONE_DAY_MS); // 10 days old — should be deleted with 7-day retention
103
- addInvocation(3 * ONE_DAY_MS); // 3 days old — should be kept
104
- addInvocation(1 * ONE_DAY_MS); // 1 day old — should be kept
118
+ addInvocation(3 * ONE_DAY_MS); // 3 days old — should be kept
119
+ addInvocation(1 * ONE_DAY_MS); // 1 day old — should be kept
105
120
 
106
121
  const deleted = rotateToolInvocations(7);
107
122
  expect(deleted).toBe(1);
108
123
  expect(getRecentInvocations(100).length).toBe(2);
109
124
  });
110
125
 
111
- test('keeps all records when none exceed retention', () => {
126
+ test("keeps all records when none exceed retention", () => {
112
127
  addInvocation(1 * ONE_DAY_MS);
113
128
  addInvocation(2 * ONE_DAY_MS);
114
129
  addInvocation(3 * ONE_DAY_MS);
@@ -118,7 +133,7 @@ describe('audit log rotation', () => {
118
133
  expect(getRecentInvocations(100).length).toBe(3);
119
134
  });
120
135
 
121
- test('deletes all records when all exceed retention', () => {
136
+ test("deletes all records when all exceed retention", () => {
122
137
  addInvocation(60 * ONE_DAY_MS);
123
138
  addInvocation(90 * ONE_DAY_MS);
124
139
  addInvocation(120 * ONE_DAY_MS);
@@ -128,13 +143,13 @@ describe('audit log rotation', () => {
128
143
  expect(getRecentInvocations(100).length).toBe(0);
129
144
  });
130
145
 
131
- test('returns 0 when table is empty', () => {
146
+ test("returns 0 when table is empty", () => {
132
147
  const deleted = rotateToolInvocations(7);
133
148
  expect(deleted).toBe(0);
134
149
  });
135
150
 
136
- test('handles 1-day retention (deletes everything older than 24h)', () => {
137
- addInvocation(2 * ONE_DAY_MS); // 2 days old — delete
151
+ test("handles 1-day retention (deletes everything older than 24h)", () => {
152
+ addInvocation(2 * ONE_DAY_MS); // 2 days old — delete
138
153
  addInvocation(12 * 60 * 60 * 1000); // 12 hours old — keep
139
154
 
140
155
  const deleted = rotateToolInvocations(1);
@@ -142,7 +157,7 @@ describe('audit log rotation', () => {
142
157
  expect(getRecentInvocations(100).length).toBe(1);
143
158
  });
144
159
 
145
- test('works with recordToolInvocation (via ORM)', () => {
160
+ test("works with recordToolInvocation (via ORM)", () => {
146
161
  // Use raw SQL to insert (avoids db singleton issues in parallel test runs)
147
162
  // and verify the rotation/query functions work correctly with it
148
163
  addInvocation(0); // just-created record