@vellumai/assistant 0.4.17 → 0.4.19

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 (528) hide show
  1. package/docs/runbook-trusted-contacts.md +5 -3
  2. package/eslint.config.mjs +2 -2
  3. package/package.json +1 -1
  4. package/src/__tests__/access-request-decision.test.ts +128 -120
  5. package/src/__tests__/account-registry.test.ts +121 -110
  6. package/src/__tests__/active-skill-tools.test.ts +200 -172
  7. package/src/__tests__/actor-token-service.test.ts +341 -274
  8. package/src/__tests__/agent-loop-thinking.test.ts +28 -19
  9. package/src/__tests__/agent-loop.test.ts +798 -378
  10. package/src/__tests__/anthropic-provider.test.ts +405 -247
  11. package/src/__tests__/app-builder-tool-scripts.test.ts +97 -97
  12. package/src/__tests__/app-bundler.test.ts +112 -79
  13. package/src/__tests__/app-executors.test.ts +205 -178
  14. package/src/__tests__/app-git-history.test.ts +90 -73
  15. package/src/__tests__/app-git-service.test.ts +67 -53
  16. package/src/__tests__/app-open-proxy.test.ts +29 -25
  17. package/src/__tests__/approval-conversation-turn.test.ts +100 -81
  18. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +45 -17
  19. package/src/__tests__/approval-message-composer.test.ts +119 -119
  20. package/src/__tests__/approval-primitive.test.ts +264 -233
  21. package/src/__tests__/approval-routes-http.test.ts +4 -3
  22. package/src/__tests__/asset-materialize-tool.test.ts +250 -178
  23. package/src/__tests__/asset-search-tool.test.ts +251 -191
  24. package/src/__tests__/assistant-attachment-directive.test.ts +187 -142
  25. package/src/__tests__/assistant-attachments.test.ts +254 -186
  26. package/src/__tests__/assistant-event-hub.test.ts +105 -63
  27. package/src/__tests__/assistant-event.test.ts +66 -58
  28. package/src/__tests__/assistant-events-sse-hardening.test.ts +113 -73
  29. package/src/__tests__/assistant-feature-flag-guard.test.ts +78 -52
  30. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +48 -45
  31. package/src/__tests__/assistant-feature-flags-integration.test.ts +118 -77
  32. package/src/__tests__/assistant-id-boundary-guard.test.ts +158 -104
  33. package/src/__tests__/attachments-store.test.ts +240 -183
  34. package/src/__tests__/attachments.test.ts +70 -62
  35. package/src/__tests__/audit-log-rotation.test.ts +50 -35
  36. package/src/__tests__/browser-fill-credential.test.ts +169 -101
  37. package/src/__tests__/browser-manager.test.ts +97 -75
  38. package/src/__tests__/browser-runtime-check.test.ts +16 -15
  39. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +12 -10
  40. package/src/__tests__/browser-skill-endstate.test.ts +97 -72
  41. package/src/__tests__/bundle-scanner.test.ts +47 -22
  42. package/src/__tests__/bundled-asset.test.ts +74 -47
  43. package/src/__tests__/call-constants.test.ts +19 -19
  44. package/src/__tests__/call-controller.test.ts +0 -1
  45. package/src/__tests__/call-conversation-messages.test.ts +90 -65
  46. package/src/__tests__/call-domain.test.ts +149 -121
  47. package/src/__tests__/call-pointer-message-composer.test.ts +113 -83
  48. package/src/__tests__/call-pointer-messages.test.ts +213 -154
  49. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +9 -10
  50. package/src/__tests__/call-recovery.test.ts +232 -212
  51. package/src/__tests__/call-routes-http.test.ts +0 -1
  52. package/src/__tests__/call-start-guardian-guard.test.ts +32 -30
  53. package/src/__tests__/call-state-machine.test.ts +62 -51
  54. package/src/__tests__/call-state.test.ts +89 -75
  55. package/src/__tests__/call-store.test.ts +387 -316
  56. package/src/__tests__/callback-handoff-copy.test.ts +84 -82
  57. package/src/__tests__/canonical-guardian-store.test.ts +331 -280
  58. package/src/__tests__/channel-approval-routes.test.ts +1643 -1115
  59. package/src/__tests__/channel-approval.test.ts +139 -137
  60. package/src/__tests__/channel-approvals.test.ts +7 -2
  61. package/src/__tests__/channel-delivery-store.test.ts +232 -194
  62. package/src/__tests__/channel-guardian.test.ts +5 -3
  63. package/src/__tests__/channel-invite-transport.test.ts +107 -92
  64. package/src/__tests__/channel-policy.test.ts +42 -38
  65. package/src/__tests__/channel-readiness-service.test.ts +119 -102
  66. package/src/__tests__/channel-reply-delivery.test.ts +147 -118
  67. package/src/__tests__/channel-retry-sweep.test.ts +153 -110
  68. package/src/__tests__/checker.test.ts +3309 -1850
  69. package/src/__tests__/clarification-resolver.test.ts +91 -79
  70. package/src/__tests__/classifier.test.ts +64 -54
  71. package/src/__tests__/claude-code-skill-regression.test.ts +42 -37
  72. package/src/__tests__/claude-code-tool-profiles.test.ts +31 -29
  73. package/src/__tests__/clawhub.test.ts +92 -82
  74. package/src/__tests__/cli.test.ts +30 -30
  75. package/src/__tests__/clipboard.test.ts +53 -46
  76. package/src/__tests__/commit-guarantee.test.ts +59 -52
  77. package/src/__tests__/commit-message-enrichment-service.test.ts +203 -75
  78. package/src/__tests__/compaction.benchmark.test.ts +33 -31
  79. package/src/__tests__/computer-use-session-compaction.test.ts +60 -50
  80. package/src/__tests__/computer-use-session-lifecycle.test.ts +145 -117
  81. package/src/__tests__/computer-use-session-working-dir.test.ts +62 -48
  82. package/src/__tests__/computer-use-skill-baseline.test.ts +22 -19
  83. package/src/__tests__/computer-use-skill-endstate.test.ts +45 -31
  84. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +121 -88
  85. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +65 -42
  86. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +33 -18
  87. package/src/__tests__/computer-use-tools.test.ts +121 -98
  88. package/src/__tests__/config-schema.test.ts +443 -347
  89. package/src/__tests__/config-watcher.test.ts +96 -81
  90. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +148 -133
  91. package/src/__tests__/conflict-intent-tokenization.test.ts +96 -78
  92. package/src/__tests__/conflict-policy.test.ts +151 -80
  93. package/src/__tests__/conflict-store.test.ts +203 -157
  94. package/src/__tests__/connection-policy.test.ts +89 -59
  95. package/src/__tests__/contacts-tools.test.ts +247 -178
  96. package/src/__tests__/context-memory-e2e.test.ts +306 -214
  97. package/src/__tests__/context-token-estimator.test.ts +114 -74
  98. package/src/__tests__/context-window-manager.test.ts +269 -167
  99. package/src/__tests__/contradiction-checker.test.ts +161 -135
  100. package/src/__tests__/conversation-attention-store.test.ts +350 -290
  101. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  102. package/src/__tests__/conversation-pairing.test.ts +220 -113
  103. package/src/__tests__/conversation-routes-guardian-reply.test.ts +8 -0
  104. package/src/__tests__/conversation-store.test.ts +390 -235
  105. package/src/__tests__/credential-broker-browser-fill.test.ts +325 -250
  106. package/src/__tests__/credential-broker-server-use.test.ts +283 -243
  107. package/src/__tests__/credential-broker.test.ts +128 -74
  108. package/src/__tests__/credential-host-pattern-match.test.ts +64 -44
  109. package/src/__tests__/credential-metadata-store.test.ts +360 -311
  110. package/src/__tests__/credential-policy-validate.test.ts +81 -65
  111. package/src/__tests__/credential-resolve.test.ts +212 -145
  112. package/src/__tests__/credential-security-e2e.test.ts +144 -103
  113. package/src/__tests__/credential-security-invariants.test.ts +253 -208
  114. package/src/__tests__/credential-selection.test.ts +254 -146
  115. package/src/__tests__/credential-vault-unit.test.ts +531 -341
  116. package/src/__tests__/credential-vault.test.ts +761 -484
  117. package/src/__tests__/daemon-assistant-events.test.ts +91 -66
  118. package/src/__tests__/daemon-lifecycle.test.ts +258 -190
  119. package/src/__tests__/daemon-server-session-init.test.ts +2 -1
  120. package/src/__tests__/date-context.test.ts +314 -249
  121. package/src/__tests__/db-migration-rollback.test.ts +259 -130
  122. package/src/__tests__/db-schedule-syntax-migration.test.ts +78 -41
  123. package/src/__tests__/delete-managed-skill-tool.test.ts +77 -53
  124. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
  125. package/src/__tests__/dictation-mode-detection.test.ts +77 -55
  126. package/src/__tests__/dictation-profile-store.test.ts +70 -56
  127. package/src/__tests__/dictation-text-processing.test.ts +53 -35
  128. package/src/__tests__/diff.test.ts +102 -98
  129. package/src/__tests__/domain-normalize.test.ts +54 -54
  130. package/src/__tests__/domain-policy.test.ts +71 -55
  131. package/src/__tests__/dynamic-page-surface.test.ts +31 -33
  132. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +69 -69
  133. package/src/__tests__/edit-engine.test.ts +56 -56
  134. package/src/__tests__/elevenlabs-client.test.ts +117 -91
  135. package/src/__tests__/elevenlabs-config.test.ts +32 -31
  136. package/src/__tests__/email-classifier.test.ts +15 -12
  137. package/src/__tests__/email-cli.test.ts +121 -108
  138. package/src/__tests__/emit-signal-routing-intent.test.ts +76 -69
  139. package/src/__tests__/encrypted-store.test.ts +180 -154
  140. package/src/__tests__/entity-extractor.test.ts +108 -87
  141. package/src/__tests__/entity-search.test.ts +664 -258
  142. package/src/__tests__/ephemeral-permissions.test.ts +224 -188
  143. package/src/__tests__/event-bus.test.ts +81 -77
  144. package/src/__tests__/extract-email.test.ts +29 -20
  145. package/src/__tests__/file-edit-tool.test.ts +62 -44
  146. package/src/__tests__/file-ops-service.test.ts +131 -114
  147. package/src/__tests__/file-read-tool.test.ts +48 -31
  148. package/src/__tests__/file-write-tool.test.ts +43 -37
  149. package/src/__tests__/filesystem-tools.test.ts +238 -209
  150. package/src/__tests__/followup-tools.test.ts +237 -162
  151. package/src/__tests__/forbidden-legacy-symbols.test.ts +19 -20
  152. package/src/__tests__/frontmatter.test.ts +96 -81
  153. package/src/__tests__/fuzzy-match-property.test.ts +75 -81
  154. package/src/__tests__/fuzzy-match.test.ts +71 -65
  155. package/src/__tests__/gateway-client-managed-outbound.test.ts +76 -57
  156. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  157. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  158. package/src/__tests__/gemini-image-service.test.ts +113 -100
  159. package/src/__tests__/gemini-provider.test.ts +297 -220
  160. package/src/__tests__/get-weather.test.ts +188 -114
  161. package/src/__tests__/gmail-integration.test.ts +13 -5
  162. package/src/__tests__/guardian-action-conversation-turn.test.ts +226 -171
  163. package/src/__tests__/guardian-action-copy-generator.test.ts +111 -93
  164. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
  165. package/src/__tests__/guardian-action-followup-store.test.ts +199 -167
  166. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +297 -250
  167. package/src/__tests__/guardian-action-late-reply.test.ts +462 -316
  168. package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +23 -18
  169. package/src/__tests__/guardian-action-store.test.ts +158 -109
  170. package/src/__tests__/guardian-action-sweep.test.ts +114 -100
  171. package/src/__tests__/guardian-actions-endpoint.test.ts +440 -256
  172. package/src/__tests__/guardian-control-plane-policy.test.ts +497 -331
  173. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +217 -215
  174. package/src/__tests__/guardian-dispatch.test.ts +316 -256
  175. package/src/__tests__/guardian-grant-minting.test.ts +247 -178
  176. package/src/__tests__/guardian-outbound-http.test.ts +5 -3
  177. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +99 -96
  178. package/src/__tests__/guardian-question-copy.test.ts +17 -17
  179. package/src/__tests__/guardian-question-mode.test.ts +134 -100
  180. package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
  181. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  182. package/src/__tests__/guardian-verification-intent-routing.test.ts +94 -88
  183. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  184. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +0 -1
  185. package/src/__tests__/handle-user-message-secret-resume.test.ts +7 -2
  186. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +92 -76
  187. package/src/__tests__/handlers-cu-observation-blob.test.ts +103 -70
  188. package/src/__tests__/handlers-ipc-blob-probe.test.ts +77 -51
  189. package/src/__tests__/handlers-slack-config.test.ts +63 -54
  190. package/src/__tests__/handlers-task-submit-slash.test.ts +18 -18
  191. package/src/__tests__/handlers-telegram-config.test.ts +662 -329
  192. package/src/__tests__/handlers-twitter-config.test.ts +525 -298
  193. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +5 -2
  194. package/src/__tests__/headless-browser-interactions.test.ts +444 -280
  195. package/src/__tests__/headless-browser-navigate.test.ts +116 -79
  196. package/src/__tests__/headless-browser-read-tools.test.ts +123 -86
  197. package/src/__tests__/headless-browser-snapshot.test.ts +71 -56
  198. package/src/__tests__/heartbeat-service.test.ts +76 -58
  199. package/src/__tests__/history-repair-observability.test.ts +14 -14
  200. package/src/__tests__/history-repair.test.ts +171 -167
  201. package/src/__tests__/home-base-bootstrap.test.ts +30 -27
  202. package/src/__tests__/hooks-blocking.test.ts +86 -37
  203. package/src/__tests__/hooks-cli.test.ts +104 -68
  204. package/src/__tests__/hooks-config.test.ts +81 -43
  205. package/src/__tests__/hooks-discovery.test.ts +106 -96
  206. package/src/__tests__/hooks-integration.test.ts +78 -72
  207. package/src/__tests__/hooks-manager.test.ts +99 -61
  208. package/src/__tests__/hooks-runner.test.ts +94 -71
  209. package/src/__tests__/hooks-settings.test.ts +69 -64
  210. package/src/__tests__/hooks-templates.test.ts +85 -54
  211. package/src/__tests__/hooks-ts-runner.test.ts +82 -45
  212. package/src/__tests__/hooks-watch.test.ts +32 -22
  213. package/src/__tests__/host-file-edit-tool.test.ts +190 -148
  214. package/src/__tests__/host-file-read-tool.test.ts +86 -63
  215. package/src/__tests__/host-file-write-tool.test.ts +98 -64
  216. package/src/__tests__/host-shell-tool.test.ts +342 -233
  217. package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
  218. package/src/__tests__/ingress-member-store.test.ts +163 -159
  219. package/src/__tests__/ingress-reconcile.test.ts +13 -6
  220. package/src/__tests__/ingress-routes-http.test.ts +441 -356
  221. package/src/__tests__/ingress-url-consistency.test.ts +125 -64
  222. package/src/__tests__/integration-status.test.ts +93 -73
  223. package/src/__tests__/intent-routing.test.ts +148 -118
  224. package/src/__tests__/invite-redemption-service.test.ts +163 -121
  225. package/src/__tests__/ipc-blob-store.test.ts +104 -91
  226. package/src/__tests__/ipc-contract-inventory.test.ts +27 -15
  227. package/src/__tests__/ipc-contract.test.ts +24 -23
  228. package/src/__tests__/ipc-protocol.test.ts +52 -46
  229. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +61 -50
  230. package/src/__tests__/ipc-snapshot.test.ts +1135 -1056
  231. package/src/__tests__/ipc-validate.test.ts +240 -179
  232. package/src/__tests__/key-migration.test.ts +123 -90
  233. package/src/__tests__/keychain.test.ts +150 -123
  234. package/src/__tests__/lifecycle-docs-guard.test.ts +65 -64
  235. package/src/__tests__/llm-usage-store.test.ts +112 -87
  236. package/src/__tests__/managed-skill-lifecycle.test.ts +147 -108
  237. package/src/__tests__/managed-store.test.ts +411 -360
  238. package/src/__tests__/mcp-cli.test.ts +190 -124
  239. package/src/__tests__/mcp-health-check.test.ts +26 -21
  240. package/src/__tests__/media-generate-image.test.ts +122 -99
  241. package/src/__tests__/media-reuse-story.e2e.test.ts +282 -214
  242. package/src/__tests__/media-visibility-policy.test.ts +86 -38
  243. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +146 -100
  244. package/src/__tests__/memory-lifecycle-e2e.test.ts +385 -297
  245. package/src/__tests__/memory-query-builder.test.ts +32 -33
  246. package/src/__tests__/memory-recall-quality.test.ts +761 -407
  247. package/src/__tests__/memory-regressions.experimental.test.ts +443 -380
  248. package/src/__tests__/memory-regressions.test.ts +3725 -2642
  249. package/src/__tests__/memory-retrieval-budget.test.ts +7 -8
  250. package/src/__tests__/memory-retrieval.benchmark.test.ts +144 -109
  251. package/src/__tests__/memory-upsert-concurrency.test.ts +292 -201
  252. package/src/__tests__/messaging-send-tool.test.ts +36 -29
  253. package/src/__tests__/migration-cli-flows.test.ts +69 -53
  254. package/src/__tests__/migration-ordering.test.ts +103 -86
  255. package/src/__tests__/mime-builder.test.ts +55 -32
  256. package/src/__tests__/mock-signup-server.test.ts +384 -246
  257. package/src/__tests__/model-intents.test.ts +61 -37
  258. package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +9 -12
  259. package/src/__tests__/no-is-trusted-guard.test.ts +24 -21
  260. package/src/__tests__/non-member-access-request.test.ts +3 -2
  261. package/src/__tests__/notification-broadcaster.test.ts +99 -81
  262. package/src/__tests__/notification-decision-fallback.test.ts +223 -178
  263. package/src/__tests__/notification-decision-strategy.test.ts +375 -337
  264. package/src/__tests__/notification-deep-link.test.ts +67 -61
  265. package/src/__tests__/notification-guardian-path.test.ts +248 -206
  266. package/src/__tests__/notification-routing-intent.test.ts +166 -93
  267. package/src/__tests__/notification-thread-candidate-validation.test.ts +78 -75
  268. package/src/__tests__/notification-thread-candidates.test.ts +64 -61
  269. package/src/__tests__/oauth-callback-registry.test.ts +40 -30
  270. package/src/__tests__/oauth-connect-handler.test.ts +109 -89
  271. package/src/__tests__/oauth-scope-policy.test.ts +63 -55
  272. package/src/__tests__/oauth2-gateway-transport.test.ts +252 -174
  273. package/src/__tests__/onboarding-starter-tasks.test.ts +93 -89
  274. package/src/__tests__/onboarding-template-contract.test.ts +93 -94
  275. package/src/__tests__/openai-provider.test.ts +366 -274
  276. package/src/__tests__/pairing-concurrent.test.ts +18 -12
  277. package/src/__tests__/pairing-routes.test.ts +45 -41
  278. package/src/__tests__/parallel-tool.benchmark.test.ts +108 -58
  279. package/src/__tests__/parser.test.ts +316 -226
  280. package/src/__tests__/path-classifier.test.ts +24 -25
  281. package/src/__tests__/path-policy.test.ts +187 -147
  282. package/src/__tests__/phone.test.ts +36 -36
  283. package/src/__tests__/platform-move-helper.test.ts +48 -40
  284. package/src/__tests__/platform-socket-path.test.ts +23 -24
  285. package/src/__tests__/platform-workspace-migration.test.ts +464 -414
  286. package/src/__tests__/platform.test.ts +61 -53
  287. package/src/__tests__/playbook-execution.test.ts +397 -265
  288. package/src/__tests__/playbook-tools.test.ts +267 -196
  289. package/src/__tests__/prebuilt-home-base-seed.test.ts +30 -27
  290. package/src/__tests__/pricing.test.ts +316 -136
  291. package/src/__tests__/profile-compiler.test.ts +206 -188
  292. package/src/__tests__/provider-commit-message-generator.test.ts +114 -106
  293. package/src/__tests__/provider-error-scenarios.test.ts +212 -158
  294. package/src/__tests__/provider-fail-open-selection.test.ts +51 -44
  295. package/src/__tests__/provider-registry-ollama.test.ts +13 -9
  296. package/src/__tests__/provider-streaming.benchmark.test.ts +232 -183
  297. package/src/__tests__/proxy-approval-callback.test.ts +180 -119
  298. package/src/__tests__/public-ingress-urls.test.ts +112 -94
  299. package/src/__tests__/qdrant-manager.test.ts +147 -98
  300. package/src/__tests__/ratelimit.test.ts +152 -82
  301. package/src/__tests__/recording-handler.test.ts +273 -151
  302. package/src/__tests__/recording-intent-fallback.test.ts +94 -75
  303. package/src/__tests__/recording-intent-handler.test.ts +9 -2
  304. package/src/__tests__/recording-intent.test.ts +578 -379
  305. package/src/__tests__/recording-state-machine.test.ts +530 -316
  306. package/src/__tests__/recurrence-engine-rruleset.test.ts +150 -92
  307. package/src/__tests__/recurrence-engine.test.ts +81 -41
  308. package/src/__tests__/recurrence-types.test.ts +63 -44
  309. package/src/__tests__/relay-server.test.ts +2131 -1602
  310. package/src/__tests__/reminder-store.test.ts +158 -80
  311. package/src/__tests__/reminder.test.ts +113 -109
  312. package/src/__tests__/remote-skill-policy.test.ts +96 -72
  313. package/src/__tests__/request-file-tool.test.ts +74 -67
  314. package/src/__tests__/response-tier.test.ts +131 -74
  315. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  316. package/src/__tests__/runtime-events-sse-parity.test.ts +167 -145
  317. package/src/__tests__/runtime-events-sse.test.ts +0 -1
  318. package/src/__tests__/sandbox-diagnostics.test.ts +66 -56
  319. package/src/__tests__/sandbox-host-parity.test.ts +377 -301
  320. package/src/__tests__/scaffold-managed-skill-tool.test.ts +213 -161
  321. package/src/__tests__/schedule-store.test.ts +268 -205
  322. package/src/__tests__/schedule-tools.test.ts +702 -524
  323. package/src/__tests__/scheduler-recurrence.test.ts +240 -130
  324. package/src/__tests__/scoped-approval-grants.test.ts +258 -168
  325. package/src/__tests__/scoped-grant-security-matrix.test.ts +160 -146
  326. package/src/__tests__/script-proxy-certs.test.ts +38 -35
  327. package/src/__tests__/script-proxy-connect-tunnel.test.ts +71 -46
  328. package/src/__tests__/script-proxy-decision-trace.test.ts +161 -84
  329. package/src/__tests__/script-proxy-http-forwarder.test.ts +146 -129
  330. package/src/__tests__/script-proxy-injection-runtime.test.ts +139 -113
  331. package/src/__tests__/script-proxy-mitm-handler.test.ts +226 -142
  332. package/src/__tests__/script-proxy-policy-runtime.test.ts +126 -86
  333. package/src/__tests__/script-proxy-policy.test.ts +308 -153
  334. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +74 -62
  335. package/src/__tests__/script-proxy-router.test.ts +111 -77
  336. package/src/__tests__/script-proxy-session-manager.test.ts +156 -113
  337. package/src/__tests__/script-proxy-session-runtime.test.ts +28 -24
  338. package/src/__tests__/secret-allowlist.test.ts +105 -90
  339. package/src/__tests__/secret-ingress-handler.test.ts +41 -30
  340. package/src/__tests__/secret-onetime-send.test.ts +67 -50
  341. package/src/__tests__/secret-prompt-log-hygiene.test.ts +35 -31
  342. package/src/__tests__/secret-response-routing.test.ts +50 -41
  343. package/src/__tests__/secret-scanner-executor.test.ts +152 -111
  344. package/src/__tests__/secret-scanner.test.ts +495 -413
  345. package/src/__tests__/secure-keys.test.ts +132 -121
  346. package/src/__tests__/send-endpoint-busy.test.ts +8 -3
  347. package/src/__tests__/send-notification-tool.test.ts +43 -42
  348. package/src/__tests__/sensitive-output-placeholders.test.ts +72 -64
  349. package/src/__tests__/sequence-store.test.ts +335 -167
  350. package/src/__tests__/server-history-render.test.ts +341 -202
  351. package/src/__tests__/session-abort-tool-results.test.ts +133 -70
  352. package/src/__tests__/session-confirmation-signals.test.ts +252 -160
  353. package/src/__tests__/session-conflict-gate.test.ts +775 -585
  354. package/src/__tests__/session-error.test.ts +222 -191
  355. package/src/__tests__/session-evictor.test.ts +79 -62
  356. package/src/__tests__/session-init.benchmark.test.ts +170 -108
  357. package/src/__tests__/session-load-history-repair.test.ts +273 -139
  358. package/src/__tests__/session-messaging-secret-redirect.test.ts +130 -90
  359. package/src/__tests__/session-pre-run-repair.test.ts +106 -59
  360. package/src/__tests__/session-profile-injection.test.ts +198 -130
  361. package/src/__tests__/session-provider-retry-repair.test.ts +223 -141
  362. package/src/__tests__/session-queue.test.ts +624 -321
  363. package/src/__tests__/session-runtime-assembly.test.ts +425 -329
  364. package/src/__tests__/session-runtime-workspace.test.ts +69 -61
  365. package/src/__tests__/session-skill-tools.test.ts +973 -678
  366. package/src/__tests__/session-slash-known.test.ts +185 -133
  367. package/src/__tests__/session-slash-queue.test.ts +147 -81
  368. package/src/__tests__/session-slash-unknown.test.ts +135 -90
  369. package/src/__tests__/session-surfaces-task-progress.test.ts +122 -87
  370. package/src/__tests__/session-tool-setup-app-refresh.test.ts +338 -177
  371. package/src/__tests__/session-tool-setup-memory-scope.test.ts +63 -40
  372. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +60 -37
  373. package/src/__tests__/session-tool-setup-tools-disabled.test.ts +28 -26
  374. package/src/__tests__/session-undo.test.ts +43 -30
  375. package/src/__tests__/session-workspace-cache-state.test.ts +108 -67
  376. package/src/__tests__/session-workspace-injection.test.ts +245 -117
  377. package/src/__tests__/session-workspace-tool-tracking.test.ts +260 -93
  378. package/src/__tests__/shared-filesystem-errors.test.ts +47 -47
  379. package/src/__tests__/shell-credential-ref.test.ts +126 -90
  380. package/src/__tests__/shell-identity.test.ts +134 -111
  381. package/src/__tests__/shell-parser-fuzz.test.ts +263 -179
  382. package/src/__tests__/shell-parser-property.test.ts +435 -288
  383. package/src/__tests__/shell-tool-proxy-mode.test.ts +142 -70
  384. package/src/__tests__/size-guard.test.ts +42 -44
  385. package/src/__tests__/skill-feature-flags-integration.test.ts +79 -52
  386. package/src/__tests__/skill-feature-flags.test.ts +75 -47
  387. package/src/__tests__/skill-include-graph.test.ts +143 -148
  388. package/src/__tests__/skill-load-feature-flag.test.ts +94 -59
  389. package/src/__tests__/skill-load-tool.test.ts +371 -199
  390. package/src/__tests__/skill-projection-feature-flag.test.ts +131 -88
  391. package/src/__tests__/skill-projection.benchmark.test.ts +93 -65
  392. package/src/__tests__/skill-script-runner-host.test.ts +460 -250
  393. package/src/__tests__/skill-script-runner-sandbox.test.ts +168 -108
  394. package/src/__tests__/skill-script-runner.test.ts +115 -74
  395. package/src/__tests__/skill-tool-factory.test.ts +140 -96
  396. package/src/__tests__/skill-tool-manifest.test.ts +306 -210
  397. package/src/__tests__/skill-version-hash.test.ts +70 -56
  398. package/src/__tests__/skills.test.ts +0 -1
  399. package/src/__tests__/slack-channel-config.test.ts +127 -84
  400. package/src/__tests__/slack-skill.test.ts +60 -47
  401. package/src/__tests__/slash-commands-catalog.test.ts +37 -31
  402. package/src/__tests__/slash-commands-parser.test.ts +71 -64
  403. package/src/__tests__/slash-commands-resolver.test.ts +143 -107
  404. package/src/__tests__/slash-commands-rewrite.test.ts +22 -22
  405. package/src/__tests__/sms-messaging-provider.test.ts +4 -0
  406. package/src/__tests__/speaker-identification.test.ts +28 -25
  407. package/src/__tests__/starter-bundle.test.ts +27 -23
  408. package/src/__tests__/starter-task-flow.test.ts +67 -52
  409. package/src/__tests__/subagent-manager-notify.test.ts +154 -108
  410. package/src/__tests__/subagent-tools.test.ts +311 -270
  411. package/src/__tests__/subagent-types.test.ts +40 -40
  412. package/src/__tests__/surface-mutex-cleanup.test.ts +42 -30
  413. package/src/__tests__/swarm-dag-pathological.test.ts +122 -111
  414. package/src/__tests__/swarm-orchestrator.test.ts +135 -101
  415. package/src/__tests__/swarm-plan-validator.test.ts +125 -73
  416. package/src/__tests__/swarm-recursion.test.ts +58 -46
  417. package/src/__tests__/swarm-router-planner.test.ts +99 -74
  418. package/src/__tests__/swarm-session-integration.test.ts +148 -91
  419. package/src/__tests__/swarm-tool.test.ts +65 -45
  420. package/src/__tests__/swarm-worker-backend.test.ts +59 -45
  421. package/src/__tests__/swarm-worker-runner.test.ts +133 -118
  422. package/src/__tests__/system-prompt.test.ts +311 -256
  423. package/src/__tests__/task-compiler.test.ts +176 -120
  424. package/src/__tests__/task-management-tools.test.ts +561 -456
  425. package/src/__tests__/task-memory-cleanup.test.ts +627 -362
  426. package/src/__tests__/task-runner.test.ts +117 -94
  427. package/src/__tests__/task-scheduler.test.ts +113 -84
  428. package/src/__tests__/task-tools.test.ts +349 -264
  429. package/src/__tests__/terminal-sandbox.test.ts +138 -108
  430. package/src/__tests__/terminal-tools.test.ts +350 -305
  431. package/src/__tests__/thread-seed-composer.test.ts +307 -180
  432. package/src/__tests__/tool-approval-handler.test.ts +238 -137
  433. package/src/__tests__/tool-audit-listener.test.ts +69 -69
  434. package/src/__tests__/tool-domain-event-publisher.test.ts +142 -132
  435. package/src/__tests__/tool-execution-abort-cleanup.test.ts +155 -146
  436. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +136 -105
  437. package/src/__tests__/tool-executor-lifecycle-events.test.ts +355 -239
  438. package/src/__tests__/tool-executor-redaction.test.ts +112 -109
  439. package/src/__tests__/tool-executor-shell-integration.test.ts +130 -79
  440. package/src/__tests__/tool-executor.test.ts +1274 -674
  441. package/src/__tests__/tool-grant-request-escalation.test.ts +401 -283
  442. package/src/__tests__/tool-metrics-listener.test.ts +97 -85
  443. package/src/__tests__/tool-notification-listener.test.ts +42 -25
  444. package/src/__tests__/tool-permission-simulate-handler.test.ts +137 -113
  445. package/src/__tests__/tool-policy.test.ts +44 -25
  446. package/src/__tests__/tool-profiling-listener.test.ts +99 -93
  447. package/src/__tests__/tool-result-truncation.test.ts +5 -4
  448. package/src/__tests__/tool-trace-listener.test.ts +131 -111
  449. package/src/__tests__/top-level-renderer.test.ts +62 -58
  450. package/src/__tests__/top-level-scanner.test.ts +68 -64
  451. package/src/__tests__/trace-emitter.test.ts +56 -56
  452. package/src/__tests__/trust-context-guards.test.ts +65 -65
  453. package/src/__tests__/trust-store.test.ts +1239 -806
  454. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  455. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  456. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +3 -2
  457. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -2
  458. package/src/__tests__/trusted-contact-verification.test.ts +251 -231
  459. package/src/__tests__/turn-commit.test.ts +259 -200
  460. package/src/__tests__/twilio-provider.test.ts +140 -126
  461. package/src/__tests__/twilio-rest.test.ts +22 -18
  462. package/src/__tests__/twilio-routes-elevenlabs.test.ts +0 -1
  463. package/src/__tests__/twilio-routes-twiml.test.ts +55 -55
  464. package/src/__tests__/twilio-routes.test.ts +0 -1
  465. package/src/__tests__/twitter-auth-handler.test.ts +184 -139
  466. package/src/__tests__/twitter-cli-error-shaping.test.ts +88 -73
  467. package/src/__tests__/twitter-cli-routing.test.ts +146 -99
  468. package/src/__tests__/twitter-oauth-client.test.ts +82 -65
  469. package/src/__tests__/update-bulletin-format.test.ts +69 -66
  470. package/src/__tests__/update-bulletin-state.test.ts +66 -60
  471. package/src/__tests__/update-bulletin.test.ts +150 -114
  472. package/src/__tests__/update-template-contract.test.ts +15 -10
  473. package/src/__tests__/url-safety.test.ts +288 -265
  474. package/src/__tests__/user-reference.test.ts +32 -32
  475. package/src/__tests__/view-image-tool.test.ts +118 -96
  476. package/src/__tests__/voice-invite-redemption.test.ts +111 -106
  477. package/src/__tests__/voice-quality.test.ts +117 -102
  478. package/src/__tests__/voice-scoped-grant-consumer.test.ts +204 -146
  479. package/src/__tests__/voice-session-bridge.test.ts +351 -216
  480. package/src/__tests__/weather-skill-regression.test.ts +170 -120
  481. package/src/__tests__/web-fetch.test.ts +664 -526
  482. package/src/__tests__/web-search.test.ts +379 -213
  483. package/src/__tests__/work-item-output.test.ts +90 -53
  484. package/src/__tests__/workspace-git-service.test.ts +437 -356
  485. package/src/__tests__/workspace-heartbeat-service.test.ts +125 -91
  486. package/src/__tests__/workspace-lifecycle.test.ts +98 -64
  487. package/src/__tests__/workspace-policy.test.ts +139 -71
  488. package/src/cli/mcp.ts +81 -28
  489. package/src/commands/__tests__/cc-command-registry.test.ts +142 -134
  490. package/src/config/__tests__/feature-flag-registry-guard.test.ts +48 -39
  491. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +25 -10
  492. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +0 -1
  493. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +6 -11
  494. package/src/config/bundled-skills/messaging/SKILL.md +4 -3
  495. package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +15 -5
  496. package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +16 -5
  497. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -2
  498. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +34 -32
  499. package/src/config/bundled-skills/sms-setup/SKILL.md +8 -16
  500. package/src/config/bundled-skills/telegram-setup/SKILL.md +3 -3
  501. package/src/config/bundled-skills/trusted-contacts/SKILL.md +13 -25
  502. package/src/config/bundled-skills/twilio-setup/SKILL.md +13 -23
  503. package/src/config/bundled-tool-registry.ts +2 -0
  504. package/src/config/env.ts +3 -4
  505. package/src/config/system-prompt.ts +32 -0
  506. package/src/mcp/client.ts +2 -7
  507. package/src/memory/db-connection.ts +16 -10
  508. package/src/messaging/providers/gmail/adapter.ts +10 -3
  509. package/src/messaging/providers/gmail/client.ts +280 -72
  510. package/src/runtime/auth/__tests__/context.test.ts +75 -65
  511. package/src/runtime/auth/__tests__/credential-service.test.ts +137 -114
  512. package/src/runtime/auth/__tests__/guard-tests.test.ts +84 -90
  513. package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +40 -40
  514. package/src/runtime/auth/__tests__/middleware.test.ts +80 -74
  515. package/src/runtime/auth/__tests__/policy.test.ts +9 -9
  516. package/src/runtime/auth/__tests__/route-policy.test.ts +76 -65
  517. package/src/runtime/auth/__tests__/scopes.test.ts +68 -60
  518. package/src/runtime/auth/__tests__/subject.test.ts +54 -54
  519. package/src/runtime/auth/__tests__/token-service.test.ts +115 -108
  520. package/src/runtime/auth/scopes.ts +3 -0
  521. package/src/runtime/auth/token-service.ts +4 -1
  522. package/src/runtime/auth/types.ts +2 -1
  523. package/src/runtime/http-server.ts +2 -1
  524. package/src/security/secure-keys.ts +120 -54
  525. package/src/tools/browser/__tests__/auth-cache.test.ts +69 -63
  526. package/src/tools/browser/__tests__/auth-detector.test.ts +218 -157
  527. package/src/tools/browser/__tests__/jit-auth.test.ts +83 -99
  528. package/src/tools/terminal/safe-env.ts +7 -0
