@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,35 +1,37 @@
1
- import { existsSync,mkdirSync, rmSync, writeFileSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
3
- import { join } from 'node:path';
1
+ import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
4
5
 
5
- import { afterEach,beforeEach, describe, expect, test } from 'bun:test';
6
+ const TEST_DIR = join(
7
+ tmpdir(),
8
+ `vellum-starter-tasks-test-${crypto.randomUUID()}`,
9
+ );
6
10
 
7
- const TEST_DIR = join(tmpdir(), `vellum-starter-tasks-test-${crypto.randomUUID()}`);
11
+ import { mock } from "bun:test";
8
12
 
9
- import { mock } from 'bun:test';
10
-
11
- mock.module('../util/platform.js', () => ({
13
+ mock.module("../util/platform.js", () => ({
12
14
  getRootDir: () => TEST_DIR,
13
15
  getDataDir: () => TEST_DIR,
14
16
  getWorkspaceDir: () => TEST_DIR,
15
- getWorkspaceConfigPath: () => join(TEST_DIR, 'config.json'),
16
- getWorkspaceSkillsDir: () => join(TEST_DIR, 'skills'),
17
- getWorkspaceHooksDir: () => join(TEST_DIR, 'hooks'),
17
+ getWorkspaceConfigPath: () => join(TEST_DIR, "config.json"),
18
+ getWorkspaceSkillsDir: () => join(TEST_DIR, "skills"),
19
+ getWorkspaceHooksDir: () => join(TEST_DIR, "hooks"),
18
20
  getWorkspacePromptPath: (file: string) => join(TEST_DIR, file),
19
21
  ensureDataDir: () => {},
20
- getSocketPath: () => join(TEST_DIR, 'vellum.sock'),
21
- getPidPath: () => join(TEST_DIR, 'vellum.pid'),
22
- getDbPath: () => join(TEST_DIR, 'data', 'assistant.db'),
23
- getLogPath: () => join(TEST_DIR, 'logs', 'vellum.log'),
24
- getHistoryPath: () => join(TEST_DIR, 'history'),
25
- getHooksDir: () => join(TEST_DIR, 'hooks'),
26
- getIpcBlobDir: () => join(TEST_DIR, 'ipc-blobs'),
27
- getSandboxRootDir: () => join(TEST_DIR, 'sandbox'),
22
+ getSocketPath: () => join(TEST_DIR, "vellum.sock"),
23
+ getPidPath: () => join(TEST_DIR, "vellum.pid"),
24
+ getDbPath: () => join(TEST_DIR, "data", "assistant.db"),
25
+ getLogPath: () => join(TEST_DIR, "logs", "vellum.log"),
26
+ getHistoryPath: () => join(TEST_DIR, "history"),
27
+ getHooksDir: () => join(TEST_DIR, "hooks"),
28
+ getIpcBlobDir: () => join(TEST_DIR, "ipc-blobs"),
29
+ getSandboxRootDir: () => join(TEST_DIR, "sandbox"),
28
30
  getSandboxWorkingDir: () => TEST_DIR,
29
- getInterfacesDir: () => join(TEST_DIR, 'interfaces'),
30
- isMacOS: () => process.platform === 'darwin',
31
- isLinux: () => process.platform === 'linux',
32
- isWindows: () => process.platform === 'win32',
31
+ getInterfacesDir: () => join(TEST_DIR, "interfaces"),
32
+ isMacOS: () => process.platform === "darwin",
33
+ isLinux: () => process.platform === "linux",
34
+ isWindows: () => process.platform === "win32",
33
35
  getPlatformName: () => process.platform,
34
36
  getClipboardCommand: () => null,
35
37
  removeSocketFile: () => {},
@@ -38,95 +40,97 @@ mock.module('../util/platform.js', () => ({
38
40
  migrateToDataLayout: () => {},
39
41
  }));
40
42
 
41
- mock.module('../util/logger.js', () => ({
42
- getLogger: () => new Proxy({} as Record<string, unknown>, {
43
- get: () => () => {},
44
- }),
43
+ mock.module("../util/logger.js", () => ({
44
+ getLogger: () =>
45
+ new Proxy({} as Record<string, unknown>, {
46
+ get: () => () => {},
47
+ }),
45
48
  isDebug: () => false,
46
49
  truncateForLog: (v: string) => v,
47
50
  }));
48
51
 
49
- const { buildStarterTaskPlaybookSection, buildSystemPrompt } = await import('../config/system-prompt.js');
52
+ const { buildStarterTaskPlaybookSection, buildSystemPrompt } =
53
+ await import("../config/system-prompt.js");
50
54
 
51
- describe('buildStarterTaskPlaybookSection', () => {
52
- test('returns a string with the section heading', () => {
55
+ describe("buildStarterTaskPlaybookSection", () => {
56
+ test("returns a string with the section heading", () => {
53
57
  const section = buildStarterTaskPlaybookSection();
54
- expect(section).toContain('## Starter Task Playbooks');
58
+ expect(section).toContain("## Starter Task Playbooks");
55
59
  });
56
60
 
57
- test('documents all three kickoff intents', () => {
61
+ test("documents all three kickoff intents", () => {
58
62
  const section = buildStarterTaskPlaybookSection();
59
- expect(section).toContain('[STARTER_TASK:make_it_yours]');
60
- expect(section).toContain('[STARTER_TASK:research_topic]');
61
- expect(section).toContain('[STARTER_TASK:research_to_ui]');
63
+ expect(section).toContain("[STARTER_TASK:make_it_yours]");
64
+ expect(section).toContain("[STARTER_TASK:research_topic]");
65
+ expect(section).toContain("[STARTER_TASK:research_to_ui]");
62
66
  });
63
67
 
64
- test('includes the make_it_yours playbook', () => {
68
+ test("includes the make_it_yours playbook", () => {
65
69
  const section = buildStarterTaskPlaybookSection();
66
- expect(section).toContain('### Playbook: make_it_yours');
67
- expect(section).toContain('accent color');
68
- expect(section).toContain('Dashboard Color Preference');
69
- expect(section).toContain('user_selected');
70
+ expect(section).toContain("### Playbook: make_it_yours");
71
+ expect(section).toContain("accent color");
72
+ expect(section).toContain("Dashboard Color Preference");
73
+ expect(section).toContain("user_selected");
70
74
  });
71
75
 
72
- test('make_it_yours uses app_file_edit instead of invalid ui_show config_update', () => {
76
+ test("make_it_yours uses app_file_edit instead of invalid ui_show config_update", () => {
73
77
  const section = buildStarterTaskPlaybookSection();
74
- expect(section).toContain('app_file_edit');
75
- expect(section).not.toContain('config_update');
78
+ expect(section).toContain("app_file_edit");
79
+ expect(section).not.toContain("config_update");
76
80
  expect(section).not.toContain('surface_type: "config_update"');
77
81
  });
78
82
 
79
- test('includes the research_topic playbook', () => {
83
+ test("includes the research_topic playbook", () => {
80
84
  const section = buildStarterTaskPlaybookSection();
81
- expect(section).toContain('### Playbook: research_topic');
82
- expect(section).toContain('web search');
85
+ expect(section).toContain("### Playbook: research_topic");
86
+ expect(section).toContain("web search");
83
87
  });
84
88
 
85
- test('includes the research_to_ui playbook', () => {
89
+ test("includes the research_to_ui playbook", () => {
86
90
  const section = buildStarterTaskPlaybookSection();
87
- expect(section).toContain('### Playbook: research_to_ui');
88
- expect(section).toContain('app_create');
91
+ expect(section).toContain("### Playbook: research_to_ui");
92
+ expect(section).toContain("app_create");
89
93
  });
90
94
 
91
- test('includes general rules section', () => {
95
+ test("includes general rules section", () => {
92
96
  const section = buildStarterTaskPlaybookSection();
93
- expect(section).toContain('### General rules for all starter tasks');
97
+ expect(section).toContain("### General rules for all starter tasks");
94
98
  });
95
99
 
96
- test('enforces trust gating in general rules', () => {
100
+ test("enforces trust gating in general rules", () => {
97
101
  const section = buildStarterTaskPlaybookSection();
98
- expect(section).toContain('trust gating');
99
- expect(section).toContain('do NOT ask for elevated permissions');
102
+ expect(section).toContain("trust gating");
103
+ expect(section).toContain("do NOT ask for elevated permissions");
100
104
  });
101
105
 
102
- test('references USER.md onboarding tasks for status tracking', () => {
106
+ test("references USER.md onboarding tasks for status tracking", () => {
103
107
  const section = buildStarterTaskPlaybookSection();
104
- expect(section).toContain('## Onboarding Tasks');
105
- expect(section).toContain('in_progress');
106
- expect(section).toContain('done');
107
- expect(section).toContain('deferred_to_dashboard');
108
+ expect(section).toContain("## Onboarding Tasks");
109
+ expect(section).toContain("in_progress");
110
+ expect(section).toContain("done");
111
+ expect(section).toContain("deferred_to_dashboard");
108
112
  });
109
113
 
110
- test('make_it_yours playbook handles locale confirmation', () => {
114
+ test("make_it_yours playbook handles locale confirmation", () => {
111
115
  const section = buildStarterTaskPlaybookSection();
112
- expect(section).toContain('locale');
113
- expect(section).toContain('confidence: low');
116
+ expect(section).toContain("locale");
117
+ expect(section).toContain("confidence: low");
114
118
  });
115
119
 
116
- test('make_it_yours playbook includes confirmation step', () => {
120
+ test("make_it_yours playbook includes confirmation step", () => {
117
121
  const section = buildStarterTaskPlaybookSection();
118
- expect(section).toContain('Confirm the selection');
119
- expect(section).toContain('Sound good?');
122
+ expect(section).toContain("Confirm the selection");
123
+ expect(section).toContain("Sound good?");
120
124
  });
121
125
 
122
- test('research_to_ui playbook references dynamic UI quality standards', () => {
126
+ test("research_to_ui playbook references dynamic UI quality standards", () => {
123
127
  const section = buildStarterTaskPlaybookSection();
124
- expect(section).toContain('Dynamic UI quality standards');
125
- expect(section).toContain('anti-AI-slop');
128
+ expect(section).toContain("Dynamic UI quality standards");
129
+ expect(section).toContain("anti-AI-slop");
126
130
  });
127
131
  });
128
132
 
129
- describe('starter task playbook integration with buildSystemPrompt', () => {
133
+ describe("starter task playbook integration with buildSystemPrompt", () => {
130
134
  beforeEach(() => {
131
135
  mkdirSync(TEST_DIR, { recursive: true });
132
136
  });
@@ -137,41 +141,41 @@ describe('starter task playbook integration with buildSystemPrompt', () => {
137
141
  }
138
142
  });
139
143
 
140
- test('buildSystemPrompt includes the starter task playbook section when BOOTSTRAP.md exists', () => {
141
- writeFileSync(join(TEST_DIR, 'IDENTITY.md'), 'I am Vellum.');
142
- writeFileSync(join(TEST_DIR, 'BOOTSTRAP.md'), '# First run');
144
+ test("buildSystemPrompt includes the starter task playbook section when BOOTSTRAP.md exists", () => {
145
+ writeFileSync(join(TEST_DIR, "IDENTITY.md"), "I am Vellum.");
146
+ writeFileSync(join(TEST_DIR, "BOOTSTRAP.md"), "# First run");
143
147
  const result = buildSystemPrompt();
144
- expect(result).toContain('## Starter Task Playbooks');
148
+ expect(result).toContain("## Starter Task Playbooks");
145
149
  });
146
150
 
147
- test('buildSystemPrompt omits starter task playbooks after onboarding is complete', () => {
148
- writeFileSync(join(TEST_DIR, 'IDENTITY.md'), 'I am Vellum.');
151
+ test("buildSystemPrompt omits starter task playbooks after onboarding is complete", () => {
152
+ writeFileSync(join(TEST_DIR, "IDENTITY.md"), "I am Vellum.");
149
153
  // No BOOTSTRAP.md → onboarding complete
150
154
  const result = buildSystemPrompt();
151
- expect(result).not.toContain('## Starter Task Playbooks');
155
+ expect(result).not.toContain("## Starter Task Playbooks");
152
156
  });
153
157
 
154
- test('starter task playbook and channel awareness both present during onboarding', () => {
155
- writeFileSync(join(TEST_DIR, 'IDENTITY.md'), 'I am Vellum.');
156
- writeFileSync(join(TEST_DIR, 'BOOTSTRAP.md'), '# First run');
158
+ test("starter task playbook and channel awareness both present during onboarding", () => {
159
+ writeFileSync(join(TEST_DIR, "IDENTITY.md"), "I am Vellum.");
160
+ writeFileSync(join(TEST_DIR, "BOOTSTRAP.md"), "# First run");
157
161
  const result = buildSystemPrompt();
158
- const starterIdx = result.indexOf('## Starter Task Playbooks');
159
- const channelIdx = result.indexOf('## Channel Awareness & Trust Gating');
162
+ const starterIdx = result.indexOf("## Starter Task Playbooks");
163
+ const channelIdx = result.indexOf("## Channel Awareness & Trust Gating");
160
164
  expect(starterIdx).toBeGreaterThan(-1);
161
165
  expect(channelIdx).toBeGreaterThan(-1);
162
166
  });
163
167
 
164
- test('all three kickoff intents present in full system prompt during onboarding', () => {
165
- writeFileSync(join(TEST_DIR, 'IDENTITY.md'), 'I am Vellum.');
166
- writeFileSync(join(TEST_DIR, 'BOOTSTRAP.md'), '# First run');
168
+ test("all three kickoff intents present in full system prompt during onboarding", () => {
169
+ writeFileSync(join(TEST_DIR, "IDENTITY.md"), "I am Vellum.");
170
+ writeFileSync(join(TEST_DIR, "BOOTSTRAP.md"), "# First run");
167
171
  const result = buildSystemPrompt();
168
- expect(result).toContain('[STARTER_TASK:make_it_yours]');
169
- expect(result).toContain('[STARTER_TASK:research_topic]');
170
- expect(result).toContain('[STARTER_TASK:research_to_ui]');
172
+ expect(result).toContain("[STARTER_TASK:make_it_yours]");
173
+ expect(result).toContain("[STARTER_TASK:research_topic]");
174
+ expect(result).toContain("[STARTER_TASK:research_to_ui]");
171
175
  });
172
176
 
173
- test('system prompt does not contain invalid config_update surface type (bare)', () => {
174
- writeFileSync(join(TEST_DIR, 'IDENTITY.md'), 'I am Vellum.');
177
+ test("system prompt does not contain invalid config_update surface type (bare)", () => {
178
+ writeFileSync(join(TEST_DIR, "IDENTITY.md"), "I am Vellum.");
175
179
  const result = buildSystemPrompt();
176
180
  // voice_config_update is a valid tool name; only bare 'config_update' surface type is invalid
177
181
  expect(result).not.toContain('surface_type: "config_update"');
@@ -1,169 +1,168 @@
1
- import { readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
-
4
- import { describe, expect,test } from 'bun:test';
5
-
6
- const templatesDir = join(import.meta.dirname, '..', 'config', 'templates');
7
- const bootstrap = readFileSync(join(templatesDir, 'BOOTSTRAP.md'), 'utf-8');
8
- const identity = readFileSync(join(templatesDir, 'IDENTITY.md'), 'utf-8');
9
- const user = readFileSync(join(templatesDir, 'USER.md'), 'utf-8');
10
-
11
- describe('onboarding template contracts', () => {
12
- describe('BOOTSTRAP.md', () => {
13
- test('contains identity question prompts', () => {
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { describe, expect, test } from "bun:test";
4
+
5
+ const templatesDir = join(import.meta.dirname, "..", "config", "templates");
6
+ const bootstrap = readFileSync(join(templatesDir, "BOOTSTRAP.md"), "utf-8");
7
+ const identity = readFileSync(join(templatesDir, "IDENTITY.md"), "utf-8");
8
+ const user = readFileSync(join(templatesDir, "USER.md"), "utf-8");
9
+
10
+ describe("onboarding template contracts", () => {
11
+ describe("BOOTSTRAP.md", () => {
12
+ test("contains identity question prompts", () => {
14
13
  const lower = bootstrap.toLowerCase();
15
- expect(lower).toContain('who am i');
14
+ expect(lower).toContain("who am i");
16
15
  });
17
16
 
18
- test('infers personality indirectly instead of asking directly', () => {
17
+ test("infers personality indirectly instead of asking directly", () => {
19
18
  const lower = bootstrap.toLowerCase();
20
19
  // Personality step must instruct indirect/organic discovery
21
- expect(lower).toContain('personality');
22
- expect(lower).toContain('indirectly');
23
- expect(lower).toContain('vibe');
20
+ expect(lower).toContain("personality");
21
+ expect(lower).toContain("indirectly");
22
+ expect(lower).toContain("vibe");
24
23
  });
25
24
 
26
- test('contains emoji auto-selection with change-later instruction', () => {
25
+ test("contains emoji auto-selection with change-later instruction", () => {
27
26
  const lower = bootstrap.toLowerCase();
28
- expect(lower).toContain('emoji');
29
- expect(lower).toContain('change it later');
27
+ expect(lower).toContain("emoji");
28
+ expect(lower).toContain("change it later");
30
29
  });
31
30
 
32
- test('creates Home Base silently in the background', () => {
31
+ test("creates Home Base silently in the background", () => {
33
32
  const lower = bootstrap.toLowerCase();
34
- expect(lower).toContain('app_create');
35
- expect(lower).toContain('set_as_home_base');
33
+ expect(lower).toContain("app_create");
34
+ expect(lower).toContain("set_as_home_base");
36
35
  // Must NOT open or announce it
37
- expect(lower).toContain('do not open it with `app_open`');
38
- expect(lower).toContain('do not announce it');
36
+ expect(lower).toContain("do not open it with `app_open`");
37
+ expect(lower).toContain("do not announce it");
39
38
  });
40
39
 
41
- test('contains naming intent markers so the first reply includes naming cues', () => {
40
+ test("contains naming intent markers so the first reply includes naming cues", () => {
42
41
  const lower = bootstrap.toLowerCase();
43
42
  // The template must prompt the assistant to ask about names.
44
- expect(lower).toContain('name');
43
+ expect(lower).toContain("name");
45
44
  // The first step should be about locking in the assistant's name
46
- expect(lower).toContain('lock in your name');
45
+ expect(lower).toContain("lock in your name");
47
46
  // The conversation sequence must include identity/naming
48
- expect(lower).toContain('who am i');
47
+ expect(lower).toContain("who am i");
49
48
  });
50
49
 
51
- test('asks user name AFTER assistant identity is established', () => {
50
+ test("asks user name AFTER assistant identity is established", () => {
52
51
  // Step 1 is locking in the assistant's name, step 3 is asking the user's name
53
- const assistantNameIdx = bootstrap.indexOf('Lock in your name.');
54
- const userNameIdx = bootstrap.indexOf('who am I talking to?');
52
+ const assistantNameIdx = bootstrap.indexOf("Lock in your name.");
53
+ const userNameIdx = bootstrap.indexOf("who am I talking to?");
55
54
  expect(assistantNameIdx).toBeGreaterThan(-1);
56
55
  expect(userNameIdx).toBeGreaterThan(-1);
57
56
  expect(assistantNameIdx).toBeLessThan(userNameIdx);
58
57
  });
59
58
 
60
- test('gathers user context: work role, hobbies, daily tools', () => {
59
+ test("gathers user context: work role, hobbies, daily tools", () => {
61
60
  const lower = bootstrap.toLowerCase();
62
- expect(lower).toContain('work');
63
- expect(lower).toContain('hobbies');
64
- expect(lower).toContain('tools');
61
+ expect(lower).toContain("work");
62
+ expect(lower).toContain("hobbies");
63
+ expect(lower).toContain("tools");
65
64
  });
66
65
 
67
- test('shows exactly 2 suggestions via ui_show card with relay_prompt actions', () => {
68
- expect(bootstrap).toContain('ui_show');
69
- expect(bootstrap).toContain('exactly 2');
66
+ test("shows exactly 2 suggestions via ui_show card with relay_prompt actions", () => {
67
+ expect(bootstrap).toContain("ui_show");
68
+ expect(bootstrap).toContain("exactly 2");
70
69
  // Must use card surface with relay_prompt action buttons
71
70
  expect(bootstrap).toContain('surface_type: "card"');
72
- expect(bootstrap).toContain('relay_prompt');
71
+ expect(bootstrap).toContain("relay_prompt");
73
72
  });
74
73
 
75
- test('contains completion gate with all required conditions', () => {
74
+ test("contains completion gate with all required conditions", () => {
76
75
  const lower = bootstrap.toLowerCase();
77
- expect(lower).toContain('completion gate');
78
- expect(lower).toContain('do not delete this file');
76
+ expect(lower).toContain("completion gate");
77
+ expect(lower).toContain("do not delete this file");
79
78
  // Assistant name is hard-required
80
- expect(lower).toContain('you have a name');
81
- expect(lower).toContain('hard requirement');
82
- expect(lower).toContain('vibe');
79
+ expect(lower).toContain("you have a name");
80
+ expect(lower).toContain("hard requirement");
81
+ expect(lower).toContain("vibe");
83
82
  // User detail fields must be resolved (provided, inferred, or declined)
84
- expect(lower).toContain('resolved');
85
- expect(lower).toContain('work role');
86
- expect(lower).toContain('2 suggestions shown');
87
- expect(lower).toContain('selected one, deferred both');
88
- expect(lower).toContain('home base');
83
+ expect(lower).toContain("resolved");
84
+ expect(lower).toContain("work role");
85
+ expect(lower).toContain("2 suggestions shown");
86
+ expect(lower).toContain("selected one, deferred both");
87
+ expect(lower).toContain("home base");
89
88
  });
90
89
 
91
- test('contains privacy/refusal policy', () => {
90
+ test("contains privacy/refusal policy", () => {
92
91
  const lower = bootstrap.toLowerCase();
93
92
  // Must have a privacy section
94
- expect(lower).toContain('privacy');
93
+ expect(lower).toContain("privacy");
95
94
  // Assistant name is hard-required, user details are best-effort
96
- expect(lower).toContain('hard-required');
97
- expect(lower).toContain('best-effort');
95
+ expect(lower).toContain("hard-required");
96
+ expect(lower).toContain("best-effort");
98
97
  // Refusal is a valid resolution
99
- expect(lower).toContain('declined');
100
- expect(lower).toContain('do not push');
98
+ expect(lower).toContain("declined");
99
+ expect(lower).toContain("do not push");
101
100
  });
102
101
 
103
- test('defines resolved as provided, inferred, or declined', () => {
102
+ test("defines resolved as provided, inferred, or declined", () => {
104
103
  const lower = bootstrap.toLowerCase();
105
104
  // The template must define what "resolved" means
106
- expect(lower).toContain('resolved');
107
- expect(lower).toContain('inferred');
108
- expect(lower).toContain('declined');
105
+ expect(lower).toContain("resolved");
106
+ expect(lower).toContain("inferred");
107
+ expect(lower).toContain("declined");
109
108
  });
110
109
 
111
- test('preserves no em dashes instruction', () => {
110
+ test("preserves no em dashes instruction", () => {
112
111
  const lower = bootstrap.toLowerCase();
113
- expect(lower).toContain('em dashes');
112
+ expect(lower).toContain("em dashes");
114
113
  });
115
114
 
116
- test('preserves no technical jargon instruction', () => {
115
+ test("preserves no technical jargon instruction", () => {
117
116
  const lower = bootstrap.toLowerCase();
118
- expect(lower).toContain('technical jargon');
119
- expect(lower).toContain('system internals');
117
+ expect(lower).toContain("technical jargon");
118
+ expect(lower).toContain("system internals");
120
119
  });
121
120
 
122
- test('preserves comment line format instruction', () => {
121
+ test("preserves comment line format instruction", () => {
123
122
  // The template must start with the comment format explanation
124
123
  expect(bootstrap).toMatch(/^_ Lines starting with _/);
125
124
  });
126
125
 
127
- test('instructs saving to IDENTITY.md, USER.md, and SOUL.md via file_edit', () => {
128
- expect(bootstrap).toContain('IDENTITY.md');
129
- expect(bootstrap).toContain('USER.md');
130
- expect(bootstrap).toContain('SOUL.md');
131
- expect(bootstrap).toContain('file_edit');
126
+ test("instructs saving to IDENTITY.md, USER.md, and SOUL.md via file_edit", () => {
127
+ expect(bootstrap).toContain("IDENTITY.md");
128
+ expect(bootstrap).toContain("USER.md");
129
+ expect(bootstrap).toContain("SOUL.md");
130
+ expect(bootstrap).toContain("file_edit");
132
131
  });
133
132
  });
134
133
 
135
- describe('IDENTITY.md', () => {
136
- test('contains canonical fields: Name, Nature, Personality, Emoji', () => {
137
- expect(identity).toContain('**Name:**');
138
- expect(identity).toContain('**Nature:**');
139
- expect(identity).toContain('**Personality:**');
140
- expect(identity).toContain('**Emoji:**');
134
+ describe("IDENTITY.md", () => {
135
+ test("contains canonical fields: Name, Nature, Personality, Emoji", () => {
136
+ expect(identity).toContain("**Name:**");
137
+ expect(identity).toContain("**Nature:**");
138
+ expect(identity).toContain("**Personality:**");
139
+ expect(identity).toContain("**Emoji:**");
141
140
  });
142
141
 
143
- test('contains the emoji overwrite instruction', () => {
142
+ test("contains the emoji overwrite instruction", () => {
144
143
  const lower = identity.toLowerCase();
145
- expect(lower).toContain('change their emoji');
144
+ expect(lower).toContain("change their emoji");
146
145
  });
147
146
 
148
- test('contains the style tendency field', () => {
149
- expect(identity).toContain('**Style tendency:**');
147
+ test("contains the style tendency field", () => {
148
+ expect(identity).toContain("**Style tendency:**");
150
149
  });
151
150
  });
152
151
 
153
- describe('USER.md', () => {
154
- test('contains onboarding snapshot with all required fields', () => {
155
- expect(user).toContain('Preferred name/reference:');
156
- expect(user).toContain('Goals:');
157
- expect(user).toContain('Locale:');
158
- expect(user).toContain('Work role:');
159
- expect(user).toContain('Hobbies/fun:');
160
- expect(user).toContain('Daily tools:');
152
+ describe("USER.md", () => {
153
+ test("contains onboarding snapshot with all required fields", () => {
154
+ expect(user).toContain("Preferred name/reference:");
155
+ expect(user).toContain("Goals:");
156
+ expect(user).toContain("Locale:");
157
+ expect(user).toContain("Work role:");
158
+ expect(user).toContain("Hobbies/fun:");
159
+ expect(user).toContain("Daily tools:");
161
160
  });
162
161
 
163
- test('documents resolved-field status conventions', () => {
162
+ test("documents resolved-field status conventions", () => {
164
163
  const lower = user.toLowerCase();
165
- expect(lower).toContain('declined_by_user');
166
- expect(lower).toContain('resolved');
164
+ expect(lower).toContain("declined_by_user");
165
+ expect(lower).toContain("resolved");
167
166
  });
168
167
  });
169
168
  });