@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
@@ -6,68 +6,72 @@
6
6
  * - Strict implicit-default policy for caller identity.
7
7
  * - Pointer messages are written on successful call start and on failure.
8
8
  */
9
- import { mkdtempSync, realpathSync, rmSync } from 'node:fs';
10
- import { tmpdir } from 'node:os';
11
- import { join } from 'node:path';
9
+ import { mkdtempSync, realpathSync, rmSync } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
12
13
 
13
- import { afterAll, beforeEach, describe, expect, mock,test } from 'bun:test';
14
+ const testDir = realpathSync(mkdtempSync(join(tmpdir(), "call-domain-test-")));
14
15
 
15
- const testDir = realpathSync(mkdtempSync(join(tmpdir(), 'call-domain-test-')));
16
-
17
- mock.module('../util/platform.js', () => ({
16
+ mock.module("../util/platform.js", () => ({
18
17
  getRootDir: () => testDir,
19
18
  getDataDir: () => testDir,
20
- isMacOS: () => process.platform === 'darwin',
21
- isLinux: () => process.platform === 'linux',
22
- isWindows: () => process.platform === 'win32',
23
- getSocketPath: () => join(testDir, 'test.sock'),
24
- getPidPath: () => join(testDir, 'test.pid'),
25
- getDbPath: () => join(testDir, 'test.db'),
26
- getLogPath: () => join(testDir, 'test.log'),
19
+ isMacOS: () => process.platform === "darwin",
20
+ isLinux: () => process.platform === "linux",
21
+ isWindows: () => process.platform === "win32",
22
+ getSocketPath: () => join(testDir, "test.sock"),
23
+ getPidPath: () => join(testDir, "test.pid"),
24
+ getDbPath: () => join(testDir, "test.db"),
25
+ getLogPath: () => join(testDir, "test.log"),
27
26
  ensureDataDir: () => {},
28
27
  }));
29
28
 
30
- mock.module('../util/logger.js', () => ({
31
- getLogger: () => new Proxy({} as Record<string, unknown>, {
32
- get: () => () => {},
33
- }),
29
+ mock.module("../util/logger.js", () => ({
30
+ getLogger: () =>
31
+ new Proxy({} as Record<string, unknown>, {
32
+ get: () => () => {},
33
+ }),
34
34
  }));
35
35
 
36
36
  // Track whether the Twilio provider's initiateCall should succeed or throw
37
- let twilioInitiateCallBehavior: 'success' | 'error' = 'success';
37
+ let twilioInitiateCallBehavior: "success" | "error" = "success";
38
38
 
39
- mock.module('../calls/twilio-config.js', () => ({
39
+ mock.module("../calls/twilio-config.js", () => ({
40
40
  getTwilioConfig: (assistantId?: string) => ({
41
- accountSid: 'AC_test',
42
- authToken: 'test_token',
43
- phoneNumber: assistantId === 'ast-alpha' ? '+15550003333' : '+15550001111',
44
- webhookBaseUrl: 'https://test.example.com',
45
- wssBaseUrl: 'wss://test.example.com',
41
+ accountSid: "AC_test",
42
+ authToken: "test_token",
43
+ phoneNumber: assistantId === "ast-alpha" ? "+15550003333" : "+15550001111",
44
+ webhookBaseUrl: "https://test.example.com",
45
+ wssBaseUrl: "wss://test.example.com",
46
46
  }),
47
47
  }));
48
48
 
49
- mock.module('../calls/twilio-provider.js', () => ({
49
+ mock.module("../calls/twilio-provider.js", () => ({
50
50
  TwilioConversationRelayProvider: class {
51
51
  async checkCallerIdEligibility(number: string) {
52
- if (number === '+15550002222') return { eligible: true };
53
- return { eligible: false, reason: `${number} is not eligible as a caller ID` };
52
+ if (number === "+15550002222") return { eligible: true };
53
+ return {
54
+ eligible: false,
55
+ reason: `${number} is not eligible as a caller ID`,
56
+ };
54
57
  }
55
58
  async initiateCall() {
56
- if (twilioInitiateCallBehavior === 'error') throw new Error('Twilio unavailable');
57
- return { callSid: 'CA_test_123' };
59
+ if (twilioInitiateCallBehavior === "error")
60
+ throw new Error("Twilio unavailable");
61
+ return { callSid: "CA_test_123" };
58
62
  }
59
63
  },
60
64
  }));
61
65
 
62
- mock.module('../security/secure-keys.js', () => ({
66
+ mock.module("../security/secure-keys.js", () => ({
63
67
  getSecureKey: () => null,
64
68
  }));
65
69
 
66
- mock.module('../config/loader.js', () => ({
70
+ mock.module("../config/loader.js", () => ({
67
71
  loadConfig: () => ({
68
72
  calls: {
69
73
  enabled: true,
70
- provider: 'twilio',
74
+ provider: "twilio",
71
75
  callerIdentity: { allowPerCallOverride: true },
72
76
  },
73
77
  memory: { enabled: false },
@@ -75,31 +79,33 @@ mock.module('../config/loader.js', () => ({
75
79
  getConfig: () => ({
76
80
  calls: {
77
81
  enabled: true,
78
- provider: 'twilio',
82
+ provider: "twilio",
79
83
  callerIdentity: { allowPerCallOverride: true },
80
84
  },
81
85
  memory: { enabled: false },
82
86
  }),
83
87
  }));
84
88
 
85
- mock.module('../inbound/platform-callback-registration.js', () => ({
89
+ mock.module("../inbound/platform-callback-registration.js", () => ({
86
90
  resolveCallbackUrl: async (fn: () => string) => fn(),
87
91
  }));
88
92
 
89
- mock.module('../inbound/public-ingress-urls.js', () => ({
90
- getTwilioVoiceWebhookUrl: () => 'https://test.example.com/webhooks/twilio/voice/test',
91
- getTwilioStatusCallbackUrl: () => 'https://test.example.com/webhooks/twilio/status',
93
+ mock.module("../inbound/public-ingress-urls.js", () => ({
94
+ getTwilioVoiceWebhookUrl: () =>
95
+ "https://test.example.com/webhooks/twilio/voice/test",
96
+ getTwilioStatusCallbackUrl: () =>
97
+ "https://test.example.com/webhooks/twilio/status",
92
98
  }));
93
99
 
94
- mock.module('../memory/conversation-title-service.js', () => ({
100
+ mock.module("../memory/conversation-title-service.js", () => ({
95
101
  queueGenerateConversationTitle: () => {},
96
102
  }));
97
103
 
98
- import { resolveCallerIdentity, startCall } from '../calls/call-domain.js';
99
- import type { AssistantConfig } from '../config/types.js';
100
- import { getMessages } from '../memory/conversation-store.js';
101
- import { getDb, initializeDb, resetDb } from '../memory/db.js';
102
- import { conversations } from '../memory/schema.js';
104
+ import { resolveCallerIdentity, startCall } from "../calls/call-domain.js";
105
+ import type { AssistantConfig } from "../config/types.js";
106
+ import { getMessages } from "../memory/conversation-store.js";
107
+ import { getDb, initializeDb, resetDb } from "../memory/db.js";
108
+ import { conversations } from "../memory/schema.js";
103
109
 
104
110
  initializeDb();
105
111
 
@@ -108,51 +114,66 @@ function ensureConversation(id: string): void {
108
114
  if (ensuredConvIds.has(id)) return;
109
115
  const db = getDb();
110
116
  const now = Date.now();
111
- db.insert(conversations).values({
112
- id,
113
- title: `Test conversation ${id}`,
114
- createdAt: now,
115
- updatedAt: now,
116
- }).run();
117
+ db.insert(conversations)
118
+ .values({
119
+ id,
120
+ title: `Test conversation ${id}`,
121
+ createdAt: now,
122
+ updatedAt: now,
123
+ })
124
+ .run();
117
125
  ensuredConvIds.add(id);
118
126
  }
119
127
 
120
128
  function resetTables(): void {
121
129
  const db = getDb();
122
- db.run('DELETE FROM external_conversation_bindings');
123
- db.run('DELETE FROM call_sessions');
124
- db.run('DELETE FROM messages');
125
- db.run('DELETE FROM conversations');
130
+ db.run("DELETE FROM external_conversation_bindings");
131
+ db.run("DELETE FROM call_sessions");
132
+ db.run("DELETE FROM messages");
133
+ db.run("DELETE FROM conversations");
126
134
  ensuredConvIds = new Set();
127
135
  }
128
136
 
129
137
  function getLatestAssistantText(conversationId: string): string | null {
130
- const msgs = getMessages(conversationId).filter((m) => m.role === 'assistant');
138
+ const msgs = getMessages(conversationId).filter(
139
+ (m) => m.role === "assistant",
140
+ );
131
141
  if (msgs.length === 0) return null;
132
142
  const latest = msgs[msgs.length - 1];
133
143
  try {
134
144
  const parsed = JSON.parse(latest.content) as unknown;
135
145
  if (Array.isArray(parsed)) {
136
146
  return parsed
137
- .filter((b): b is { type: string; text?: string } => typeof b === 'object' && b != null)
138
- .filter((b) => b.type === 'text')
139
- .map((b) => b.text ?? '')
140
- .join('');
147
+ .filter(
148
+ (b): b is { type: string; text?: string } =>
149
+ typeof b === "object" && b != null,
150
+ )
151
+ .filter((b) => b.type === "text")
152
+ .map((b) => b.text ?? "")
153
+ .join("");
141
154
  }
142
- if (typeof parsed === 'string') return parsed;
143
- } catch { /* fall through */ }
155
+ if (typeof parsed === "string") return parsed;
156
+ } catch {
157
+ /* fall through */
158
+ }
144
159
  return latest.content;
145
160
  }
146
161
 
147
162
  afterAll(() => {
148
163
  resetDb();
149
- try { rmSync(testDir, { recursive: true }); } catch { /* best effort */ }
164
+ try {
165
+ rmSync(testDir, { recursive: true });
166
+ } catch {
167
+ /* best effort */
168
+ }
150
169
  });
151
170
 
152
- function makeConfig(overrides: {
153
- allowPerCallOverride?: boolean;
154
- userNumber?: string;
155
- } = {}): AssistantConfig {
171
+ function makeConfig(
172
+ overrides: {
173
+ allowPerCallOverride?: boolean;
174
+ userNumber?: string;
175
+ } = {},
176
+ ): AssistantConfig {
156
177
  return {
157
178
  calls: {
158
179
  callerIdentity: {
@@ -163,119 +184,126 @@ function makeConfig(overrides: {
163
184
  } as unknown as AssistantConfig;
164
185
  }
165
186
 
166
- describe('resolveCallerIdentity — strict implicit-default policy', () => {
167
- test('implicit call defaults to assistant_number', async () => {
187
+ describe("resolveCallerIdentity — strict implicit-default policy", () => {
188
+ test("implicit call defaults to assistant_number", async () => {
168
189
  const result = await resolveCallerIdentity(makeConfig());
169
190
  expect(result.ok).toBe(true);
170
191
  if (result.ok) {
171
- expect(result.mode).toBe('assistant_number');
172
- expect(result.fromNumber).toBe('+15550001111');
173
- expect(result.source).toBe('implicit_default');
192
+ expect(result.mode).toBe("assistant_number");
193
+ expect(result.fromNumber).toBe("+15550001111");
194
+ expect(result.source).toBe("implicit_default");
174
195
  }
175
196
  });
176
197
 
177
- test('implicit call uses assistant_number even when userNumber is configured', async () => {
198
+ test("implicit call uses assistant_number even when userNumber is configured", async () => {
178
199
  const result = await resolveCallerIdentity(
179
- makeConfig({ userNumber: '+15550002222' }),
200
+ makeConfig({ userNumber: "+15550002222" }),
180
201
  );
181
202
  expect(result.ok).toBe(true);
182
203
  if (result.ok) {
183
- expect(result.mode).toBe('assistant_number');
184
- expect(result.fromNumber).toBe('+15550001111');
185
- expect(result.source).toBe('implicit_default');
204
+ expect(result.mode).toBe("assistant_number");
205
+ expect(result.fromNumber).toBe("+15550001111");
206
+ expect(result.source).toBe("implicit_default");
186
207
  }
187
208
  });
188
209
 
189
- test('assistant_number resolves from assistant-scoped Twilio number when assistantId is provided', async () => {
190
- const result = await resolveCallerIdentity(makeConfig(), undefined, 'ast-alpha');
210
+ test("assistant_number resolves from assistant-scoped Twilio number when assistantId is provided", async () => {
211
+ const result = await resolveCallerIdentity(
212
+ makeConfig(),
213
+ undefined,
214
+ "ast-alpha",
215
+ );
191
216
  expect(result.ok).toBe(true);
192
217
  if (result.ok) {
193
- expect(result.mode).toBe('assistant_number');
194
- expect(result.fromNumber).toBe('+15550003333');
195
- expect(result.source).toBe('implicit_default');
218
+ expect(result.mode).toBe("assistant_number");
219
+ expect(result.fromNumber).toBe("+15550003333");
220
+ expect(result.source).toBe("implicit_default");
196
221
  }
197
222
  });
198
223
 
199
- test('explicit user_number succeeds when eligible', async () => {
224
+ test("explicit user_number succeeds when eligible", async () => {
200
225
  const result = await resolveCallerIdentity(
201
- makeConfig({ userNumber: '+15550002222' }),
202
- 'user_number',
226
+ makeConfig({ userNumber: "+15550002222" }),
227
+ "user_number",
203
228
  );
204
229
  expect(result.ok).toBe(true);
205
230
  if (result.ok) {
206
- expect(result.mode).toBe('user_number');
207
- expect(result.fromNumber).toBe('+15550002222');
208
- expect(result.source).toBe('user_config');
231
+ expect(result.mode).toBe("user_number");
232
+ expect(result.fromNumber).toBe("+15550002222");
233
+ expect(result.source).toBe("user_config");
209
234
  }
210
235
  });
211
236
 
212
- test('explicit user_number fails when no user phone configured', async () => {
213
- const result = await resolveCallerIdentity(makeConfig(), 'user_number');
237
+ test("explicit user_number fails when no user phone configured", async () => {
238
+ const result = await resolveCallerIdentity(makeConfig(), "user_number");
214
239
  expect(result.ok).toBe(false);
215
240
  if (!result.ok) {
216
- expect(result.error).toContain('user_number');
217
- expect(result.error).toContain('user phone number');
241
+ expect(result.error).toContain("user_number");
242
+ expect(result.error).toContain("user phone number");
218
243
  }
219
244
  });
220
245
 
221
- test('explicit user_number fails when number is ineligible', async () => {
246
+ test("explicit user_number fails when number is ineligible", async () => {
222
247
  const result = await resolveCallerIdentity(
223
- makeConfig({ userNumber: '+15559999999' }),
224
- 'user_number',
248
+ makeConfig({ userNumber: "+15559999999" }),
249
+ "user_number",
225
250
  );
226
251
  expect(result.ok).toBe(false);
227
252
  if (!result.ok) {
228
- expect(result.error).toContain('not eligible');
253
+ expect(result.error).toContain("not eligible");
229
254
  }
230
255
  });
231
256
 
232
- test('explicit override rejected when allowPerCallOverride=false', async () => {
257
+ test("explicit override rejected when allowPerCallOverride=false", async () => {
233
258
  const result = await resolveCallerIdentity(
234
- makeConfig({ allowPerCallOverride: false, userNumber: '+15550002222' }),
235
- 'user_number',
259
+ makeConfig({ allowPerCallOverride: false, userNumber: "+15550002222" }),
260
+ "user_number",
236
261
  );
237
262
  expect(result.ok).toBe(false);
238
263
  if (!result.ok) {
239
- expect(result.error).toContain('override is disabled');
264
+ expect(result.error).toContain("override is disabled");
240
265
  }
241
266
  });
242
267
 
243
- test('explicit assistant_number override succeeds when allowed', async () => {
244
- const result = await resolveCallerIdentity(makeConfig(), 'assistant_number');
268
+ test("explicit assistant_number override succeeds when allowed", async () => {
269
+ const result = await resolveCallerIdentity(
270
+ makeConfig(),
271
+ "assistant_number",
272
+ );
245
273
  expect(result.ok).toBe(true);
246
274
  if (result.ok) {
247
- expect(result.mode).toBe('assistant_number');
248
- expect(result.source).toBe('per_call_override');
275
+ expect(result.mode).toBe("assistant_number");
276
+ expect(result.source).toBe("per_call_override");
249
277
  }
250
278
  });
251
279
 
252
- test('invalid mode returns error', async () => {
280
+ test("invalid mode returns error", async () => {
253
281
  const result = await resolveCallerIdentity(
254
282
  makeConfig(),
255
- 'custom_number' as 'assistant_number',
283
+ "custom_number" as "assistant_number",
256
284
  );
257
285
  expect(result.ok).toBe(false);
258
286
  if (!result.ok) {
259
- expect(result.error).toContain('Invalid callerIdentityMode');
287
+ expect(result.error).toContain("Invalid callerIdentityMode");
260
288
  }
261
289
  });
262
290
  });
263
291
 
264
292
  // ── Pointer message regression tests ──────────────────────────────
265
293
 
266
- describe('startCall — pointer message regression', () => {
294
+ describe("startCall — pointer message regression", () => {
267
295
  beforeEach(() => {
268
296
  resetTables();
269
- twilioInitiateCallBehavior = 'success';
297
+ twilioInitiateCallBehavior = "success";
270
298
  });
271
299
 
272
- test('successful call writes a started pointer to the initiating conversation', async () => {
273
- const convId = 'conv-domain-ptr-start';
300
+ test("successful call writes a started pointer to the initiating conversation", async () => {
301
+ const convId = "conv-domain-ptr-start";
274
302
  ensureConversation(convId);
275
303
 
276
304
  const result = await startCall({
277
- phoneNumber: '+15559876543',
278
- task: 'Test call',
305
+ phoneNumber: "+15559876543",
306
+ task: "Test call",
279
307
  conversationId: convId,
280
308
  });
281
309
 
@@ -285,18 +313,18 @@ describe('startCall — pointer message regression', () => {
285
313
 
286
314
  const text = getLatestAssistantText(convId);
287
315
  expect(text).not.toBeNull();
288
- expect(text!).toContain('+15559876543');
289
- expect(text!).toContain('started');
316
+ expect(text!).toContain("+15559876543");
317
+ expect(text!).toContain("started");
290
318
  });
291
319
 
292
- test('failed call writes a failed pointer to the initiating conversation', async () => {
293
- const convId = 'conv-domain-ptr-fail';
320
+ test("failed call writes a failed pointer to the initiating conversation", async () => {
321
+ const convId = "conv-domain-ptr-fail";
294
322
  ensureConversation(convId);
295
- twilioInitiateCallBehavior = 'error';
323
+ twilioInitiateCallBehavior = "error";
296
324
 
297
325
  const result = await startCall({
298
- phoneNumber: '+15559876543',
299
- task: 'Test call',
326
+ phoneNumber: "+15559876543",
327
+ task: "Test call",
300
328
  conversationId: convId,
301
329
  });
302
330
 
@@ -306,7 +334,7 @@ describe('startCall — pointer message regression', () => {
306
334
 
307
335
  const text = getLatestAssistantText(convId);
308
336
  expect(text).not.toBeNull();
309
- expect(text!).toContain('+15559876543');
310
- expect(text!).toContain('failed');
337
+ expect(text!).toContain("+15559876543");
338
+ expect(text!).toContain("failed");
311
339
  });
312
340
  });