@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,113 +1,113 @@
1
- import { describe, expect,test } from 'bun:test';
1
+ import { describe, expect, test } from "bun:test";
2
2
 
3
- import { normalizeDomain } from '../tools/network/domain-normalize.js';
3
+ import { normalizeDomain } from "../tools/network/domain-normalize.js";
4
4
 
5
- describe('normalizeDomain', () => {
5
+ describe("normalizeDomain", () => {
6
6
  // ── Basic hostname parsing ──────────────────────────────────────────
7
7
 
8
- test('parses simple hostname', () => {
9
- const result = normalizeDomain('example.com');
8
+ test("parses simple hostname", () => {
9
+ const result = normalizeDomain("example.com");
10
10
  expect(result).not.toBeNull();
11
- expect(result!.hostname).toBe('example.com');
12
- expect(result!.registrableDomain).toBe('example.com');
11
+ expect(result!.hostname).toBe("example.com");
12
+ expect(result!.registrableDomain).toBe("example.com");
13
13
  });
14
14
 
15
- test('parses subdomain', () => {
16
- const result = normalizeDomain('login.example.com');
15
+ test("parses subdomain", () => {
16
+ const result = normalizeDomain("login.example.com");
17
17
  expect(result).not.toBeNull();
18
- expect(result!.hostname).toBe('login.example.com');
19
- expect(result!.registrableDomain).toBe('example.com');
18
+ expect(result!.hostname).toBe("login.example.com");
19
+ expect(result!.registrableDomain).toBe("example.com");
20
20
  });
21
21
 
22
- test('parses deep subdomain', () => {
23
- const result = normalizeDomain('foo.bar.example.co.uk');
22
+ test("parses deep subdomain", () => {
23
+ const result = normalizeDomain("foo.bar.example.co.uk");
24
24
  expect(result).not.toBeNull();
25
- expect(result!.hostname).toBe('foo.bar.example.co.uk');
26
- expect(result!.registrableDomain).toBe('example.co.uk');
25
+ expect(result!.hostname).toBe("foo.bar.example.co.uk");
26
+ expect(result!.registrableDomain).toBe("example.co.uk");
27
27
  });
28
28
 
29
29
  // ── URL extraction ──────────────────────────────────────────────────
30
30
 
31
- test('extracts hostname from full URL', () => {
32
- const result = normalizeDomain('https://login.example.com/path?q=1');
31
+ test("extracts hostname from full URL", () => {
32
+ const result = normalizeDomain("https://login.example.com/path?q=1");
33
33
  expect(result).not.toBeNull();
34
- expect(result!.hostname).toBe('login.example.com');
35
- expect(result!.registrableDomain).toBe('example.com');
34
+ expect(result!.hostname).toBe("login.example.com");
35
+ expect(result!.registrableDomain).toBe("example.com");
36
36
  });
37
37
 
38
- test('extracts hostname from URL with port', () => {
39
- const result = normalizeDomain('https://example.com:8443/api');
38
+ test("extracts hostname from URL with port", () => {
39
+ const result = normalizeDomain("https://example.com:8443/api");
40
40
  expect(result).not.toBeNull();
41
- expect(result!.hostname).toBe('example.com');
41
+ expect(result!.hostname).toBe("example.com");
42
42
  });
43
43
 
44
- test('strips port from bare hostname', () => {
45
- const result = normalizeDomain('example.com:8080');
44
+ test("strips port from bare hostname", () => {
45
+ const result = normalizeDomain("example.com:8080");
46
46
  expect(result).not.toBeNull();
47
- expect(result!.hostname).toBe('example.com');
48
- expect(result!.registrableDomain).toBe('example.com');
47
+ expect(result!.hostname).toBe("example.com");
48
+ expect(result!.registrableDomain).toBe("example.com");
49
49
  });
50
50
 
51
51
  // ── Normalization ───────────────────────────────────────────────────
52
52
 
53
- test('lowercases hostname', () => {
54
- const result = normalizeDomain('Login.EXAMPLE.Com');
53
+ test("lowercases hostname", () => {
54
+ const result = normalizeDomain("Login.EXAMPLE.Com");
55
55
  expect(result).not.toBeNull();
56
- expect(result!.hostname).toBe('login.example.com');
57
- expect(result!.registrableDomain).toBe('example.com');
56
+ expect(result!.hostname).toBe("login.example.com");
57
+ expect(result!.registrableDomain).toBe("example.com");
58
58
  });
59
59
 
60
- test('strips trailing dot', () => {
61
- const result = normalizeDomain('example.com.');
60
+ test("strips trailing dot", () => {
61
+ const result = normalizeDomain("example.com.");
62
62
  expect(result).not.toBeNull();
63
- expect(result!.hostname).toBe('example.com');
64
- expect(result!.registrableDomain).toBe('example.com');
63
+ expect(result!.hostname).toBe("example.com");
64
+ expect(result!.registrableDomain).toBe("example.com");
65
65
  });
66
66
 
67
67
  // ── Punycode / IDN ──────────────────────────────────────────────────
68
68
 
69
- test('handles punycode domain', () => {
70
- const result = normalizeDomain('xn--nxasmq6b.example.com');
69
+ test("handles punycode domain", () => {
70
+ const result = normalizeDomain("xn--nxasmq6b.example.com");
71
71
  expect(result).not.toBeNull();
72
- expect(result!.hostname).toBe('xn--nxasmq6b.example.com');
73
- expect(result!.registrableDomain).toBe('example.com');
72
+ expect(result!.hostname).toBe("xn--nxasmq6b.example.com");
73
+ expect(result!.registrableDomain).toBe("example.com");
74
74
  });
75
75
 
76
76
  // ── Rejection cases ─────────────────────────────────────────────────
77
77
 
78
- test('returns null for IPv4 address', () => {
79
- expect(normalizeDomain('192.168.1.1')).toBeNull();
78
+ test("returns null for IPv4 address", () => {
79
+ expect(normalizeDomain("192.168.1.1")).toBeNull();
80
80
  });
81
81
 
82
- test('returns null for IPv6 address', () => {
83
- expect(normalizeDomain('[::1]')).toBeNull();
84
- expect(normalizeDomain('::1')).toBeNull();
82
+ test("returns null for IPv6 address", () => {
83
+ expect(normalizeDomain("[::1]")).toBeNull();
84
+ expect(normalizeDomain("::1")).toBeNull();
85
85
  });
86
86
 
87
- test('returns null for localhost', () => {
88
- expect(normalizeDomain('localhost')).toBeNull();
87
+ test("returns null for localhost", () => {
88
+ expect(normalizeDomain("localhost")).toBeNull();
89
89
  });
90
90
 
91
- test('returns null for empty string', () => {
92
- expect(normalizeDomain('')).toBeNull();
91
+ test("returns null for empty string", () => {
92
+ expect(normalizeDomain("")).toBeNull();
93
93
  });
94
94
 
95
- test('returns null for null-like input', () => {
95
+ test("returns null for null-like input", () => {
96
96
  expect(normalizeDomain(null as unknown as string)).toBeNull();
97
97
  expect(normalizeDomain(undefined as unknown as string)).toBeNull();
98
98
  });
99
99
 
100
100
  // ── Co.uk / multi-part TLD ──────────────────────────────────────────
101
101
 
102
- test('handles co.uk correctly', () => {
103
- const result = normalizeDomain('www.bbc.co.uk');
102
+ test("handles co.uk correctly", () => {
103
+ const result = normalizeDomain("www.bbc.co.uk");
104
104
  expect(result).not.toBeNull();
105
- expect(result!.registrableDomain).toBe('bbc.co.uk');
105
+ expect(result!.registrableDomain).toBe("bbc.co.uk");
106
106
  });
107
107
 
108
- test('handles com.au correctly', () => {
109
- const result = normalizeDomain('shop.example.com.au');
108
+ test("handles com.au correctly", () => {
109
+ const result = normalizeDomain("shop.example.com.au");
110
110
  expect(result).not.toBeNull();
111
- expect(result!.registrableDomain).toBe('example.com.au');
111
+ expect(result!.registrableDomain).toBe("example.com.au");
112
112
  });
113
113
  });
@@ -1,125 +1,141 @@
1
- import { describe, expect,test } from 'bun:test';
1
+ import { describe, expect, test } from "bun:test";
2
2
 
3
- import { isDomainAllowed } from '../tools/credentials/domain-policy.js';
3
+ import { isDomainAllowed } from "../tools/credentials/domain-policy.js";
4
4
 
5
- describe('isDomainAllowed', () => {
5
+ describe("isDomainAllowed", () => {
6
6
  // ── Exact host match ────────────────────────────────────────────────
7
7
 
8
- test('allows exact hostname match', () => {
9
- expect(isDomainAllowed('example.com', ['example.com'])).toBe(true);
8
+ test("allows exact hostname match", () => {
9
+ expect(isDomainAllowed("example.com", ["example.com"])).toBe(true);
10
10
  });
11
11
 
12
- test('allows exact hostname match (case insensitive)', () => {
13
- expect(isDomainAllowed('Example.COM', ['example.com'])).toBe(true);
12
+ test("allows exact hostname match (case insensitive)", () => {
13
+ expect(isDomainAllowed("Example.COM", ["example.com"])).toBe(true);
14
14
  });
15
15
 
16
16
  // ── Registrable-domain + subdomain ──────────────────────────────────
17
17
 
18
- test('allows subdomain when registrable domain matches', () => {
19
- expect(isDomainAllowed('login.example.com', ['example.com'])).toBe(true);
18
+ test("allows subdomain when registrable domain matches", () => {
19
+ expect(isDomainAllowed("login.example.com", ["example.com"])).toBe(true);
20
20
  });
21
21
 
22
- test('allows deep subdomain when registrable domain matches', () => {
23
- expect(isDomainAllowed('a.b.c.example.com', ['example.com'])).toBe(true);
22
+ test("allows deep subdomain when registrable domain matches", () => {
23
+ expect(isDomainAllowed("a.b.c.example.com", ["example.com"])).toBe(true);
24
24
  });
25
25
 
26
- test('allows subdomain of co.uk domain', () => {
27
- expect(isDomainAllowed('login.bbc.co.uk', ['bbc.co.uk'])).toBe(true);
26
+ test("allows subdomain of co.uk domain", () => {
27
+ expect(isDomainAllowed("login.bbc.co.uk", ["bbc.co.uk"])).toBe(true);
28
28
  });
29
29
 
30
30
  // ── Deny cases ──────────────────────────────────────────────────────
31
31
 
32
- test('denies unrelated domain', () => {
33
- expect(isDomainAllowed('evil.com', ['example.com'])).toBe(false);
32
+ test("denies unrelated domain", () => {
33
+ expect(isDomainAllowed("evil.com", ["example.com"])).toBe(false);
34
34
  });
35
35
 
36
- test('denies domain that looks similar but differs', () => {
37
- expect(isDomainAllowed('notexample.com', ['example.com'])).toBe(false);
36
+ test("denies domain that looks similar but differs", () => {
37
+ expect(isDomainAllowed("notexample.com", ["example.com"])).toBe(false);
38
38
  });
39
39
 
40
- test('denies different TLD', () => {
41
- expect(isDomainAllowed('example.org', ['example.com'])).toBe(false);
40
+ test("denies different TLD", () => {
41
+ expect(isDomainAllowed("example.org", ["example.com"])).toBe(false);
42
42
  });
43
43
 
44
- test('denies when allowed list is empty', () => {
45
- expect(isDomainAllowed('example.com', [])).toBe(false);
44
+ test("denies when allowed list is empty", () => {
45
+ expect(isDomainAllowed("example.com", [])).toBe(false);
46
46
  });
47
47
 
48
- test('denies when allowed list is undefined-like', () => {
49
- expect(isDomainAllowed('example.com', undefined as unknown as string[])).toBe(false);
48
+ test("denies when allowed list is undefined-like", () => {
49
+ expect(
50
+ isDomainAllowed("example.com", undefined as unknown as string[]),
51
+ ).toBe(false);
50
52
  });
51
53
 
52
- test('denies when request host is empty', () => {
53
- expect(isDomainAllowed('', ['example.com'])).toBe(false);
54
+ test("denies when request host is empty", () => {
55
+ expect(isDomainAllowed("", ["example.com"])).toBe(false);
54
56
  });
55
57
 
56
- test('denies when request host is invalid', () => {
57
- expect(isDomainAllowed('not a valid host!!!', ['example.com'])).toBe(false);
58
+ test("denies when request host is invalid", () => {
59
+ expect(isDomainAllowed("not a valid host!!!", ["example.com"])).toBe(false);
58
60
  });
59
61
 
60
- test('denies malformed host even when same string is in allowed list', () => {
61
- expect(isDomainAllowed('not a valid host!!!', ['not a valid host!!!'])).toBe(false);
62
+ test("denies malformed host even when same string is in allowed list", () => {
63
+ expect(
64
+ isDomainAllowed("not a valid host!!!", ["not a valid host!!!"]),
65
+ ).toBe(false);
62
66
  });
63
67
 
64
- test('denies hostname with consecutive dots', () => {
65
- expect(isDomainAllowed('a..b', ['a..b'])).toBe(false);
68
+ test("denies hostname with consecutive dots", () => {
69
+ expect(isDomainAllowed("a..b", ["a..b"])).toBe(false);
66
70
  });
67
71
 
68
- test('denies hostname with label starting with hyphen', () => {
69
- expect(isDomainAllowed('-foo.example.com', ['example.com'])).toBe(false);
72
+ test("denies hostname with label starting with hyphen", () => {
73
+ expect(isDomainAllowed("-foo.example.com", ["example.com"])).toBe(false);
70
74
  });
71
75
 
72
- test('denies hostname with label ending with hyphen', () => {
73
- expect(isDomainAllowed('foo-.example.com', ['example.com'])).toBe(false);
76
+ test("denies hostname with label ending with hyphen", () => {
77
+ expect(isDomainAllowed("foo-.example.com", ["example.com"])).toBe(false);
74
78
  });
75
79
 
76
- test('denies IP addresses', () => {
77
- expect(isDomainAllowed('192.168.1.1', ['192.168.1.1'])).toBe(false);
80
+ test("denies IP addresses", () => {
81
+ expect(isDomainAllowed("192.168.1.1", ["192.168.1.1"])).toBe(false);
78
82
  });
79
83
 
80
- test('denies localhost', () => {
81
- expect(isDomainAllowed('localhost', ['localhost'])).toBe(false);
84
+ test("denies localhost", () => {
85
+ expect(isDomainAllowed("localhost", ["localhost"])).toBe(false);
82
86
  });
83
87
 
84
88
  // ── Internal / non-registrable hosts ────────────────────────────────
85
89
 
86
- test('allows exact match for single-label intranet host', () => {
87
- expect(isDomainAllowed('intranet', ['intranet'])).toBe(true);
90
+ test("allows exact match for single-label intranet host", () => {
91
+ expect(isDomainAllowed("intranet", ["intranet"])).toBe(true);
88
92
  });
89
93
 
90
- test('allows exact match for internal two-label host', () => {
91
- expect(isDomainAllowed('vault.corp', ['vault.corp'])).toBe(true);
94
+ test("allows exact match for internal two-label host", () => {
95
+ expect(isDomainAllowed("vault.corp", ["vault.corp"])).toBe(true);
92
96
  });
93
97
 
94
98
  // ── URL extraction ──────────────────────────────────────────────────
95
99
 
96
- test('extracts hostname from full URL', () => {
97
- expect(isDomainAllowed('https://login.example.com/path', ['example.com'])).toBe(true);
100
+ test("extracts hostname from full URL", () => {
101
+ expect(
102
+ isDomainAllowed("https://login.example.com/path", ["example.com"]),
103
+ ).toBe(true);
98
104
  });
99
105
 
100
- test('denies URL with wrong domain', () => {
101
- expect(isDomainAllowed('https://evil.com/path', ['example.com'])).toBe(false);
106
+ test("denies URL with wrong domain", () => {
107
+ expect(isDomainAllowed("https://evil.com/path", ["example.com"])).toBe(
108
+ false,
109
+ );
102
110
  });
103
111
 
104
112
  // ── Subdomain in allowed list ──────────────────────────────────────
105
113
 
106
- test('allows exact subdomain match when subdomain is in allowed list', () => {
107
- expect(isDomainAllowed('login.example.com', ['login.example.com'])).toBe(true);
114
+ test("allows exact subdomain match when subdomain is in allowed list", () => {
115
+ expect(isDomainAllowed("login.example.com", ["login.example.com"])).toBe(
116
+ true,
117
+ );
108
118
  });
109
119
 
110
- test('denies different subdomain when only specific subdomain is allowed', () => {
120
+ test("denies different subdomain when only specific subdomain is allowed", () => {
111
121
  // When allowed is a subdomain (not the registrable domain itself),
112
122
  // only exact matches should work
113
- expect(isDomainAllowed('other.example.com', ['login.example.com'])).toBe(false);
123
+ expect(isDomainAllowed("other.example.com", ["login.example.com"])).toBe(
124
+ false,
125
+ );
114
126
  });
115
127
 
116
128
  // ── Multiple allowed domains ────────────────────────────────────────
117
129
 
118
- test('matches against any domain in the allowed list', () => {
119
- expect(isDomainAllowed('login.github.com', ['example.com', 'github.com'])).toBe(true);
130
+ test("matches against any domain in the allowed list", () => {
131
+ expect(
132
+ isDomainAllowed("login.github.com", ["example.com", "github.com"]),
133
+ ).toBe(true);
120
134
  });
121
135
 
122
- test('denies when none of the allowed domains match', () => {
123
- expect(isDomainAllowed('evil.com', ['example.com', 'github.com'])).toBe(false);
136
+ test("denies when none of the allowed domains match", () => {
137
+ expect(isDomainAllowed("evil.com", ["example.com", "github.com"])).toBe(
138
+ false,
139
+ );
124
140
  });
125
141
  });
@@ -1,37 +1,35 @@
1
- import { describe, expect,test } from 'bun:test';
1
+ import { describe, expect, test } from "bun:test";
2
2
 
3
3
  import type {
4
4
  DynamicPageSurfaceData,
5
5
  UiSurfaceShowDynamicPage,
6
- } from '../daemon/ipc-protocol.js';
7
- import {
8
- INTERACTIVE_SURFACE_TYPES,
9
- } from '../daemon/ipc-protocol.js';
10
- import { uiShowTool } from '../tools/ui-surface/definitions.js';
6
+ } from "../daemon/ipc-protocol.js";
7
+ import { INTERACTIVE_SURFACE_TYPES } from "../daemon/ipc-protocol.js";
8
+ import { uiShowTool } from "../tools/ui-surface/definitions.js";
11
9
 
12
10
  // ---------------------------------------------------------------------------
13
11
  // DynamicPageSurfaceData shape
14
12
  // ---------------------------------------------------------------------------
15
13
 
16
- describe('DynamicPageSurfaceData shape', () => {
17
- test('accepts an object with html, width, and height', () => {
14
+ describe("DynamicPageSurfaceData shape", () => {
15
+ test("accepts an object with html, width, and height", () => {
18
16
  const data: DynamicPageSurfaceData = {
19
- html: '<h1>Hi</h1>',
17
+ html: "<h1>Hi</h1>",
20
18
  width: 400,
21
19
  height: 300,
22
20
  };
23
21
 
24
- expect(data.html).toBe('<h1>Hi</h1>');
22
+ expect(data.html).toBe("<h1>Hi</h1>");
25
23
  expect(data.width).toBe(400);
26
24
  expect(data.height).toBe(300);
27
25
  });
28
26
 
29
- test('width and height are optional', () => {
27
+ test("width and height are optional", () => {
30
28
  const data: DynamicPageSurfaceData = {
31
- html: '<p>Hello</p>',
29
+ html: "<p>Hello</p>",
32
30
  };
33
31
 
34
- expect(data.html).toBe('<p>Hello</p>');
32
+ expect(data.html).toBe("<p>Hello</p>");
35
33
  expect(data.width).toBeUndefined();
36
34
  expect(data.height).toBeUndefined();
37
35
  });
@@ -41,8 +39,8 @@ describe('DynamicPageSurfaceData shape', () => {
41
39
  // Tool definition includes dynamic_page
42
40
  // ---------------------------------------------------------------------------
43
41
 
44
- describe('Tool definition includes dynamic_page', () => {
45
- test('input_schema surface_type enum includes dynamic_page', () => {
42
+ describe("Tool definition includes dynamic_page", () => {
43
+ test("input_schema surface_type enum includes dynamic_page", () => {
46
44
  const definition = uiShowTool.getDefinition();
47
45
  const surfaceTypeEnum = (
48
46
  definition.input_schema as {
@@ -50,12 +48,12 @@ describe('Tool definition includes dynamic_page', () => {
50
48
  }
51
49
  ).properties.surface_type.enum;
52
50
 
53
- expect(surfaceTypeEnum).toContain('dynamic_page');
51
+ expect(surfaceTypeEnum).toContain("dynamic_page");
54
52
  });
55
53
 
56
- test('description mentions dynamic_page', () => {
54
+ test("description mentions dynamic_page", () => {
57
55
  const definition = uiShowTool.getDefinition();
58
- expect(definition.description).toContain('dynamic_page');
56
+ expect(definition.description).toContain("dynamic_page");
59
57
  });
60
58
  });
61
59
 
@@ -63,21 +61,21 @@ describe('Tool definition includes dynamic_page', () => {
63
61
  // UiSurfaceShowDynamicPage structure
64
62
  // ---------------------------------------------------------------------------
65
63
 
66
- describe('UiSurfaceShowDynamicPage structure', () => {
67
- test('can construct a well-typed UiSurfaceShowDynamicPage object', () => {
64
+ describe("UiSurfaceShowDynamicPage structure", () => {
65
+ test("can construct a well-typed UiSurfaceShowDynamicPage object", () => {
68
66
  const msg: UiSurfaceShowDynamicPage = {
69
- type: 'ui_surface_show',
70
- sessionId: 'session-abc',
71
- surfaceId: 'surface-123',
72
- surfaceType: 'dynamic_page',
73
- data: { html: '<div>Content</div>' },
67
+ type: "ui_surface_show",
68
+ sessionId: "session-abc",
69
+ surfaceId: "surface-123",
70
+ surfaceType: "dynamic_page",
71
+ data: { html: "<div>Content</div>" },
74
72
  };
75
73
 
76
- expect(msg.type).toBe('ui_surface_show');
77
- expect(msg.surfaceType).toBe('dynamic_page');
78
- expect(typeof msg.data.html).toBe('string');
79
- expect(msg.sessionId).toBe('session-abc');
80
- expect(msg.surfaceId).toBe('surface-123');
74
+ expect(msg.type).toBe("ui_surface_show");
75
+ expect(msg.surfaceType).toBe("dynamic_page");
76
+ expect(typeof msg.data.html).toBe("string");
77
+ expect(msg.sessionId).toBe("session-abc");
78
+ expect(msg.surfaceId).toBe("surface-123");
81
79
  });
82
80
  });
83
81
 
@@ -85,8 +83,8 @@ describe('UiSurfaceShowDynamicPage structure', () => {
85
83
  // Interactivity
86
84
  // ---------------------------------------------------------------------------
87
85
 
88
- describe('dynamic_page interactivity', () => {
89
- test('dynamic_page is in the interactive surface types list', () => {
90
- expect(INTERACTIVE_SURFACE_TYPES).toContain('dynamic_page');
86
+ describe("dynamic_page interactivity", () => {
87
+ test("dynamic_page is in the interactive surface types list", () => {
88
+ expect(INTERACTIVE_SURFACE_TYPES).toContain("dynamic_page");
91
89
  });
92
90
  });