@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
@@ -8,7 +8,6 @@
8
8
  import { mkdtempSync, realpathSync, rmSync } from "node:fs";
9
9
  import { tmpdir } from "node:os";
10
10
  import { join } from "node:path";
11
-
12
11
  import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
13
12
 
14
13
  mock.module("../config/env.js", () => ({ isHttpAuthDisabled: () => true }));
@@ -1,6 +1,6 @@
1
- import { beforeEach, describe, expect, mock, test } from 'bun:test';
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
- import type { ToolContext } from '../tools/types.js';
3
+ import type { ToolContext } from "../tools/types.js";
4
4
 
5
5
  let callsEnabled = true;
6
6
  const startCallInputs: Array<Record<string, unknown>> = [];
@@ -9,88 +9,90 @@ let activeVoiceSession: {
9
9
  expectedPhoneE164: string | null;
10
10
  } | null = null;
11
11
 
12
- mock.module('../config/loader.js', () => ({
12
+ mock.module("../config/loader.js", () => ({
13
13
  getConfig: () => ({
14
14
  ui: {},
15
-
15
+
16
16
  calls: { enabled: callsEnabled },
17
17
  }),
18
18
  }));
19
19
 
20
- mock.module('../calls/call-domain.js', () => ({
20
+ mock.module("../calls/call-domain.js", () => ({
21
21
  startCall: async (input: Record<string, unknown>) => {
22
22
  startCallInputs.push(input);
23
23
  return {
24
24
  ok: true,
25
25
  session: {
26
- id: 'call-session-1',
27
- toNumber: String(input.phoneNumber ?? ''),
28
- fromNumber: '+14155550000',
26
+ id: "call-session-1",
27
+ toNumber: String(input.phoneNumber ?? ""),
28
+ fromNumber: "+14155550000",
29
29
  },
30
- callSid: 'CA-mock',
31
- callerIdentityMode: 'assistant_number',
30
+ callSid: "CA-mock",
31
+ callerIdentityMode: "assistant_number",
32
32
  };
33
33
  },
34
34
  }));
35
35
 
36
- mock.module('../runtime/channel-guardian-service.js', () => ({
36
+ mock.module("../runtime/channel-guardian-service.js", () => ({
37
37
  findActiveSession: () => activeVoiceSession,
38
38
  }));
39
39
 
40
- const { executeCallStart } = await import('../tools/calls/call-start.js');
40
+ const { executeCallStart } = await import("../tools/calls/call-start.js");
41
41
 
42
42
  function makeContext(): ToolContext {
43
43
  return {
44
- workingDir: '/tmp',
45
- sessionId: 'session-1',
46
- conversationId: 'conversation-1',
47
- assistantId: 'self',
48
- guardianTrustClass: 'guardian',
44
+ workingDir: "/tmp",
45
+ sessionId: "session-1",
46
+ conversationId: "conversation-1",
47
+ assistantId: "self",
48
+ guardianTrustClass: "guardian",
49
49
  };
50
50
  }
51
51
 
52
- describe('call_start guardian verification guard', () => {
52
+ describe("call_start guardian verification guard", () => {
53
53
  beforeEach(() => {
54
54
  callsEnabled = true;
55
55
  startCallInputs.length = 0;
56
56
  activeVoiceSession = null;
57
57
  });
58
58
 
59
- test('blocks call_start when voice guardian verification is active for the same number', async () => {
59
+ test("blocks call_start when voice guardian verification is active for the same number", async () => {
60
60
  activeVoiceSession = {
61
- destinationAddress: '+14155551234',
62
- expectedPhoneE164: '+14155551234',
61
+ destinationAddress: "+14155551234",
62
+ expectedPhoneE164: "+14155551234",
63
63
  };
64
64
 
65
65
  const result = await executeCallStart(
66
66
  {
67
- phone_number: '(415) 555-1234',
68
- task: 'Test call while verification is active',
67
+ phone_number: "(415) 555-1234",
68
+ task: "Test call while verification is active",
69
69
  },
70
70
  makeContext(),
71
71
  );
72
72
 
73
73
  expect(result.isError).toBe(true);
74
- expect(result.content).toContain('guardian voice verification call is already active');
74
+ expect(result.content).toContain(
75
+ "guardian voice verification call is already active",
76
+ );
75
77
  expect(startCallInputs.length).toBe(0);
76
78
  });
77
79
 
78
- test('allows call_start when active guardian verification targets a different number', async () => {
80
+ test("allows call_start when active guardian verification targets a different number", async () => {
79
81
  activeVoiceSession = {
80
- destinationAddress: '+14155550001',
81
- expectedPhoneE164: '+14155550001',
82
+ destinationAddress: "+14155550001",
83
+ expectedPhoneE164: "+14155550001",
82
84
  };
83
85
 
84
86
  const result = await executeCallStart(
85
87
  {
86
- phone_number: '+14155551234',
87
- task: 'Normal outbound call',
88
+ phone_number: "+14155551234",
89
+ task: "Normal outbound call",
88
90
  },
89
91
  makeContext(),
90
92
  );
91
93
 
92
94
  expect(result.isError).toBe(false);
93
- expect(result.content).toContain('Call initiated successfully.');
95
+ expect(result.content).toContain("Call initiated successfully.");
94
96
  expect(startCallInputs.length).toBe(1);
95
97
  });
96
98
  });
@@ -1,37 +1,40 @@
1
- import { describe, expect,test } from 'bun:test';
1
+ import { describe, expect, test } from "bun:test";
2
2
 
3
- import { isTerminalState,validateTransition } from '../calls/call-state-machine.js';
4
- import type { CallStatus } from '../calls/types.js';
3
+ import {
4
+ isTerminalState,
5
+ validateTransition,
6
+ } from "../calls/call-state-machine.js";
7
+ import type { CallStatus } from "../calls/types.js";
5
8
 
6
- describe('call-state-machine', () => {
9
+ describe("call-state-machine", () => {
7
10
  // ── Valid transitions ───────────────────────────────────────────────
8
11
 
9
- describe('valid transitions', () => {
12
+ describe("valid transitions", () => {
10
13
  const validCases: Array<[CallStatus, CallStatus]> = [
11
14
  // From initiated
12
- ['initiated', 'ringing'],
13
- ['initiated', 'in_progress'],
14
- ['initiated', 'completed'],
15
- ['initiated', 'failed'],
16
- ['initiated', 'cancelled'],
15
+ ["initiated", "ringing"],
16
+ ["initiated", "in_progress"],
17
+ ["initiated", "completed"],
18
+ ["initiated", "failed"],
19
+ ["initiated", "cancelled"],
17
20
 
18
21
  // From ringing
19
- ['ringing', 'in_progress'],
20
- ['ringing', 'completed'],
21
- ['ringing', 'failed'],
22
- ['ringing', 'cancelled'],
22
+ ["ringing", "in_progress"],
23
+ ["ringing", "completed"],
24
+ ["ringing", "failed"],
25
+ ["ringing", "cancelled"],
23
26
 
24
27
  // From in_progress
25
- ['in_progress', 'waiting_on_user'],
26
- ['in_progress', 'completed'],
27
- ['in_progress', 'failed'],
28
- ['in_progress', 'cancelled'],
28
+ ["in_progress", "waiting_on_user"],
29
+ ["in_progress", "completed"],
30
+ ["in_progress", "failed"],
31
+ ["in_progress", "cancelled"],
29
32
 
30
33
  // From waiting_on_user
31
- ['waiting_on_user', 'in_progress'],
32
- ['waiting_on_user', 'completed'],
33
- ['waiting_on_user', 'failed'],
34
- ['waiting_on_user', 'cancelled'],
34
+ ["waiting_on_user", "in_progress"],
35
+ ["waiting_on_user", "completed"],
36
+ ["waiting_on_user", "failed"],
37
+ ["waiting_on_user", "cancelled"],
35
38
  ];
36
39
 
37
40
  for (const [from, to] of validCases) {
@@ -45,10 +48,15 @@ describe('call-state-machine', () => {
45
48
 
46
49
  // ── Same-state transitions (no-op, valid) ──────────────────────────
47
50
 
48
- describe('same-state transitions', () => {
51
+ describe("same-state transitions", () => {
49
52
  const allStatuses: CallStatus[] = [
50
- 'initiated', 'ringing', 'in_progress', 'waiting_on_user',
51
- 'completed', 'failed', 'cancelled',
53
+ "initiated",
54
+ "ringing",
55
+ "in_progress",
56
+ "waiting_on_user",
57
+ "completed",
58
+ "failed",
59
+ "cancelled",
52
60
  ];
53
61
 
54
62
  for (const status of allStatuses) {
@@ -61,14 +69,14 @@ describe('call-state-machine', () => {
61
69
 
62
70
  // ── Invalid transitions ─────────────────────────────────────────────
63
71
 
64
- describe('invalid transitions', () => {
72
+ describe("invalid transitions", () => {
65
73
  const invalidCases: Array<[CallStatus, CallStatus]> = [
66
74
  // Cannot skip backwards
67
- ['ringing', 'initiated'],
68
- ['in_progress', 'initiated'],
69
- ['in_progress', 'ringing'],
70
- ['waiting_on_user', 'initiated'],
71
- ['waiting_on_user', 'ringing'],
75
+ ["ringing", "initiated"],
76
+ ["in_progress", "initiated"],
77
+ ["in_progress", "ringing"],
78
+ ["waiting_on_user", "initiated"],
79
+ ["waiting_on_user", "ringing"],
72
80
  ];
73
81
 
74
82
  for (const [from, to] of invalidCases) {
@@ -83,10 +91,13 @@ describe('call-state-machine', () => {
83
91
 
84
92
  // ── Terminal state immutability ─────────────────────────────────────
85
93
 
86
- describe('terminal state immutability', () => {
87
- const terminalStates: CallStatus[] = ['completed', 'failed', 'cancelled'];
94
+ describe("terminal state immutability", () => {
95
+ const terminalStates: CallStatus[] = ["completed", "failed", "cancelled"];
88
96
  const nonTerminalTargets: CallStatus[] = [
89
- 'initiated', 'ringing', 'in_progress', 'waiting_on_user',
97
+ "initiated",
98
+ "ringing",
99
+ "in_progress",
100
+ "waiting_on_user",
90
101
  ];
91
102
 
92
103
  for (const terminal of terminalStates) {
@@ -94,7 +105,7 @@ describe('call-state-machine', () => {
94
105
  test(`${terminal} -> ${target} is rejected (terminal state)`, () => {
95
106
  const result = validateTransition(terminal, target);
96
107
  expect(result.valid).toBe(false);
97
- expect(result.reason).toContain('terminal');
108
+ expect(result.reason).toContain("terminal");
98
109
  });
99
110
  }
100
111
 
@@ -104,7 +115,7 @@ describe('call-state-machine', () => {
104
115
  test(`${terminal} -> ${otherTerminal} is rejected (terminal to terminal)`, () => {
105
116
  const result = validateTransition(terminal, otherTerminal);
106
117
  expect(result.valid).toBe(false);
107
- expect(result.reason).toContain('terminal');
118
+ expect(result.reason).toContain("terminal");
108
119
  });
109
120
  }
110
121
  }
@@ -112,33 +123,33 @@ describe('call-state-machine', () => {
112
123
 
113
124
  // ── isTerminalState ─────────────────────────────────────────────────
114
125
 
115
- describe('isTerminalState', () => {
116
- test('completed is terminal', () => {
117
- expect(isTerminalState('completed')).toBe(true);
126
+ describe("isTerminalState", () => {
127
+ test("completed is terminal", () => {
128
+ expect(isTerminalState("completed")).toBe(true);
118
129
  });
119
130
 
120
- test('failed is terminal', () => {
121
- expect(isTerminalState('failed')).toBe(true);
131
+ test("failed is terminal", () => {
132
+ expect(isTerminalState("failed")).toBe(true);
122
133
  });
123
134
 
124
- test('cancelled is terminal', () => {
125
- expect(isTerminalState('cancelled')).toBe(true);
135
+ test("cancelled is terminal", () => {
136
+ expect(isTerminalState("cancelled")).toBe(true);
126
137
  });
127
138
 
128
- test('initiated is not terminal', () => {
129
- expect(isTerminalState('initiated')).toBe(false);
139
+ test("initiated is not terminal", () => {
140
+ expect(isTerminalState("initiated")).toBe(false);
130
141
  });
131
142
 
132
- test('ringing is not terminal', () => {
133
- expect(isTerminalState('ringing')).toBe(false);
143
+ test("ringing is not terminal", () => {
144
+ expect(isTerminalState("ringing")).toBe(false);
134
145
  });
135
146
 
136
- test('in_progress is not terminal', () => {
137
- expect(isTerminalState('in_progress')).toBe(false);
147
+ test("in_progress is not terminal", () => {
148
+ expect(isTerminalState("in_progress")).toBe(false);
138
149
  });
139
150
 
140
- test('waiting_on_user is not terminal', () => {
141
- expect(isTerminalState('waiting_on_user')).toBe(false);
151
+ test("waiting_on_user is not terminal", () => {
152
+ expect(isTerminalState("waiting_on_user")).toBe(false);
142
153
  });
143
154
  });
144
155
  });
@@ -1,12 +1,13 @@
1
- import { beforeEach, describe, expect, mock,test } from 'bun:test';
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
- mock.module('../util/logger.js', () => ({
4
- getLogger: () => new Proxy({} as Record<string, unknown>, {
5
- get: () => () => {},
6
- }),
3
+ mock.module("../util/logger.js", () => ({
4
+ getLogger: () =>
5
+ new Proxy({} as Record<string, unknown>, {
6
+ get: () => () => {},
7
+ }),
7
8
  }));
8
9
 
9
- import type { CallController } from '../calls/call-controller.js';
10
+ import type { CallController } from "../calls/call-controller.js";
10
11
  import {
11
12
  fireCallCompletionNotifier,
12
13
  fireCallQuestionNotifier,
@@ -20,155 +21,168 @@ import {
20
21
  unregisterCallController,
21
22
  unregisterCallQuestionNotifier,
22
23
  unregisterCallTranscriptNotifier,
23
- } from '../calls/call-state.js';
24
+ } from "../calls/call-state.js";
24
25
 
25
- describe('call-state', () => {
26
+ describe("call-state", () => {
26
27
  // Clean up notifiers between tests
27
28
  beforeEach(() => {
28
- unregisterCallQuestionNotifier('test-conv');
29
- unregisterCallTranscriptNotifier('test-conv');
30
- unregisterCallCompletionNotifier('test-conv');
31
- unregisterCallController('test-session');
29
+ unregisterCallQuestionNotifier("test-conv");
30
+ unregisterCallTranscriptNotifier("test-conv");
31
+ unregisterCallCompletionNotifier("test-conv");
32
+ unregisterCallController("test-session");
32
33
  });
33
34
 
34
35
  // ── Question notifiers ────────────────────────────────────────────
35
36
 
36
- test('registerCallQuestionNotifier + fireCallQuestionNotifier: callback receives args', () => {
37
- let receivedSessionId = '';
38
- let receivedQuestion = '';
37
+ test("registerCallQuestionNotifier + fireCallQuestionNotifier: callback receives args", () => {
38
+ let receivedSessionId = "";
39
+ let receivedQuestion = "";
39
40
 
40
- registerCallQuestionNotifier('test-conv', (callSessionId, question) => {
41
+ registerCallQuestionNotifier("test-conv", (callSessionId, question) => {
41
42
  receivedSessionId = callSessionId;
42
43
  receivedQuestion = question;
43
44
  });
44
45
 
45
- fireCallQuestionNotifier('test-conv', 'session-123', 'What is the date?');
46
+ fireCallQuestionNotifier("test-conv", "session-123", "What is the date?");
46
47
 
47
- expect(receivedSessionId).toBe('session-123');
48
- expect(receivedQuestion).toBe('What is the date?');
48
+ expect(receivedSessionId).toBe("session-123");
49
+ expect(receivedQuestion).toBe("What is the date?");
49
50
  });
50
51
 
51
- test('unregisterCallQuestionNotifier: fire after unregister does nothing', () => {
52
+ test("unregisterCallQuestionNotifier: fire after unregister does nothing", () => {
52
53
  let called = false;
53
54
 
54
- registerCallQuestionNotifier('test-conv', () => {
55
+ registerCallQuestionNotifier("test-conv", () => {
55
56
  called = true;
56
57
  });
57
58
 
58
- unregisterCallQuestionNotifier('test-conv');
59
- fireCallQuestionNotifier('test-conv', 'session-123', 'Some question');
59
+ unregisterCallQuestionNotifier("test-conv");
60
+ fireCallQuestionNotifier("test-conv", "session-123", "Some question");
60
61
 
61
62
  expect(called).toBe(false);
62
63
  });
63
64
 
64
- test('fireCallQuestionNotifier does nothing when no notifier is registered', () => {
65
+ test("fireCallQuestionNotifier does nothing when no notifier is registered", () => {
65
66
  // Should not throw
66
- fireCallQuestionNotifier('unregistered-conv', 'session-1', 'question');
67
+ fireCallQuestionNotifier("unregistered-conv", "session-1", "question");
67
68
  });
68
69
 
69
70
  // ── Transcript notifiers ──────────────────────────────────────────
70
71
 
71
- test('registerCallTranscriptNotifier + fireCallTranscriptNotifier: callback receives args', () => {
72
- let receivedSessionId = '';
73
- let receivedSpeaker = '';
74
- let receivedText = '';
75
-
76
- registerCallTranscriptNotifier('test-conv', (callSessionId, speaker, text) => {
77
- receivedSessionId = callSessionId;
78
- receivedSpeaker = speaker;
79
- receivedText = text;
80
- });
81
-
82
- fireCallTranscriptNotifier('test-conv', 'session-321', 'caller', 'Hello from caller');
83
-
84
- expect(receivedSessionId).toBe('session-321');
85
- expect(receivedSpeaker).toBe('caller');
86
- expect(receivedText).toBe('Hello from caller');
72
+ test("registerCallTranscriptNotifier + fireCallTranscriptNotifier: callback receives args", () => {
73
+ let receivedSessionId = "";
74
+ let receivedSpeaker = "";
75
+ let receivedText = "";
76
+
77
+ registerCallTranscriptNotifier(
78
+ "test-conv",
79
+ (callSessionId, speaker, text) => {
80
+ receivedSessionId = callSessionId;
81
+ receivedSpeaker = speaker;
82
+ receivedText = text;
83
+ },
84
+ );
85
+
86
+ fireCallTranscriptNotifier(
87
+ "test-conv",
88
+ "session-321",
89
+ "caller",
90
+ "Hello from caller",
91
+ );
92
+
93
+ expect(receivedSessionId).toBe("session-321");
94
+ expect(receivedSpeaker).toBe("caller");
95
+ expect(receivedText).toBe("Hello from caller");
87
96
  });
88
97
 
89
- test('unregisterCallTranscriptNotifier: fire after unregister does nothing', () => {
98
+ test("unregisterCallTranscriptNotifier: fire after unregister does nothing", () => {
90
99
  let called = false;
91
100
 
92
- registerCallTranscriptNotifier('test-conv', () => {
101
+ registerCallTranscriptNotifier("test-conv", () => {
93
102
  called = true;
94
103
  });
95
104
 
96
- unregisterCallTranscriptNotifier('test-conv');
97
- fireCallTranscriptNotifier('test-conv', 'session-321', 'assistant', 'Test');
105
+ unregisterCallTranscriptNotifier("test-conv");
106
+ fireCallTranscriptNotifier("test-conv", "session-321", "assistant", "Test");
98
107
 
99
108
  expect(called).toBe(false);
100
109
  });
101
110
 
102
- test('fireCallTranscriptNotifier does nothing when no notifier is registered', () => {
103
- fireCallTranscriptNotifier('unregistered-conv', 'session-1', 'caller', 'text');
111
+ test("fireCallTranscriptNotifier does nothing when no notifier is registered", () => {
112
+ fireCallTranscriptNotifier(
113
+ "unregistered-conv",
114
+ "session-1",
115
+ "caller",
116
+ "text",
117
+ );
104
118
  });
105
119
 
106
120
  // ── Completion notifiers ──────────────────────────────────────────
107
121
 
108
- test('registerCallCompletionNotifier + fireCallCompletionNotifier: callback receives callSessionId', () => {
109
- let receivedSessionId = '';
122
+ test("registerCallCompletionNotifier + fireCallCompletionNotifier: callback receives callSessionId", () => {
123
+ let receivedSessionId = "";
110
124
 
111
- registerCallCompletionNotifier('test-conv', (callSessionId) => {
125
+ registerCallCompletionNotifier("test-conv", (callSessionId) => {
112
126
  receivedSessionId = callSessionId;
113
127
  });
114
128
 
115
- fireCallCompletionNotifier('test-conv', 'session-456');
129
+ fireCallCompletionNotifier("test-conv", "session-456");
116
130
 
117
- expect(receivedSessionId).toBe('session-456');
131
+ expect(receivedSessionId).toBe("session-456");
118
132
  });
119
133
 
120
- test('unregisterCallCompletionNotifier: fire after unregister does nothing', () => {
134
+ test("unregisterCallCompletionNotifier: fire after unregister does nothing", () => {
121
135
  let called = false;
122
136
 
123
- registerCallCompletionNotifier('test-conv', () => {
137
+ registerCallCompletionNotifier("test-conv", () => {
124
138
  called = true;
125
139
  });
126
140
 
127
- unregisterCallCompletionNotifier('test-conv');
128
- fireCallCompletionNotifier('test-conv', 'session-456');
141
+ unregisterCallCompletionNotifier("test-conv");
142
+ fireCallCompletionNotifier("test-conv", "session-456");
129
143
 
130
144
  expect(called).toBe(false);
131
145
  });
132
146
 
133
- test('fireCallCompletionNotifier does nothing when no notifier is registered', () => {
147
+ test("fireCallCompletionNotifier does nothing when no notifier is registered", () => {
134
148
  // Should not throw
135
- fireCallCompletionNotifier('unregistered-conv', 'session-1');
149
+ fireCallCompletionNotifier("unregistered-conv", "session-1");
136
150
  });
137
151
 
138
152
  // ── Controller registry ─────────────────────────────────────────
139
153
 
140
- test('registerCallController + getCallController: retrieves controller', () => {
141
- const fakeController = { id: 'fake-ctrl' } as unknown as CallController;
154
+ test("registerCallController + getCallController: retrieves controller", () => {
155
+ const fakeController = { id: "fake-ctrl" } as unknown as CallController;
142
156
 
143
- registerCallController('test-session', fakeController);
157
+ registerCallController("test-session", fakeController);
144
158
 
145
- const retrieved = getCallController('test-session');
159
+ const retrieved = getCallController("test-session");
146
160
  expect(retrieved).toBe(fakeController);
147
161
  });
148
162
 
149
- test('unregisterCallController: getCallController returns undefined after unregister', () => {
150
- const fakeController = { id: 'fake-ctrl-2' } as unknown as CallController;
163
+ test("unregisterCallController: getCallController returns undefined after unregister", () => {
164
+ const fakeController = { id: "fake-ctrl-2" } as unknown as CallController;
151
165
 
152
- registerCallController('test-session', fakeController);
153
- unregisterCallController('test-session');
166
+ registerCallController("test-session", fakeController);
167
+ unregisterCallController("test-session");
154
168
 
155
- const retrieved = getCallController('test-session');
169
+ const retrieved = getCallController("test-session");
156
170
  expect(retrieved).toBeUndefined();
157
171
  });
158
172
 
159
- test('getCallController returns undefined for unregistered session', () => {
160
- const retrieved = getCallController('nonexistent-session');
173
+ test("getCallController returns undefined for unregistered session", () => {
174
+ const retrieved = getCallController("nonexistent-session");
161
175
  expect(retrieved).toBeUndefined();
162
176
  });
163
177
 
164
- test('registering a new controller for same session overwrites the previous one', () => {
165
- const first = { id: 'first' } as unknown as CallController;
166
- const second = { id: 'second' } as unknown as CallController;
178
+ test("registering a new controller for same session overwrites the previous one", () => {
179
+ const first = { id: "first" } as unknown as CallController;
180
+ const second = { id: "second" } as unknown as CallController;
167
181
 
168
- registerCallController('test-session', first);
169
- registerCallController('test-session', second);
182
+ registerCallController("test-session", first);
183
+ registerCallController("test-session", second);
170
184
 
171
- const retrieved = getCallController('test-session');
185
+ const retrieved = getCallController("test-session");
172
186
  expect(retrieved).toBe(second);
173
187
  });
174
188
  });