@@ -1,8 +1,14 @@
1
- import { beforeEach,describe, expect, test } from 'bun:test';
2
-
3
- import type { ChannelId } from '../channels/types.js';
4
- import { ChannelReadinessService, REMOTE_TTL_MS } from '../runtime/channel-readiness-service.js';
5
- import type { ChannelProbe, ReadinessCheckResult } from '../runtime/channel-readiness-types.js';
1
+ import { beforeEach, describe, expect, test } from "bun:test";
2
+
3
+ import type { ChannelId } from "../channels/types.js";
4
+ import {
5
+ ChannelReadinessService,
6
+ REMOTE_TTL_MS,
7
+ } from "../runtime/channel-readiness-service.js";
8
+ import type {
9
+ ChannelProbe,
10
+ ReadinessCheckResult,
11
+ } from "../runtime/channel-readiness-types.js";
6
12
 
7
13
  // ── Test helpers ────────────────────────────────────────────────────────────
8
14
 
@@ -33,125 +39,125 @@ function makeProbe(
33
39
 
34
40
  // ── Tests ───────────────────────────────────────────────────────────────────
35
41
 
36
- describe('ChannelReadinessService', () => {
42
+ describe("ChannelReadinessService", () => {
37
43
  let service: ChannelReadinessService;
38
44
 
39
45
  beforeEach(() => {
40
46
  service = new ChannelReadinessService();
41
47
  });
42
48
 
43
- test('local checks run on every call (no caching of local results)', async () => {
44
- const probe = makeProbe('sms', [
45
- { name: 'creds', passed: true, message: 'ok' },
49
+ test("local checks run on every call (no caching of local results)", async () => {
50
+ const probe = makeProbe("sms", [
51
+ { name: "creds", passed: true, message: "ok" },
46
52
  ]);
47
53
  service.registerProbe(probe);
48
54
 
49
- await service.getReadiness('sms');
50
- await service.getReadiness('sms');
55
+ await service.getReadiness("sms");
56
+ await service.getReadiness("sms");
51
57
 
52
58
  expect(probe.localCallCount).toBe(2);
53
59
  });
54
60
 
55
- test('cache miss runs local checks and returns snapshot', async () => {
56
- const probe = makeProbe('sms', [
57
- { name: 'creds', passed: true, message: 'ok' },
58
- { name: 'phone', passed: false, message: 'missing' },
61
+ test("cache miss runs local checks and returns snapshot", async () => {
62
+ const probe = makeProbe("sms", [
63
+ { name: "creds", passed: true, message: "ok" },
64
+ { name: "phone", passed: false, message: "missing" },
59
65
  ]);
60
66
  service.registerProbe(probe);
61
67
 
62
- const [snapshot] = await service.getReadiness('sms');
68
+ const [snapshot] = await service.getReadiness("sms");
63
69
 
64
70
  expect(probe.localCallCount).toBe(1);
65
- expect(snapshot.channel).toBe('sms');
71
+ expect(snapshot.channel).toBe("sms");
66
72
  expect(snapshot.ready).toBe(false);
67
73
  expect(snapshot.localChecks).toHaveLength(2);
68
- expect(snapshot.reasons).toEqual([
69
- { code: 'phone', text: 'missing' },
70
- ]);
74
+ expect(snapshot.reasons).toEqual([{ code: "phone", text: "missing" }]);
71
75
  });
72
76
 
73
- test('includeRemote=true runs remote checks on cache miss', async () => {
77
+ test("includeRemote=true runs remote checks on cache miss", async () => {
74
78
  const probe = makeProbe(
75
- 'sms',
76
- [{ name: 'creds', passed: true, message: 'ok' }],
77
- [{ name: 'api_check', passed: true, message: 'remote ok' }],
79
+ "sms",
80
+ [{ name: "creds", passed: true, message: "ok" }],
81
+ [{ name: "api_check", passed: true, message: "remote ok" }],
78
82
  );
79
83
  service.registerProbe(probe);
80
84
 
81
- const [snapshot] = await service.getReadiness('sms', true);
85
+ const [snapshot] = await service.getReadiness("sms", true);
82
86
 
83
87
  expect(probe.remoteCallCount).toBe(1);
84
88
  expect(snapshot.remoteChecks).toHaveLength(1);
85
89
  expect(snapshot.remoteChecks![0].passed).toBe(true);
86
90
  });
87
91
 
88
- test('cached remote checks reused within TTL', async () => {
92
+ test("cached remote checks reused within TTL", async () => {
89
93
  const probe = makeProbe(
90
- 'sms',
91
- [{ name: 'creds', passed: true, message: 'ok' }],
92
- [{ name: 'api_check', passed: true, message: 'remote ok' }],
94
+ "sms",
95
+ [{ name: "creds", passed: true, message: "ok" }],
96
+ [{ name: "api_check", passed: true, message: "remote ok" }],
93
97
  );
94
98
  service.registerProbe(probe);
95
99
 
96
100
  // First call populates cache
97
- await service.getReadiness('sms', true);
101
+ await service.getReadiness("sms", true);
98
102
  expect(probe.remoteCallCount).toBe(1);
99
103
 
100
104
  // Second call within TTL should reuse cache
101
- const [snapshot] = await service.getReadiness('sms', true);
105
+ const [snapshot] = await service.getReadiness("sms", true);
102
106
  expect(probe.remoteCallCount).toBe(1);
103
107
  expect(snapshot.remoteChecks).toHaveLength(1);
104
108
  });
105
109
 
106
- test('stale cache triggers remote check re-run', async () => {
110
+ test("stale cache triggers remote check re-run", async () => {
107
111
  const probe = makeProbe(
108
- 'sms',
109
- [{ name: 'creds', passed: true, message: 'ok' }],
110
- [{ name: 'api_check', passed: true, message: 'remote ok' }],
112
+ "sms",
113
+ [{ name: "creds", passed: true, message: "ok" }],
114
+ [{ name: "api_check", passed: true, message: "remote ok" }],
111
115
  );
112
116
  service.registerProbe(probe);
113
117
 
114
118
  // First call
115
- await service.getReadiness('sms', true);
119
+ await service.getReadiness("sms", true);
116
120
  expect(probe.remoteCallCount).toBe(1);
117
121
 
118
122
  // Manually age the cached snapshot beyond TTL
119
- const cached = (service as unknown as { snapshots: Map<string, { checkedAt: number }> }).snapshots.get('sms::__default__')!;
123
+ const cached = (
124
+ service as unknown as { snapshots: Map<string, { checkedAt: number }> }
125
+ ).snapshots.get("sms::__default__")!;
120
126
  cached.checkedAt = Date.now() - REMOTE_TTL_MS - 1;
121
127
 
122
128
  // Second call should re-run remote checks
123
- await service.getReadiness('sms', true);
129
+ await service.getReadiness("sms", true);
124
130
  expect(probe.remoteCallCount).toBe(2);
125
131
  });
126
132
 
127
- test('invalidateChannel clears cache for specific channel', async () => {
133
+ test("invalidateChannel clears cache for specific channel", async () => {
128
134
  const probe = makeProbe(
129
- 'sms',
130
- [{ name: 'creds', passed: true, message: 'ok' }],
131
- [{ name: 'api_check', passed: true, message: 'remote ok' }],
135
+ "sms",
136
+ [{ name: "creds", passed: true, message: "ok" }],
137
+ [{ name: "api_check", passed: true, message: "remote ok" }],
132
138
  );
133
139
  service.registerProbe(probe);
134
140
 
135
- await service.getReadiness('sms', true);
141
+ await service.getReadiness("sms", true);
136
142
  expect(probe.remoteCallCount).toBe(1);
137
143
 
138
- service.invalidateChannel('sms');
144
+ service.invalidateChannel("sms");
139
145
 
140
146
  // After invalidation, remote checks should run again
141
- await service.getReadiness('sms', true);
147
+ await service.getReadiness("sms", true);
142
148
  expect(probe.remoteCallCount).toBe(2);
143
149
  });
144
150
 
145
- test('invalidateAll clears all cached snapshots', async () => {
151
+ test("invalidateAll clears all cached snapshots", async () => {
146
152
  const smsProbe = makeProbe(
147
- 'sms',
148
- [{ name: 'creds', passed: true, message: 'ok' }],
149
- [{ name: 'api', passed: true, message: 'ok' }],
153
+ "sms",
154
+ [{ name: "creds", passed: true, message: "ok" }],
155
+ [{ name: "api", passed: true, message: "ok" }],
150
156
  );
151
157
  const telegramProbe = makeProbe(
152
- 'telegram',
153
- [{ name: 'token', passed: true, message: 'ok' }],
154
- [{ name: 'webhook', passed: true, message: 'ok' }],
158
+ "telegram",
159
+ [{ name: "token", passed: true, message: "ok" }],
160
+ [{ name: "webhook", passed: true, message: "ok" }],
155
161
  );
156
162
  service.registerProbe(smsProbe);
157
163
  service.registerProbe(telegramProbe);
@@ -167,112 +173,121 @@ describe('ChannelReadinessService', () => {
167
173
  expect(telegramProbe.remoteCallCount).toBe(2);
168
174
  });
169
175
 
170
- test('unknown channel returns unsupported_channel reason', async () => {
176
+ test("unknown channel returns unsupported_channel reason", async () => {
171
177
  // Cast to exercise runtime handling of an unrecognized channel value
172
- const [snapshot] = await service.getReadiness('carrier_pigeon' as ChannelId);
178
+ const [snapshot] = await service.getReadiness(
179
+ "carrier_pigeon" as ChannelId,
180
+ );
173
181
 
174
- expect(snapshot.channel).toBe('carrier_pigeon' as ChannelId);
182
+ expect(snapshot.channel).toBe("carrier_pigeon" as ChannelId);
175
183
  expect(snapshot.ready).toBe(false);
176
184
  expect(snapshot.reasons).toEqual([
177
- { code: 'unsupported_channel', text: 'Channel carrier_pigeon is not supported' },
185
+ {
186
+ code: "unsupported_channel",
187
+ text: "Channel carrier_pigeon is not supported",
188
+ },
178
189
  ]);
179
190
  expect(snapshot.localChecks).toHaveLength(0);
180
191
  });
181
192
 
182
- test('all checks passing yields ready=true', async () => {
183
- const probe = makeProbe('telegram', [
184
- { name: 'a', passed: true, message: 'ok' },
185
- { name: 'b', passed: true, message: 'ok' },
193
+ test("all checks passing yields ready=true", async () => {
194
+ const probe = makeProbe("telegram", [
195
+ { name: "a", passed: true, message: "ok" },
196
+ { name: "b", passed: true, message: "ok" },
186
197
  ]);
187
198
  service.registerProbe(probe);
188
199
 
189
- const [snapshot] = await service.getReadiness('telegram');
200
+ const [snapshot] = await service.getReadiness("telegram");
190
201
 
191
202
  expect(snapshot.ready).toBe(true);
192
203
  expect(snapshot.reasons).toHaveLength(0);
193
204
  });
194
205
 
195
- test('getReadiness with no channel returns all registered channels', async () => {
196
- service.registerProbe(makeProbe('sms', [{ name: 'a', passed: true, message: 'ok' }]));
197
- service.registerProbe(makeProbe('telegram', [{ name: 'b', passed: true, message: 'ok' }]));
206
+ test("getReadiness with no channel returns all registered channels", async () => {
207
+ service.registerProbe(
208
+ makeProbe("sms", [{ name: "a", passed: true, message: "ok" }]),
209
+ );
210
+ service.registerProbe(
211
+ makeProbe("telegram", [{ name: "b", passed: true, message: "ok" }]),
212
+ );
198
213
 
199
214
  const snapshots = await service.getReadiness();
200
215
 
201
216
  expect(snapshots).toHaveLength(2);
202
217
  const channels = snapshots.map((s) => s.channel).sort();
203
- expect(channels).toEqual(['sms', 'telegram']);
218
+ expect(channels).toEqual(["sms", "telegram"]);
204
219
  });
205
220
 
206
- test('cached remote checks preserve original checkedAt (TTL not reset on reuse)', async () => {
221
+ test("cached remote checks preserve original checkedAt (TTL not reset on reuse)", async () => {
207
222
  const probe = makeProbe(
208
- 'sms',
209
- [{ name: 'creds', passed: true, message: 'ok' }],
210
- [{ name: 'api_check', passed: true, message: 'remote ok' }],
223
+ "sms",
224
+ [{ name: "creds", passed: true, message: "ok" }],
225
+ [{ name: "api_check", passed: true, message: "remote ok" }],
211
226
  );
212
227
  service.registerProbe(probe);
213
228
 
214
229
  // First call populates cache with freshly fetched remote checks
215
- const [first] = await service.getReadiness('sms', true);
230
+ const [first] = await service.getReadiness("sms", true);
216
231
  const originalCheckedAt = first.checkedAt;
217
232
  expect(probe.remoteCallCount).toBe(1);
218
233
 
219
234
  // Second call within TTL reuses cache — checkedAt must stay at the original value
220
- const [second] = await service.getReadiness('sms', true);
235
+ const [second] = await service.getReadiness("sms", true);
221
236
  expect(probe.remoteCallCount).toBe(1);
222
237
  expect(second.checkedAt).toBe(originalCheckedAt);
223
238
  });
224
239
 
225
- test('includeRemote runs remote checks when cache exists without remote data', async () => {
240
+ test("includeRemote runs remote checks when cache exists without remote data", async () => {
226
241
  const probe = makeProbe(
227
- 'sms',
228
- [{ name: 'creds', passed: true, message: 'ok' }],
229
- [{ name: 'api_check', passed: true, message: 'remote ok' }],
242
+ "sms",
243
+ [{ name: "creds", passed: true, message: "ok" }],
244
+ [{ name: "api_check", passed: true, message: "remote ok" }],
230
245
  );
231
246
  service.registerProbe(probe);
232
247
 
233
248
  // First call without includeRemote — cache has no remote data
234
- await service.getReadiness('sms', false);
249
+ await service.getReadiness("sms", false);
235
250
  expect(probe.remoteCallCount).toBe(0);
236
251
 
237
252
  // Second call with includeRemote — should run remote checks even though
238
253
  // the cached snapshot exists (because it has no remoteChecks)
239
- const [snapshot] = await service.getReadiness('sms', true);
254
+ const [snapshot] = await service.getReadiness("sms", true);
240
255
  expect(probe.remoteCallCount).toBe(1);
241
256
  expect(snapshot.remoteChecks).toHaveLength(1);
242
257
  expect(snapshot.remoteChecks![0].passed).toBe(true);
243
258
  });
244
259
 
245
- test('failed remote check makes channel not ready', async () => {
260
+ test("failed remote check makes channel not ready", async () => {
246
261
  const probe = makeProbe(
247
- 'sms',
248
- [{ name: 'creds', passed: true, message: 'ok' }],
249
- [{ name: 'api_check', passed: false, message: 'API unreachable' }],
262
+ "sms",
263
+ [{ name: "creds", passed: true, message: "ok" }],
264
+ [{ name: "api_check", passed: false, message: "API unreachable" }],
250
265
  );
251
266
  service.registerProbe(probe);
252
267
 
253
- const [snapshot] = await service.getReadiness('sms', true);
268
+ const [snapshot] = await service.getReadiness("sms", true);
254
269
 
255
270
  expect(snapshot.ready).toBe(false);
256
271
  expect(snapshot.reasons).toEqual([
257
- { code: 'api_check', text: 'API unreachable' },
272
+ { code: "api_check", text: "API unreachable" },
258
273
  ]);
259
274
  });
260
275
 
261
- test('fresh cached remote failures do not affect local-only readiness', async () => {
276
+ test("fresh cached remote failures do not affect local-only readiness", async () => {
262
277
  const probe = makeProbe(
263
- 'sms',
264
- [{ name: 'creds', passed: true, message: 'ok' }],
265
- [{ name: 'api_check', passed: false, message: 'API unreachable' }],
278
+ "sms",
279
+ [{ name: "creds", passed: true, message: "ok" }],
280
+ [{ name: "api_check", passed: false, message: "API unreachable" }],
266
281
  );
267
282
  service.registerProbe(probe);
268
283
 
269
284
  // Prime remote cache with a failing check
270
- await service.getReadiness('sms', true);
285
+ await service.getReadiness("sms", true);
271
286
 
272
287
  // Immediately call with includeRemote=false (cache is still fresh within TTL).
273
288
  // The cached remote failure should be surfaced for visibility but must NOT
274
289
  // affect readiness when the caller explicitly opted out of remote checks.
275
- const [snapshot] = await service.getReadiness('sms', false);
290
+ const [snapshot] = await service.getReadiness("sms", false);
276
291
  expect(snapshot.ready).toBe(true);
277
292
  expect(snapshot.reasons).toEqual([]);
278
293
  // Remote checks are still visible for informational purposes
@@ -280,39 +295,41 @@ describe('ChannelReadinessService', () => {
280
295
  expect(snapshot.remoteChecks![0].passed).toBe(false);
281
296
  });
282
297
 
283
- test('stale cached remote failures do not affect local-only readiness', async () => {
298
+ test("stale cached remote failures do not affect local-only readiness", async () => {
284
299
  const probe = makeProbe(
285
- 'sms',
286
- [{ name: 'creds', passed: true, message: 'ok' }],
287
- [{ name: 'api_check', passed: false, message: 'API unreachable' }],
300
+ "sms",
301
+ [{ name: "creds", passed: true, message: "ok" }],
302
+ [{ name: "api_check", passed: false, message: "API unreachable" }],
288
303
  );
289
304
  service.registerProbe(probe);
290
305
 
291
306
  // Prime remote cache with a failing check
292
- await service.getReadiness('sms', true);
307
+ await service.getReadiness("sms", true);
293
308
 
294
309
  // Age snapshot beyond TTL so remote checks are stale
295
- const cached = (service as unknown as { snapshots: Map<string, { checkedAt: number }> }).snapshots.get('sms::__default__')!;
310
+ const cached = (
311
+ service as unknown as { snapshots: Map<string, { checkedAt: number }> }
312
+ ).snapshots.get("sms::__default__")!;
296
313
  cached.checkedAt = Date.now() - REMOTE_TTL_MS - 1;
297
314
 
298
315
  // Local-only call should not be blocked by stale remote failure
299
- const [snapshot] = await service.getReadiness('sms', false);
316
+ const [snapshot] = await service.getReadiness("sms", false);
300
317
  expect(snapshot.stale).toBe(true);
301
318
  expect(snapshot.ready).toBe(true);
302
319
  expect(snapshot.reasons).toEqual([]);
303
320
  });
304
321
 
305
- test('remote cache uses fixed internal scope (no per-assistantId scoping)', async () => {
322
+ test("remote cache uses fixed internal scope (no per-assistantId scoping)", async () => {
306
323
  const probe = makeProbe(
307
- 'sms',
308
- [{ name: 'local', passed: true, message: 'ok' }],
309
- [{ name: 'remote', passed: true, message: 'ok' }],
324
+ "sms",
325
+ [{ name: "local", passed: true, message: "ok" }],
326
+ [{ name: "remote", passed: true, message: "ok" }],
310
327
  );
311
328
  service.registerProbe(probe);
312
329
 
313
330
  // All calls share the same cache key since there is no assistantId dimension
314
- await service.getReadiness('sms', true);
315
- await service.getReadiness('sms', true);
331
+ await service.getReadiness("sms", true);
332
+ await service.getReadiness("sms", true);
316
333
 
317
334
  expect(probe.remoteCallCount).toBe(1);
318
335
  });