@vellumai/assistant 0.4.17 → 0.4.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (515) hide show
  1. package/eslint.config.mjs +2 -2
  2. package/package.json +1 -1
  3. package/src/__tests__/access-request-decision.test.ts +128 -120
  4. package/src/__tests__/account-registry.test.ts +121 -110
  5. package/src/__tests__/active-skill-tools.test.ts +200 -172
  6. package/src/__tests__/actor-token-service.test.ts +341 -274
  7. package/src/__tests__/agent-loop-thinking.test.ts +28 -19
  8. package/src/__tests__/agent-loop.test.ts +798 -378
  9. package/src/__tests__/anthropic-provider.test.ts +405 -247
  10. package/src/__tests__/app-builder-tool-scripts.test.ts +97 -97
  11. package/src/__tests__/app-bundler.test.ts +112 -79
  12. package/src/__tests__/app-executors.test.ts +205 -178
  13. package/src/__tests__/app-git-history.test.ts +90 -73
  14. package/src/__tests__/app-git-service.test.ts +67 -53
  15. package/src/__tests__/app-open-proxy.test.ts +29 -25
  16. package/src/__tests__/approval-conversation-turn.test.ts +100 -81
  17. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +45 -17
  18. package/src/__tests__/approval-message-composer.test.ts +119 -119
  19. package/src/__tests__/approval-primitive.test.ts +264 -233
  20. package/src/__tests__/approval-routes-http.test.ts +4 -3
  21. package/src/__tests__/asset-materialize-tool.test.ts +250 -178
  22. package/src/__tests__/asset-search-tool.test.ts +251 -191
  23. package/src/__tests__/assistant-attachment-directive.test.ts +187 -142
  24. package/src/__tests__/assistant-attachments.test.ts +254 -186
  25. package/src/__tests__/assistant-event-hub.test.ts +105 -63
  26. package/src/__tests__/assistant-event.test.ts +66 -58
  27. package/src/__tests__/assistant-events-sse-hardening.test.ts +113 -73
  28. package/src/__tests__/assistant-feature-flag-guard.test.ts +78 -52
  29. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +48 -45
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +118 -77
  31. package/src/__tests__/assistant-id-boundary-guard.test.ts +158 -104
  32. package/src/__tests__/attachments-store.test.ts +240 -183
  33. package/src/__tests__/attachments.test.ts +70 -62
  34. package/src/__tests__/audit-log-rotation.test.ts +50 -35
  35. package/src/__tests__/browser-fill-credential.test.ts +169 -101
  36. package/src/__tests__/browser-manager.test.ts +97 -75
  37. package/src/__tests__/browser-runtime-check.test.ts +16 -15
  38. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +12 -10
  39. package/src/__tests__/browser-skill-endstate.test.ts +97 -72
  40. package/src/__tests__/bundle-scanner.test.ts +47 -22
  41. package/src/__tests__/bundled-asset.test.ts +74 -47
  42. package/src/__tests__/call-constants.test.ts +19 -19
  43. package/src/__tests__/call-controller.test.ts +0 -1
  44. package/src/__tests__/call-conversation-messages.test.ts +90 -65
  45. package/src/__tests__/call-domain.test.ts +149 -121
  46. package/src/__tests__/call-pointer-message-composer.test.ts +113 -83
  47. package/src/__tests__/call-pointer-messages.test.ts +213 -154
  48. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +9 -10
  49. package/src/__tests__/call-recovery.test.ts +232 -212
  50. package/src/__tests__/call-routes-http.test.ts +0 -1
  51. package/src/__tests__/call-start-guardian-guard.test.ts +32 -30
  52. package/src/__tests__/call-state-machine.test.ts +62 -51
  53. package/src/__tests__/call-state.test.ts +89 -75
  54. package/src/__tests__/call-store.test.ts +387 -316
  55. package/src/__tests__/callback-handoff-copy.test.ts +84 -82
  56. package/src/__tests__/canonical-guardian-store.test.ts +331 -280
  57. package/src/__tests__/channel-approval-routes.test.ts +1643 -1115
  58. package/src/__tests__/channel-approval.test.ts +139 -137
  59. package/src/__tests__/channel-approvals.test.ts +0 -1
  60. package/src/__tests__/channel-delivery-store.test.ts +232 -194
  61. package/src/__tests__/channel-guardian.test.ts +5 -3
  62. package/src/__tests__/channel-invite-transport.test.ts +107 -92
  63. package/src/__tests__/channel-policy.test.ts +42 -38
  64. package/src/__tests__/channel-readiness-service.test.ts +119 -102
  65. package/src/__tests__/channel-reply-delivery.test.ts +147 -118
  66. package/src/__tests__/channel-retry-sweep.test.ts +153 -110
  67. package/src/__tests__/checker.test.ts +3309 -1850
  68. package/src/__tests__/clarification-resolver.test.ts +91 -79
  69. package/src/__tests__/classifier.test.ts +64 -54
  70. package/src/__tests__/claude-code-skill-regression.test.ts +42 -37
  71. package/src/__tests__/claude-code-tool-profiles.test.ts +31 -29
  72. package/src/__tests__/clawhub.test.ts +92 -82
  73. package/src/__tests__/cli.test.ts +30 -30
  74. package/src/__tests__/clipboard.test.ts +53 -46
  75. package/src/__tests__/commit-guarantee.test.ts +59 -52
  76. package/src/__tests__/commit-message-enrichment-service.test.ts +203 -75
  77. package/src/__tests__/compaction.benchmark.test.ts +33 -31
  78. package/src/__tests__/computer-use-session-compaction.test.ts +60 -50
  79. package/src/__tests__/computer-use-session-lifecycle.test.ts +145 -117
  80. package/src/__tests__/computer-use-session-working-dir.test.ts +62 -48
  81. package/src/__tests__/computer-use-skill-baseline.test.ts +22 -19
  82. package/src/__tests__/computer-use-skill-endstate.test.ts +45 -31
  83. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +121 -88
  84. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +65 -42
  85. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +33 -18
  86. package/src/__tests__/computer-use-tools.test.ts +121 -98
  87. package/src/__tests__/config-schema.test.ts +443 -347
  88. package/src/__tests__/config-watcher.test.ts +96 -81
  89. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +148 -133
  90. package/src/__tests__/conflict-intent-tokenization.test.ts +96 -78
  91. package/src/__tests__/conflict-policy.test.ts +151 -80
  92. package/src/__tests__/conflict-store.test.ts +203 -157
  93. package/src/__tests__/connection-policy.test.ts +89 -59
  94. package/src/__tests__/contacts-tools.test.ts +247 -178
  95. package/src/__tests__/context-memory-e2e.test.ts +306 -214
  96. package/src/__tests__/context-token-estimator.test.ts +114 -74
  97. package/src/__tests__/context-window-manager.test.ts +269 -167
  98. package/src/__tests__/contradiction-checker.test.ts +161 -135
  99. package/src/__tests__/conversation-attention-store.test.ts +350 -290
  100. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  101. package/src/__tests__/conversation-pairing.test.ts +220 -113
  102. package/src/__tests__/conversation-store.test.ts +390 -235
  103. package/src/__tests__/credential-broker-browser-fill.test.ts +325 -250
  104. package/src/__tests__/credential-broker-server-use.test.ts +283 -243
  105. package/src/__tests__/credential-broker.test.ts +128 -74
  106. package/src/__tests__/credential-host-pattern-match.test.ts +64 -44
  107. package/src/__tests__/credential-metadata-store.test.ts +360 -311
  108. package/src/__tests__/credential-policy-validate.test.ts +81 -65
  109. package/src/__tests__/credential-resolve.test.ts +212 -145
  110. package/src/__tests__/credential-security-e2e.test.ts +144 -103
  111. package/src/__tests__/credential-security-invariants.test.ts +253 -208
  112. package/src/__tests__/credential-selection.test.ts +254 -146
  113. package/src/__tests__/credential-vault-unit.test.ts +531 -341
  114. package/src/__tests__/credential-vault.test.ts +761 -484
  115. package/src/__tests__/daemon-assistant-events.test.ts +91 -66
  116. package/src/__tests__/daemon-lifecycle.test.ts +258 -190
  117. package/src/__tests__/daemon-server-session-init.test.ts +0 -1
  118. package/src/__tests__/date-context.test.ts +314 -249
  119. package/src/__tests__/db-migration-rollback.test.ts +259 -130
  120. package/src/__tests__/db-schedule-syntax-migration.test.ts +78 -41
  121. package/src/__tests__/delete-managed-skill-tool.test.ts +77 -53
  122. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
  123. package/src/__tests__/dictation-mode-detection.test.ts +77 -55
  124. package/src/__tests__/dictation-profile-store.test.ts +70 -56
  125. package/src/__tests__/dictation-text-processing.test.ts +53 -35
  126. package/src/__tests__/diff.test.ts +102 -98
  127. package/src/__tests__/domain-normalize.test.ts +54 -54
  128. package/src/__tests__/domain-policy.test.ts +71 -55
  129. package/src/__tests__/dynamic-page-surface.test.ts +31 -33
  130. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +69 -69
  131. package/src/__tests__/edit-engine.test.ts +56 -56
  132. package/src/__tests__/elevenlabs-client.test.ts +117 -91
  133. package/src/__tests__/elevenlabs-config.test.ts +32 -31
  134. package/src/__tests__/email-classifier.test.ts +15 -12
  135. package/src/__tests__/email-cli.test.ts +121 -108
  136. package/src/__tests__/emit-signal-routing-intent.test.ts +76 -69
  137. package/src/__tests__/encrypted-store.test.ts +180 -154
  138. package/src/__tests__/entity-extractor.test.ts +108 -87
  139. package/src/__tests__/entity-search.test.ts +664 -258
  140. package/src/__tests__/ephemeral-permissions.test.ts +224 -188
  141. package/src/__tests__/event-bus.test.ts +81 -77
  142. package/src/__tests__/extract-email.test.ts +29 -20
  143. package/src/__tests__/file-edit-tool.test.ts +62 -44
  144. package/src/__tests__/file-ops-service.test.ts +131 -114
  145. package/src/__tests__/file-read-tool.test.ts +48 -31
  146. package/src/__tests__/file-write-tool.test.ts +43 -37
  147. package/src/__tests__/filesystem-tools.test.ts +238 -209
  148. package/src/__tests__/followup-tools.test.ts +237 -162
  149. package/src/__tests__/forbidden-legacy-symbols.test.ts +19 -20
  150. package/src/__tests__/frontmatter.test.ts +96 -81
  151. package/src/__tests__/fuzzy-match-property.test.ts +75 -81
  152. package/src/__tests__/fuzzy-match.test.ts +71 -65
  153. package/src/__tests__/gateway-client-managed-outbound.test.ts +76 -57
  154. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  155. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  156. package/src/__tests__/gemini-image-service.test.ts +113 -100
  157. package/src/__tests__/gemini-provider.test.ts +297 -220
  158. package/src/__tests__/get-weather.test.ts +188 -114
  159. package/src/__tests__/gmail-integration.test.ts +0 -1
  160. package/src/__tests__/guardian-action-conversation-turn.test.ts +226 -171
  161. package/src/__tests__/guardian-action-copy-generator.test.ts +111 -93
  162. package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
  163. package/src/__tests__/guardian-action-followup-store.test.ts +199 -167
  164. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +297 -250
  165. package/src/__tests__/guardian-action-late-reply.test.ts +462 -316
  166. package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +23 -18
  167. package/src/__tests__/guardian-action-store.test.ts +158 -109
  168. package/src/__tests__/guardian-action-sweep.test.ts +114 -100
  169. package/src/__tests__/guardian-actions-endpoint.test.ts +440 -256
  170. package/src/__tests__/guardian-control-plane-policy.test.ts +497 -331
  171. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +217 -215
  172. package/src/__tests__/guardian-dispatch.test.ts +316 -256
  173. package/src/__tests__/guardian-grant-minting.test.ts +247 -178
  174. package/src/__tests__/guardian-outbound-http.test.ts +5 -3
  175. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +99 -96
  176. package/src/__tests__/guardian-question-copy.test.ts +17 -17
  177. package/src/__tests__/guardian-question-mode.test.ts +134 -100
  178. package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
  179. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  180. package/src/__tests__/guardian-verification-intent-routing.test.ts +94 -88
  181. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  182. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +0 -1
  183. package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -1
  184. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +92 -76
  185. package/src/__tests__/handlers-cu-observation-blob.test.ts +103 -70
  186. package/src/__tests__/handlers-ipc-blob-probe.test.ts +77 -51
  187. package/src/__tests__/handlers-slack-config.test.ts +63 -54
  188. package/src/__tests__/handlers-task-submit-slash.test.ts +18 -18
  189. package/src/__tests__/handlers-telegram-config.test.ts +662 -329
  190. package/src/__tests__/handlers-twitter-config.test.ts +525 -298
  191. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +3 -2
  192. package/src/__tests__/headless-browser-interactions.test.ts +444 -280
  193. package/src/__tests__/headless-browser-navigate.test.ts +116 -79
  194. package/src/__tests__/headless-browser-read-tools.test.ts +123 -86
  195. package/src/__tests__/headless-browser-snapshot.test.ts +71 -56
  196. package/src/__tests__/heartbeat-service.test.ts +76 -58
  197. package/src/__tests__/history-repair-observability.test.ts +14 -14
  198. package/src/__tests__/history-repair.test.ts +171 -167
  199. package/src/__tests__/home-base-bootstrap.test.ts +30 -27
  200. package/src/__tests__/hooks-blocking.test.ts +86 -37
  201. package/src/__tests__/hooks-cli.test.ts +104 -68
  202. package/src/__tests__/hooks-config.test.ts +81 -43
  203. package/src/__tests__/hooks-discovery.test.ts +106 -96
  204. package/src/__tests__/hooks-integration.test.ts +78 -72
  205. package/src/__tests__/hooks-manager.test.ts +99 -61
  206. package/src/__tests__/hooks-runner.test.ts +94 -71
  207. package/src/__tests__/hooks-settings.test.ts +69 -64
  208. package/src/__tests__/hooks-templates.test.ts +85 -54
  209. package/src/__tests__/hooks-ts-runner.test.ts +82 -45
  210. package/src/__tests__/hooks-watch.test.ts +32 -22
  211. package/src/__tests__/host-file-edit-tool.test.ts +190 -148
  212. package/src/__tests__/host-file-read-tool.test.ts +86 -63
  213. package/src/__tests__/host-file-write-tool.test.ts +98 -64
  214. package/src/__tests__/host-shell-tool.test.ts +342 -233
  215. package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
  216. package/src/__tests__/ingress-member-store.test.ts +163 -159
  217. package/src/__tests__/ingress-reconcile.test.ts +0 -1
  218. package/src/__tests__/ingress-routes-http.test.ts +441 -356
  219. package/src/__tests__/ingress-url-consistency.test.ts +125 -64
  220. package/src/__tests__/integration-status.test.ts +93 -73
  221. package/src/__tests__/intent-routing.test.ts +148 -118
  222. package/src/__tests__/invite-redemption-service.test.ts +163 -121
  223. package/src/__tests__/ipc-blob-store.test.ts +104 -91
  224. package/src/__tests__/ipc-contract-inventory.test.ts +27 -15
  225. package/src/__tests__/ipc-contract.test.ts +24 -23
  226. package/src/__tests__/ipc-protocol.test.ts +52 -46
  227. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +61 -50
  228. package/src/__tests__/ipc-snapshot.test.ts +1135 -1056
  229. package/src/__tests__/ipc-validate.test.ts +240 -179
  230. package/src/__tests__/key-migration.test.ts +123 -90
  231. package/src/__tests__/keychain.test.ts +150 -123
  232. package/src/__tests__/lifecycle-docs-guard.test.ts +65 -64
  233. package/src/__tests__/llm-usage-store.test.ts +112 -87
  234. package/src/__tests__/managed-skill-lifecycle.test.ts +147 -108
  235. package/src/__tests__/managed-store.test.ts +411 -360
  236. package/src/__tests__/mcp-cli.test.ts +189 -123
  237. package/src/__tests__/mcp-health-check.test.ts +26 -21
  238. package/src/__tests__/media-generate-image.test.ts +122 -99
  239. package/src/__tests__/media-reuse-story.e2e.test.ts +282 -214
  240. package/src/__tests__/media-visibility-policy.test.ts +86 -38
  241. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +146 -100
  242. package/src/__tests__/memory-lifecycle-e2e.test.ts +385 -297
  243. package/src/__tests__/memory-query-builder.test.ts +32 -33
  244. package/src/__tests__/memory-recall-quality.test.ts +761 -407
  245. package/src/__tests__/memory-regressions.experimental.test.ts +443 -380
  246. package/src/__tests__/memory-regressions.test.ts +3725 -2642
  247. package/src/__tests__/memory-retrieval-budget.test.ts +7 -8
  248. package/src/__tests__/memory-retrieval.benchmark.test.ts +144 -109
  249. package/src/__tests__/memory-upsert-concurrency.test.ts +292 -201
  250. package/src/__tests__/messaging-send-tool.test.ts +36 -29
  251. package/src/__tests__/migration-cli-flows.test.ts +69 -53
  252. package/src/__tests__/migration-ordering.test.ts +103 -86
  253. package/src/__tests__/mime-builder.test.ts +55 -32
  254. package/src/__tests__/mock-signup-server.test.ts +384 -246
  255. package/src/__tests__/model-intents.test.ts +61 -37
  256. package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +9 -12
  257. package/src/__tests__/no-is-trusted-guard.test.ts +24 -21
  258. package/src/__tests__/non-member-access-request.test.ts +3 -2
  259. package/src/__tests__/notification-broadcaster.test.ts +99 -81
  260. package/src/__tests__/notification-decision-fallback.test.ts +223 -178
  261. package/src/__tests__/notification-decision-strategy.test.ts +375 -337
  262. package/src/__tests__/notification-deep-link.test.ts +67 -61
  263. package/src/__tests__/notification-guardian-path.test.ts +248 -206
  264. package/src/__tests__/notification-routing-intent.test.ts +166 -93
  265. package/src/__tests__/notification-thread-candidate-validation.test.ts +78 -75
  266. package/src/__tests__/notification-thread-candidates.test.ts +64 -61
  267. package/src/__tests__/oauth-callback-registry.test.ts +40 -30
  268. package/src/__tests__/oauth-connect-handler.test.ts +109 -89
  269. package/src/__tests__/oauth-scope-policy.test.ts +63 -55
  270. package/src/__tests__/oauth2-gateway-transport.test.ts +252 -174
  271. package/src/__tests__/onboarding-starter-tasks.test.ts +93 -89
  272. package/src/__tests__/onboarding-template-contract.test.ts +93 -94
  273. package/src/__tests__/openai-provider.test.ts +366 -274
  274. package/src/__tests__/pairing-concurrent.test.ts +18 -12
  275. package/src/__tests__/pairing-routes.test.ts +45 -41
  276. package/src/__tests__/parallel-tool.benchmark.test.ts +108 -58
  277. package/src/__tests__/parser.test.ts +316 -226
  278. package/src/__tests__/path-classifier.test.ts +24 -25
  279. package/src/__tests__/path-policy.test.ts +187 -147
  280. package/src/__tests__/phone.test.ts +36 -36
  281. package/src/__tests__/platform-move-helper.test.ts +48 -40
  282. package/src/__tests__/platform-socket-path.test.ts +23 -24
  283. package/src/__tests__/platform-workspace-migration.test.ts +464 -414
  284. package/src/__tests__/platform.test.ts +61 -53
  285. package/src/__tests__/playbook-execution.test.ts +397 -265
  286. package/src/__tests__/playbook-tools.test.ts +267 -196
  287. package/src/__tests__/prebuilt-home-base-seed.test.ts +30 -27
  288. package/src/__tests__/pricing.test.ts +316 -136
  289. package/src/__tests__/profile-compiler.test.ts +206 -188
  290. package/src/__tests__/provider-commit-message-generator.test.ts +114 -106
  291. package/src/__tests__/provider-error-scenarios.test.ts +212 -158
  292. package/src/__tests__/provider-fail-open-selection.test.ts +51 -44
  293. package/src/__tests__/provider-registry-ollama.test.ts +13 -9
  294. package/src/__tests__/provider-streaming.benchmark.test.ts +232 -183
  295. package/src/__tests__/proxy-approval-callback.test.ts +180 -119
  296. package/src/__tests__/public-ingress-urls.test.ts +112 -94
  297. package/src/__tests__/qdrant-manager.test.ts +147 -98
  298. package/src/__tests__/ratelimit.test.ts +152 -82
  299. package/src/__tests__/recording-handler.test.ts +273 -151
  300. package/src/__tests__/recording-intent-fallback.test.ts +94 -75
  301. package/src/__tests__/recording-intent-handler.test.ts +0 -1
  302. package/src/__tests__/recording-intent.test.ts +578 -379
  303. package/src/__tests__/recording-state-machine.test.ts +530 -316
  304. package/src/__tests__/recurrence-engine-rruleset.test.ts +150 -92
  305. package/src/__tests__/recurrence-engine.test.ts +81 -41
  306. package/src/__tests__/recurrence-types.test.ts +63 -44
  307. package/src/__tests__/relay-server.test.ts +2131 -1602
  308. package/src/__tests__/reminder-store.test.ts +158 -80
  309. package/src/__tests__/reminder.test.ts +113 -109
  310. package/src/__tests__/remote-skill-policy.test.ts +96 -72
  311. package/src/__tests__/request-file-tool.test.ts +74 -67
  312. package/src/__tests__/response-tier.test.ts +131 -74
  313. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  314. package/src/__tests__/runtime-events-sse-parity.test.ts +167 -145
  315. package/src/__tests__/runtime-events-sse.test.ts +0 -1
  316. package/src/__tests__/sandbox-diagnostics.test.ts +66 -56
  317. package/src/__tests__/sandbox-host-parity.test.ts +377 -301
  318. package/src/__tests__/scaffold-managed-skill-tool.test.ts +213 -161
  319. package/src/__tests__/schedule-store.test.ts +268 -205
  320. package/src/__tests__/schedule-tools.test.ts +702 -524
  321. package/src/__tests__/scheduler-recurrence.test.ts +240 -130
  322. package/src/__tests__/scoped-approval-grants.test.ts +258 -168
  323. package/src/__tests__/scoped-grant-security-matrix.test.ts +160 -146
  324. package/src/__tests__/script-proxy-certs.test.ts +38 -35
  325. package/src/__tests__/script-proxy-connect-tunnel.test.ts +71 -46
  326. package/src/__tests__/script-proxy-decision-trace.test.ts +161 -84
  327. package/src/__tests__/script-proxy-http-forwarder.test.ts +146 -129
  328. package/src/__tests__/script-proxy-injection-runtime.test.ts +139 -113
  329. package/src/__tests__/script-proxy-mitm-handler.test.ts +226 -142
  330. package/src/__tests__/script-proxy-policy-runtime.test.ts +126 -86
  331. package/src/__tests__/script-proxy-policy.test.ts +308 -153
  332. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +74 -62
  333. package/src/__tests__/script-proxy-router.test.ts +111 -77
  334. package/src/__tests__/script-proxy-session-manager.test.ts +156 -113
  335. package/src/__tests__/script-proxy-session-runtime.test.ts +28 -24
  336. package/src/__tests__/secret-allowlist.test.ts +105 -90
  337. package/src/__tests__/secret-ingress-handler.test.ts +41 -30
  338. package/src/__tests__/secret-onetime-send.test.ts +67 -50
  339. package/src/__tests__/secret-prompt-log-hygiene.test.ts +35 -31
  340. package/src/__tests__/secret-response-routing.test.ts +50 -41
  341. package/src/__tests__/secret-scanner-executor.test.ts +152 -111
  342. package/src/__tests__/secret-scanner.test.ts +495 -413
  343. package/src/__tests__/secure-keys.test.ts +132 -121
  344. package/src/__tests__/send-endpoint-busy.test.ts +0 -1
  345. package/src/__tests__/send-notification-tool.test.ts +43 -42
  346. package/src/__tests__/sensitive-output-placeholders.test.ts +72 -64
  347. package/src/__tests__/sequence-store.test.ts +335 -167
  348. package/src/__tests__/server-history-render.test.ts +341 -202
  349. package/src/__tests__/session-abort-tool-results.test.ts +133 -70
  350. package/src/__tests__/session-confirmation-signals.test.ts +252 -160
  351. package/src/__tests__/session-conflict-gate.test.ts +775 -585
  352. package/src/__tests__/session-error.test.ts +222 -191
  353. package/src/__tests__/session-evictor.test.ts +79 -62
  354. package/src/__tests__/session-init.benchmark.test.ts +170 -108
  355. package/src/__tests__/session-load-history-repair.test.ts +273 -139
  356. package/src/__tests__/session-messaging-secret-redirect.test.ts +130 -90
  357. package/src/__tests__/session-pre-run-repair.test.ts +106 -59
  358. package/src/__tests__/session-profile-injection.test.ts +198 -130
  359. package/src/__tests__/session-provider-retry-repair.test.ts +223 -141
  360. package/src/__tests__/session-queue.test.ts +624 -321
  361. package/src/__tests__/session-runtime-assembly.test.ts +425 -329
  362. package/src/__tests__/session-runtime-workspace.test.ts +69 -61
  363. package/src/__tests__/session-skill-tools.test.ts +973 -678
  364. package/src/__tests__/session-slash-known.test.ts +185 -133
  365. package/src/__tests__/session-slash-queue.test.ts +147 -81
  366. package/src/__tests__/session-slash-unknown.test.ts +135 -90
  367. package/src/__tests__/session-surfaces-task-progress.test.ts +122 -87
  368. package/src/__tests__/session-tool-setup-app-refresh.test.ts +338 -177
  369. package/src/__tests__/session-tool-setup-memory-scope.test.ts +63 -40
  370. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +60 -37
  371. package/src/__tests__/session-tool-setup-tools-disabled.test.ts +28 -26
  372. package/src/__tests__/session-undo.test.ts +43 -30
  373. package/src/__tests__/session-workspace-cache-state.test.ts +108 -67
  374. package/src/__tests__/session-workspace-injection.test.ts +245 -117
  375. package/src/__tests__/session-workspace-tool-tracking.test.ts +260 -93
  376. package/src/__tests__/shared-filesystem-errors.test.ts +47 -47
  377. package/src/__tests__/shell-credential-ref.test.ts +126 -90
  378. package/src/__tests__/shell-identity.test.ts +134 -111
  379. package/src/__tests__/shell-parser-fuzz.test.ts +263 -179
  380. package/src/__tests__/shell-parser-property.test.ts +435 -288
  381. package/src/__tests__/shell-tool-proxy-mode.test.ts +142 -70
  382. package/src/__tests__/size-guard.test.ts +42 -44
  383. package/src/__tests__/skill-feature-flags-integration.test.ts +79 -52
  384. package/src/__tests__/skill-feature-flags.test.ts +75 -47
  385. package/src/__tests__/skill-include-graph.test.ts +143 -148
  386. package/src/__tests__/skill-load-feature-flag.test.ts +94 -59
  387. package/src/__tests__/skill-load-tool.test.ts +371 -199
  388. package/src/__tests__/skill-projection-feature-flag.test.ts +131 -88
  389. package/src/__tests__/skill-projection.benchmark.test.ts +93 -65
  390. package/src/__tests__/skill-script-runner-host.test.ts +460 -250
  391. package/src/__tests__/skill-script-runner-sandbox.test.ts +168 -108
  392. package/src/__tests__/skill-script-runner.test.ts +115 -74
  393. package/src/__tests__/skill-tool-factory.test.ts +140 -96
  394. package/src/__tests__/skill-tool-manifest.test.ts +306 -210
  395. package/src/__tests__/skill-version-hash.test.ts +70 -56
  396. package/src/__tests__/skills.test.ts +0 -1
  397. package/src/__tests__/slack-channel-config.test.ts +127 -84
  398. package/src/__tests__/slack-skill.test.ts +60 -47
  399. package/src/__tests__/slash-commands-catalog.test.ts +37 -31
  400. package/src/__tests__/slash-commands-parser.test.ts +71 -64
  401. package/src/__tests__/slash-commands-resolver.test.ts +143 -107
  402. package/src/__tests__/slash-commands-rewrite.test.ts +22 -22
  403. package/src/__tests__/speaker-identification.test.ts +28 -25
  404. package/src/__tests__/starter-bundle.test.ts +27 -23
  405. package/src/__tests__/starter-task-flow.test.ts +67 -52
  406. package/src/__tests__/subagent-manager-notify.test.ts +154 -108
  407. package/src/__tests__/subagent-tools.test.ts +311 -270
  408. package/src/__tests__/subagent-types.test.ts +40 -40
  409. package/src/__tests__/surface-mutex-cleanup.test.ts +42 -30
  410. package/src/__tests__/swarm-dag-pathological.test.ts +122 -111
  411. package/src/__tests__/swarm-orchestrator.test.ts +135 -101
  412. package/src/__tests__/swarm-plan-validator.test.ts +125 -73
  413. package/src/__tests__/swarm-recursion.test.ts +58 -46
  414. package/src/__tests__/swarm-router-planner.test.ts +99 -74
  415. package/src/__tests__/swarm-session-integration.test.ts +148 -91
  416. package/src/__tests__/swarm-tool.test.ts +65 -45
  417. package/src/__tests__/swarm-worker-backend.test.ts +59 -45
  418. package/src/__tests__/swarm-worker-runner.test.ts +133 -118
  419. package/src/__tests__/system-prompt.test.ts +290 -256
  420. package/src/__tests__/task-compiler.test.ts +176 -120
  421. package/src/__tests__/task-management-tools.test.ts +561 -456
  422. package/src/__tests__/task-memory-cleanup.test.ts +627 -362
  423. package/src/__tests__/task-runner.test.ts +117 -94
  424. package/src/__tests__/task-scheduler.test.ts +113 -84
  425. package/src/__tests__/task-tools.test.ts +349 -264
  426. package/src/__tests__/terminal-sandbox.test.ts +138 -108
  427. package/src/__tests__/terminal-tools.test.ts +350 -305
  428. package/src/__tests__/thread-seed-composer.test.ts +307 -180
  429. package/src/__tests__/tool-approval-handler.test.ts +238 -137
  430. package/src/__tests__/tool-audit-listener.test.ts +69 -69
  431. package/src/__tests__/tool-domain-event-publisher.test.ts +142 -132
  432. package/src/__tests__/tool-execution-abort-cleanup.test.ts +153 -146
  433. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +136 -105
  434. package/src/__tests__/tool-executor-lifecycle-events.test.ts +355 -239
  435. package/src/__tests__/tool-executor-redaction.test.ts +112 -109
  436. package/src/__tests__/tool-executor-shell-integration.test.ts +130 -79
  437. package/src/__tests__/tool-executor.test.ts +1274 -674
  438. package/src/__tests__/tool-grant-request-escalation.test.ts +401 -283
  439. package/src/__tests__/tool-metrics-listener.test.ts +97 -85
  440. package/src/__tests__/tool-notification-listener.test.ts +42 -25
  441. package/src/__tests__/tool-permission-simulate-handler.test.ts +137 -113
  442. package/src/__tests__/tool-policy.test.ts +44 -25
  443. package/src/__tests__/tool-profiling-listener.test.ts +99 -93
  444. package/src/__tests__/tool-result-truncation.test.ts +5 -4
  445. package/src/__tests__/tool-trace-listener.test.ts +131 -111
  446. package/src/__tests__/top-level-renderer.test.ts +62 -58
  447. package/src/__tests__/top-level-scanner.test.ts +68 -64
  448. package/src/__tests__/trace-emitter.test.ts +56 -56
  449. package/src/__tests__/trust-context-guards.test.ts +65 -65
  450. package/src/__tests__/trust-store.test.ts +1239 -806
  451. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  452. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  453. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +3 -2
  454. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -2
  455. package/src/__tests__/trusted-contact-verification.test.ts +251 -231
  456. package/src/__tests__/turn-commit.test.ts +259 -200
  457. package/src/__tests__/twilio-provider.test.ts +140 -126
  458. package/src/__tests__/twilio-rest.test.ts +22 -18
  459. package/src/__tests__/twilio-routes-elevenlabs.test.ts +0 -1
  460. package/src/__tests__/twilio-routes-twiml.test.ts +55 -55
  461. package/src/__tests__/twilio-routes.test.ts +0 -1
  462. package/src/__tests__/twitter-auth-handler.test.ts +184 -139
  463. package/src/__tests__/twitter-cli-error-shaping.test.ts +88 -73
  464. package/src/__tests__/twitter-cli-routing.test.ts +146 -99
  465. package/src/__tests__/twitter-oauth-client.test.ts +82 -65
  466. package/src/__tests__/update-bulletin-format.test.ts +69 -66
  467. package/src/__tests__/update-bulletin-state.test.ts +66 -60
  468. package/src/__tests__/update-bulletin.test.ts +150 -114
  469. package/src/__tests__/update-template-contract.test.ts +15 -10
  470. package/src/__tests__/url-safety.test.ts +288 -265
  471. package/src/__tests__/user-reference.test.ts +32 -32
  472. package/src/__tests__/view-image-tool.test.ts +118 -96
  473. package/src/__tests__/voice-invite-redemption.test.ts +111 -106
  474. package/src/__tests__/voice-quality.test.ts +117 -102
  475. package/src/__tests__/voice-scoped-grant-consumer.test.ts +204 -146
  476. package/src/__tests__/voice-session-bridge.test.ts +351 -216
  477. package/src/__tests__/weather-skill-regression.test.ts +170 -120
  478. package/src/__tests__/web-fetch.test.ts +664 -526
  479. package/src/__tests__/web-search.test.ts +379 -213
  480. package/src/__tests__/work-item-output.test.ts +90 -53
  481. package/src/__tests__/workspace-git-service.test.ts +437 -356
  482. package/src/__tests__/workspace-heartbeat-service.test.ts +125 -91
  483. package/src/__tests__/workspace-lifecycle.test.ts +98 -64
  484. package/src/__tests__/workspace-policy.test.ts +139 -71
  485. package/src/commands/__tests__/cc-command-registry.test.ts +142 -134
  486. package/src/config/__tests__/feature-flag-registry-guard.test.ts +48 -39
  487. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +25 -10
  488. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +0 -1
  489. package/src/config/bundled-skills/messaging/SKILL.md +4 -3
  490. package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +15 -5
  491. package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +16 -5
  492. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +34 -32
  493. package/src/config/bundled-tool-registry.ts +2 -0
  494. package/src/config/env.ts +3 -4
  495. package/src/memory/db-connection.ts +16 -10
  496. package/src/messaging/providers/gmail/adapter.ts +10 -3
  497. package/src/messaging/providers/gmail/client.ts +280 -72
  498. package/src/runtime/auth/__tests__/context.test.ts +75 -65
  499. package/src/runtime/auth/__tests__/credential-service.test.ts +137 -114
  500. package/src/runtime/auth/__tests__/guard-tests.test.ts +84 -90
  501. package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +40 -40
  502. package/src/runtime/auth/__tests__/middleware.test.ts +80 -74
  503. package/src/runtime/auth/__tests__/policy.test.ts +9 -9
  504. package/src/runtime/auth/__tests__/route-policy.test.ts +76 -65
  505. package/src/runtime/auth/__tests__/scopes.test.ts +68 -60
  506. package/src/runtime/auth/__tests__/subject.test.ts +54 -54
  507. package/src/runtime/auth/__tests__/token-service.test.ts +115 -108
  508. package/src/runtime/auth/scopes.ts +3 -0
  509. package/src/runtime/auth/token-service.ts +4 -1
  510. package/src/runtime/auth/types.ts +2 -1
  511. package/src/runtime/http-server.ts +2 -1
  512. package/src/security/secure-keys.ts +103 -53
  513. package/src/tools/browser/__tests__/auth-cache.test.ts +69 -63
  514. package/src/tools/browser/__tests__/auth-detector.test.ts +218 -157
  515. package/src/tools/browser/__tests__/jit-auth.test.ts +83 -99
@@ -1,7 +1,7 @@
1
- import { describe, expect,test } from 'bun:test';
1
+ import { describe, expect, test } from "bun:test";
2
2
 
3
- import type { AppDefinition } from '../memory/app-store.js';
4
- import type { AppStore, ProxyResolver } from '../tools/apps/executors.js';
3
+ import type { AppDefinition } from "../memory/app-store.js";
4
+ import type { AppStore, ProxyResolver } from "../tools/apps/executors.js";
5
5
  import {
6
6
  executeAppCreate,
7
7
  executeAppDelete,
@@ -12,8 +12,8 @@ import {
12
12
  executeAppList,
13
13
  executeAppQuery,
14
14
  executeAppUpdate,
15
- } from '../tools/apps/executors.js';
16
- import type { EditEngineResult } from '../tools/shared/filesystem/edit-engine.js';
15
+ } from "../tools/apps/executors.js";
16
+ import type { EditEngineResult } from "../tools/shared/filesystem/edit-engine.js";
17
17
 
18
18
  // ---------------------------------------------------------------------------
19
19
  // Mock factory
@@ -21,11 +21,11 @@ import type { EditEngineResult } from '../tools/shared/filesystem/edit-engine.js
21
21
 
22
22
  function makeApp(overrides: Partial<AppDefinition> = {}): AppDefinition {
23
23
  return {
24
- id: 'app-1',
25
- name: 'Test App',
26
- description: 'A test app',
27
- schemaJson: '{}',
28
- htmlDefinition: '<h1>Hi</h1>',
24
+ id: "app-1",
25
+ name: "Test App",
26
+ description: "A test app",
27
+ schemaJson: "{}",
28
+ htmlDefinition: "<h1>Hi</h1>",
29
29
  createdAt: 1000,
30
30
  updatedAt: 2000,
31
31
  ...overrides,
@@ -37,15 +37,23 @@ function makeMockStore(overrides: Partial<AppStore> = {}): AppStore {
37
37
  getApp: () => makeApp(),
38
38
  listApps: () => [makeApp()],
39
39
  queryAppRecords: () => [],
40
- listAppFiles: () => ['index.html'],
41
- readAppFile: () => '<h1>Hi</h1>',
40
+ listAppFiles: () => ["index.html"],
41
+ readAppFile: () => "<h1>Hi</h1>",
42
42
  createApp: (params) =>
43
43
  makeApp({ name: params.name, description: params.description }),
44
44
  updateApp: (id, updates) => makeApp({ id, ...updates }),
45
45
  deleteApp: () => {},
46
46
  writeAppFile: () => {},
47
47
  editAppFile: () =>
48
- ({ ok: true, updatedContent: 'new', matchCount: 1, matchMethod: 'exact', similarity: 1, actualOld: 'old', actualNew: 'new' }) as EditEngineResult,
48
+ ({
49
+ ok: true,
50
+ updatedContent: "new",
51
+ matchCount: 1,
52
+ matchMethod: "exact",
53
+ similarity: 1,
54
+ actualOld: "old",
55
+ actualNew: "new",
56
+ }) as EditEngineResult,
49
57
  ...overrides,
50
58
  };
51
59
  }
@@ -54,16 +62,16 @@ function makeMockStore(overrides: Partial<AppStore> = {}): AppStore {
54
62
  // app_create
55
63
  // ---------------------------------------------------------------------------
56
64
 
57
- describe('executeAppCreate', () => {
58
- test('creates an app and returns its definition', async () => {
65
+ describe("executeAppCreate", () => {
66
+ test("creates an app and returns its definition", async () => {
59
67
  const store = makeMockStore();
60
68
  const result = await executeAppCreate(
61
- { name: 'My App', html: '<p>Hello</p>' },
69
+ { name: "My App", html: "<p>Hello</p>" },
62
70
  store,
63
71
  );
64
72
  expect(result.isError).toBe(false);
65
73
  const parsed = JSON.parse(result.content);
66
- expect(parsed.name).toBe('My App');
74
+ expect(parsed.name).toBe("My App");
67
75
  });
68
76
 
69
77
  test('defaults schema_json to "{}" when not provided', async () => {
@@ -74,11 +82,11 @@ describe('executeAppCreate', () => {
74
82
  return makeApp({ name: params.name });
75
83
  },
76
84
  });
77
- await executeAppCreate({ name: 'App', html: '<p/>' }, store);
78
- expect(capturedSchema).toBe('{}');
85
+ await executeAppCreate({ name: "App", html: "<p/>" }, store);
86
+ expect(capturedSchema).toBe("{}");
79
87
  });
80
88
 
81
- test('passes schema_json through when provided', async () => {
89
+ test("passes schema_json through when provided", async () => {
82
90
  let capturedSchema: string | undefined;
83
91
  const store = makeMockStore({
84
92
  createApp: (params) => {
@@ -87,36 +95,36 @@ describe('executeAppCreate', () => {
87
95
  },
88
96
  });
89
97
  await executeAppCreate(
90
- { name: 'App', html: '<p/>', schema_json: '{"type":"object"}' },
98
+ { name: "App", html: "<p/>", schema_json: '{"type":"object"}' },
91
99
  store,
92
100
  );
93
101
  expect(capturedSchema).toBe('{"type":"object"}');
94
102
  });
95
103
 
96
- test('auto-opens the app when proxyToolResolver is provided', async () => {
104
+ test("auto-opens the app when proxyToolResolver is provided", async () => {
97
105
  const store = makeMockStore();
98
106
  const proxy: ProxyResolver = async () => ({
99
- content: 'opened',
107
+ content: "opened",
100
108
  isError: false,
101
109
  });
102
110
  const result = await executeAppCreate(
103
- { name: 'Auto', html: '<p/>' },
111
+ { name: "Auto", html: "<p/>" },
104
112
  store,
105
113
  proxy,
106
114
  );
107
115
  expect(result.isError).toBe(false);
108
116
  const parsed = JSON.parse(result.content);
109
117
  expect(parsed.auto_opened).toBe(true);
110
- expect(parsed.open_result).toBe('opened');
118
+ expect(parsed.open_result).toBe("opened");
111
119
  });
112
120
 
113
- test('returns auto_opened=false when proxy resolver throws', async () => {
121
+ test("returns auto_opened=false when proxy resolver throws", async () => {
114
122
  const store = makeMockStore();
115
123
  const proxy: ProxyResolver = async () => {
116
- throw new Error('no client');
124
+ throw new Error("no client");
117
125
  };
118
126
  const result = await executeAppCreate(
119
- { name: 'Fail Open', html: '<p/>' },
127
+ { name: "Fail Open", html: "<p/>" },
120
128
  store,
121
129
  proxy,
122
130
  );
@@ -124,19 +132,19 @@ describe('executeAppCreate', () => {
124
132
  const parsed = JSON.parse(result.content);
125
133
  expect(parsed.auto_opened).toBe(false);
126
134
  expect(parsed.auto_open_error).toBe(
127
- 'Failed to auto-open app. Use app_open to open it manually.',
135
+ "Failed to auto-open app. Use app_open to open it manually.",
128
136
  );
129
137
  });
130
138
 
131
- test('skips auto-open when auto_open is false', async () => {
139
+ test("skips auto-open when auto_open is false", async () => {
132
140
  let proxyCalled = false;
133
141
  const store = makeMockStore();
134
142
  const proxy: ProxyResolver = async () => {
135
143
  proxyCalled = true;
136
- return { content: 'opened', isError: false };
144
+ return { content: "opened", isError: false };
137
145
  };
138
146
  const result = await executeAppCreate(
139
- { name: 'No Open', html: '<p/>', auto_open: false },
147
+ { name: "No Open", html: "<p/>", auto_open: false },
140
148
  store,
141
149
  proxy,
142
150
  );
@@ -146,10 +154,10 @@ describe('executeAppCreate', () => {
146
154
  expect(parsed.auto_opened).toBeUndefined();
147
155
  });
148
156
 
149
- test('skips auto-open when no proxyToolResolver', async () => {
157
+ test("skips auto-open when no proxyToolResolver", async () => {
150
158
  const store = makeMockStore();
151
159
  const result = await executeAppCreate(
152
- { name: 'No Proxy', html: '<p/>' },
160
+ { name: "No Proxy", html: "<p/>" },
153
161
  store,
154
162
  );
155
163
  expect(result.isError).toBe(false);
@@ -157,7 +165,7 @@ describe('executeAppCreate', () => {
157
165
  expect(parsed.auto_opened).toBeUndefined();
158
166
  });
159
167
 
160
- test('passes pages through to store.createApp', async () => {
168
+ test("passes pages through to store.createApp", async () => {
161
169
  let capturedPages: Record<string, string> | undefined;
162
170
  const store = makeMockStore({
163
171
  createApp: (params) => {
@@ -166,37 +174,34 @@ describe('executeAppCreate', () => {
166
174
  },
167
175
  });
168
176
  await executeAppCreate(
169
- { name: 'Multi', html: '<p/>', pages: { 'settings.html': '<div/>' } },
177
+ { name: "Multi", html: "<p/>", pages: { "settings.html": "<div/>" } },
170
178
  store,
171
179
  );
172
- expect(capturedPages).toEqual({ 'settings.html': '<div/>' });
180
+ expect(capturedPages).toEqual({ "settings.html": "<div/>" });
173
181
  });
174
182
 
175
183
  test('maps type "site" to appType "site"', async () => {
176
- let capturedType: 'app' | 'site' | undefined;
184
+ let capturedType: "app" | "site" | undefined;
177
185
  const store = makeMockStore({
178
186
  createApp: (params) => {
179
187
  capturedType = params.appType;
180
188
  return makeApp({ name: params.name });
181
189
  },
182
190
  });
183
- await executeAppCreate(
184
- { name: 'Site', html: '<p/>', type: 'site' },
185
- store,
186
- );
187
- expect(capturedType).toBe('site');
191
+ await executeAppCreate({ name: "Site", html: "<p/>", type: "site" }, store);
192
+ expect(capturedType).toBe("site");
188
193
  });
189
194
 
190
195
  test('defaults appType to "app" when type is not "site"', async () => {
191
- let capturedType: 'app' | 'site' | undefined;
196
+ let capturedType: "app" | "site" | undefined;
192
197
  const store = makeMockStore({
193
198
  createApp: (params) => {
194
199
  capturedType = params.appType;
195
200
  return makeApp({ name: params.name });
196
201
  },
197
202
  });
198
- await executeAppCreate({ name: 'App', html: '<p/>' }, store);
199
- expect(capturedType).toBe('app');
203
+ await executeAppCreate({ name: "App", html: "<p/>" }, store);
204
+ expect(capturedType).toBe("app");
200
205
  });
201
206
  });
202
207
 
@@ -204,26 +209,36 @@ describe('executeAppCreate', () => {
204
209
  // app_list
205
210
  // ---------------------------------------------------------------------------
206
211
 
207
- describe('executeAppList', () => {
208
- test('returns mapped list of apps', () => {
212
+ describe("executeAppList", () => {
213
+ test("returns mapped list of apps", () => {
209
214
  const store = makeMockStore({
210
215
  listApps: () => [
211
- makeApp({ id: 'a1', name: 'First', description: 'desc1', updatedAt: 100 }),
212
- makeApp({ id: 'a2', name: 'Second', updatedAt: 200 }),
216
+ makeApp({
217
+ id: "a1",
218
+ name: "First",
219
+ description: "desc1",
220
+ updatedAt: 100,
221
+ }),
222
+ makeApp({ id: "a2", name: "Second", updatedAt: 200 }),
213
223
  ],
214
224
  });
215
225
  const result = executeAppList(store);
216
226
  expect(result.isError).toBe(false);
217
227
  const parsed = JSON.parse(result.content);
218
228
  expect(parsed).toHaveLength(2);
219
- expect(parsed[0]).toEqual({ id: 'a1', name: 'First', description: 'desc1', updatedAt: 100 });
220
- expect(parsed[1].id).toBe('a2');
229
+ expect(parsed[0]).toEqual({
230
+ id: "a1",
231
+ name: "First",
232
+ description: "desc1",
233
+ updatedAt: 100,
234
+ });
235
+ expect(parsed[1].id).toBe("a2");
221
236
  // Should not include htmlDefinition or schemaJson
222
237
  expect(parsed[0].htmlDefinition).toBeUndefined();
223
238
  expect(parsed[0].schemaJson).toBeUndefined();
224
239
  });
225
240
 
226
- test('returns empty array when no apps exist', () => {
241
+ test("returns empty array when no apps exist", () => {
227
242
  const store = makeMockStore({ listApps: () => [] });
228
243
  const result = executeAppList(store);
229
244
  expect(result.isError).toBe(false);
@@ -235,18 +250,18 @@ describe('executeAppList', () => {
235
250
  // app_query
236
251
  // ---------------------------------------------------------------------------
237
252
 
238
- describe('executeAppQuery', () => {
239
- test('returns records for a given app', () => {
240
- const records = [{ id: 'r1', appId: 'app-1', data: { x: 1 } }];
253
+ describe("executeAppQuery", () => {
254
+ test("returns records for a given app", () => {
255
+ const records = [{ id: "r1", appId: "app-1", data: { x: 1 } }];
241
256
  const store = makeMockStore({ queryAppRecords: () => records });
242
- const result = executeAppQuery({ app_id: 'app-1' }, store);
257
+ const result = executeAppQuery({ app_id: "app-1" }, store);
243
258
  expect(result.isError).toBe(false);
244
259
  expect(JSON.parse(result.content)).toEqual(records);
245
260
  });
246
261
 
247
- test('returns empty array when no records', () => {
262
+ test("returns empty array when no records", () => {
248
263
  const store = makeMockStore({ queryAppRecords: () => [] });
249
- const result = executeAppQuery({ app_id: 'app-1' }, store);
264
+ const result = executeAppQuery({ app_id: "app-1" }, store);
250
265
  expect(result.isError).toBe(false);
251
266
  expect(JSON.parse(result.content)).toEqual([]);
252
267
  });
@@ -256,8 +271,8 @@ describe('executeAppQuery', () => {
256
271
  // app_update
257
272
  // ---------------------------------------------------------------------------
258
273
 
259
- describe('executeAppUpdate', () => {
260
- test('passes update fields through to store', () => {
274
+ describe("executeAppUpdate", () => {
275
+ test("passes update fields through to store", () => {
261
276
  let capturedUpdates: Record<string, unknown> = {};
262
277
  const store = makeMockStore({
263
278
  updateApp: (_id, updates) => {
@@ -267,26 +282,26 @@ describe('executeAppUpdate', () => {
267
282
  });
268
283
  const result = executeAppUpdate(
269
284
  {
270
- app_id: 'app-1',
271
- name: 'New Name',
272
- description: 'New desc',
285
+ app_id: "app-1",
286
+ name: "New Name",
287
+ description: "New desc",
273
288
  schema_json: '{"a":1}',
274
- html: '<div/>',
275
- pages: { 'about.html': '<p/>' },
289
+ html: "<div/>",
290
+ pages: { "about.html": "<p/>" },
276
291
  },
277
292
  store,
278
293
  );
279
294
  expect(result.isError).toBe(false);
280
295
  expect(capturedUpdates).toEqual({
281
- name: 'New Name',
282
- description: 'New desc',
296
+ name: "New Name",
297
+ description: "New desc",
283
298
  schemaJson: '{"a":1}',
284
- htmlDefinition: '<div/>',
285
- pages: { 'about.html': '<p/>' },
299
+ htmlDefinition: "<div/>",
300
+ pages: { "about.html": "<p/>" },
286
301
  });
287
302
  });
288
303
 
289
- test('only includes provided fields in updates', () => {
304
+ test("only includes provided fields in updates", () => {
290
305
  let capturedUpdates: Record<string, unknown> = {};
291
306
  const store = makeMockStore({
292
307
  updateApp: (_id, updates) => {
@@ -294,23 +309,23 @@ describe('executeAppUpdate', () => {
294
309
  return makeApp({ id: _id, ...updates });
295
310
  },
296
311
  });
297
- executeAppUpdate({ app_id: 'app-1', name: 'Only Name' }, store);
298
- expect(capturedUpdates).toEqual({ name: 'Only Name' });
312
+ executeAppUpdate({ app_id: "app-1", name: "Only Name" }, store);
313
+ expect(capturedUpdates).toEqual({ name: "Only Name" });
299
314
  // html, description, schema_json, pages should NOT be in the updates
300
- expect('htmlDefinition' in capturedUpdates).toBe(false);
301
- expect('description' in capturedUpdates).toBe(false);
302
- expect('schemaJson' in capturedUpdates).toBe(false);
303
- expect('pages' in capturedUpdates).toBe(false);
315
+ expect("htmlDefinition" in capturedUpdates).toBe(false);
316
+ expect("description" in capturedUpdates).toBe(false);
317
+ expect("schemaJson" in capturedUpdates).toBe(false);
318
+ expect("pages" in capturedUpdates).toBe(false);
304
319
  });
305
320
 
306
- test('propagates store errors', () => {
321
+ test("propagates store errors", () => {
307
322
  const store = makeMockStore({
308
323
  updateApp: () => {
309
- throw new Error('App not found: bad-id');
324
+ throw new Error("App not found: bad-id");
310
325
  },
311
326
  });
312
- expect(() => executeAppUpdate({ app_id: 'bad-id' }, store)).toThrow(
313
- 'App not found: bad-id',
327
+ expect(() => executeAppUpdate({ app_id: "bad-id" }, store)).toThrow(
328
+ "App not found: bad-id",
314
329
  );
315
330
  });
316
331
  });
@@ -319,18 +334,21 @@ describe('executeAppUpdate', () => {
319
334
  // app_delete
320
335
  // ---------------------------------------------------------------------------
321
336
 
322
- describe('executeAppDelete', () => {
323
- test('deletes the app and returns confirmation', () => {
337
+ describe("executeAppDelete", () => {
338
+ test("deletes the app and returns confirmation", () => {
324
339
  let deletedId: string | undefined;
325
340
  const store = makeMockStore({
326
341
  deleteApp: (id) => {
327
342
  deletedId = id;
328
343
  },
329
344
  });
330
- const result = executeAppDelete({ app_id: 'app-1' }, store);
345
+ const result = executeAppDelete({ app_id: "app-1" }, store);
331
346
  expect(result.isError).toBe(false);
332
- expect(JSON.parse(result.content)).toEqual({ deleted: true, appId: 'app-1' });
333
- expect(deletedId).toBe('app-1');
347
+ expect(JSON.parse(result.content)).toEqual({
348
+ deleted: true,
349
+ appId: "app-1",
350
+ });
351
+ expect(deletedId).toBe("app-1");
334
352
  });
335
353
  });
336
354
 
@@ -338,23 +356,23 @@ describe('executeAppDelete', () => {
338
356
  // app_file_list
339
357
  // ---------------------------------------------------------------------------
340
358
 
341
- describe('executeAppFileList', () => {
342
- test('returns list of files', () => {
359
+ describe("executeAppFileList", () => {
360
+ test("returns list of files", () => {
343
361
  const store = makeMockStore({
344
- listAppFiles: () => ['index.html', 'styles.css', 'js/app.js'],
362
+ listAppFiles: () => ["index.html", "styles.css", "js/app.js"],
345
363
  });
346
- const result = executeAppFileList({ app_id: 'app-1' }, store);
364
+ const result = executeAppFileList({ app_id: "app-1" }, store);
347
365
  expect(result.isError).toBe(false);
348
366
  expect(JSON.parse(result.content)).toEqual([
349
- 'index.html',
350
- 'styles.css',
351
- 'js/app.js',
367
+ "index.html",
368
+ "styles.css",
369
+ "js/app.js",
352
370
  ]);
353
371
  });
354
372
 
355
- test('returns empty array when app has no files', () => {
373
+ test("returns empty array when app has no files", () => {
356
374
  const store = makeMockStore({ listAppFiles: () => [] });
357
- const result = executeAppFileList({ app_id: 'app-1' }, store);
375
+ const result = executeAppFileList({ app_id: "app-1" }, store);
358
376
  expect(result.isError).toBe(false);
359
377
  expect(JSON.parse(result.content)).toEqual([]);
360
378
  });
@@ -364,80 +382,76 @@ describe('executeAppFileList', () => {
364
382
  // app_file_read
365
383
  // ---------------------------------------------------------------------------
366
384
 
367
- describe('executeAppFileRead', () => {
368
- test('returns formatted content with line numbers', () => {
385
+ describe("executeAppFileRead", () => {
386
+ test("returns formatted content with line numbers", () => {
369
387
  const store = makeMockStore({
370
- readAppFile: () => 'line1\nline2\nline3',
388
+ readAppFile: () => "line1\nline2\nline3",
371
389
  });
372
390
  const result = executeAppFileRead(
373
- { app_id: 'app-1', path: 'index.html' },
391
+ { app_id: "app-1", path: "index.html" },
374
392
  store,
375
393
  );
376
394
  expect(result.isError).toBe(false);
377
- expect(result.content).toBe(
378
- ' 1\tline1\n 2\tline2\n 3\tline3',
379
- );
395
+ expect(result.content).toBe(" 1\tline1\n 2\tline2\n 3\tline3");
380
396
  });
381
397
 
382
- test('applies offset parameter (1-based)', () => {
398
+ test("applies offset parameter (1-based)", () => {
383
399
  const store = makeMockStore({
384
- readAppFile: () => 'a\nb\nc\nd\ne',
400
+ readAppFile: () => "a\nb\nc\nd\ne",
385
401
  });
386
402
  const result = executeAppFileRead(
387
- { app_id: 'app-1', path: 'f.txt', offset: 3 },
403
+ { app_id: "app-1", path: "f.txt", offset: 3 },
388
404
  store,
389
405
  );
390
406
  expect(result.isError).toBe(false);
391
407
  // Lines 3, 4, 5
392
- expect(result.content).toBe(
393
- ' 3\tc\n 4\td\n 5\te',
394
- );
408
+ expect(result.content).toBe(" 3\tc\n 4\td\n 5\te");
395
409
  });
396
410
 
397
- test('applies limit parameter', () => {
411
+ test("applies limit parameter", () => {
398
412
  const store = makeMockStore({
399
- readAppFile: () => 'a\nb\nc\nd\ne',
413
+ readAppFile: () => "a\nb\nc\nd\ne",
400
414
  });
401
415
  const result = executeAppFileRead(
402
- { app_id: 'app-1', path: 'f.txt', limit: 2 },
416
+ { app_id: "app-1", path: "f.txt", limit: 2 },
403
417
  store,
404
418
  );
405
419
  expect(result.isError).toBe(false);
406
- expect(result.content).toBe(' 1\ta\n 2\tb');
420
+ expect(result.content).toBe(" 1\ta\n 2\tb");
407
421
  });
408
422
 
409
- test('applies both offset and limit', () => {
423
+ test("applies both offset and limit", () => {
410
424
  const store = makeMockStore({
411
- readAppFile: () => 'a\nb\nc\nd\ne',
425
+ readAppFile: () => "a\nb\nc\nd\ne",
412
426
  });
413
427
  const result = executeAppFileRead(
414
- { app_id: 'app-1', path: 'f.txt', offset: 2, limit: 2 },
428
+ { app_id: "app-1", path: "f.txt", offset: 2, limit: 2 },
415
429
  store,
416
430
  );
417
431
  expect(result.isError).toBe(false);
418
- expect(result.content).toBe(' 2\tb\n 3\tc');
432
+ expect(result.content).toBe(" 2\tb\n 3\tc");
419
433
  });
420
434
 
421
- test('defaults offset to 1 when not provided', () => {
435
+ test("defaults offset to 1 when not provided", () => {
422
436
  const store = makeMockStore({
423
- readAppFile: () => 'only',
437
+ readAppFile: () => "only",
424
438
  });
425
439
  const result = executeAppFileRead(
426
- { app_id: 'app-1', path: 'f.txt' },
440
+ { app_id: "app-1", path: "f.txt" },
427
441
  store,
428
442
  );
429
- expect(result.content).toBe(' 1\tonly');
443
+ expect(result.content).toBe(" 1\tonly");
430
444
  });
431
445
 
432
- test('propagates store errors (e.g. file not found)', () => {
446
+ test("propagates store errors (e.g. file not found)", () => {
433
447
  const store = makeMockStore({
434
448
  readAppFile: () => {
435
- throw new Error('File not found: missing.txt');
449
+ throw new Error("File not found: missing.txt");
436
450
  },
437
451
  });
438
452
  expect(() =>
439
- executeAppFileRead({ app_id: 'app-1', path: 'missing.txt' }, store),
440
- ).toThrow('File not found: missing.txt');
453
+ executeAppFileRead({ app_id: "app-1", path: "missing.txt" }, store),
454
+ ).toThrow("File not found: missing.txt");
441
455
  });
442
456
  });
443
457
 
@@ -445,24 +459,24 @@ describe('executeAppFileRead', () => {
445
459
  // app_file_edit
446
460
  // ---------------------------------------------------------------------------
447
461
 
448
- describe('executeAppFileEdit', () => {
449
- test('returns edit result from store', () => {
462
+ describe("executeAppFileEdit", () => {
463
+ test("returns edit result from store", () => {
450
464
  const editResult: EditEngineResult = {
451
465
  ok: true,
452
- updatedContent: 'updated',
466
+ updatedContent: "updated",
453
467
  matchCount: 1,
454
- matchMethod: 'exact' as const,
468
+ matchMethod: "exact" as const,
455
469
  similarity: 1,
456
- actualOld: 'old',
457
- actualNew: 'new',
470
+ actualOld: "old",
471
+ actualNew: "new",
458
472
  };
459
473
  const store = makeMockStore({ editAppFile: () => editResult });
460
474
  const result = executeAppFileEdit(
461
475
  {
462
- app_id: 'app-1',
463
- path: 'index.html',
464
- old_string: 'old',
465
- new_string: 'new',
476
+ app_id: "app-1",
477
+ path: "index.html",
478
+ old_string: "old",
479
+ new_string: "new",
466
480
  },
467
481
  store,
468
482
  );
@@ -470,37 +484,45 @@ describe('executeAppFileEdit', () => {
470
484
  expect(JSON.parse(result.content)).toEqual(editResult);
471
485
  });
472
486
 
473
- test('returns error when old_string is empty', () => {
487
+ test("returns error when old_string is empty", () => {
474
488
  const store = makeMockStore();
475
489
  const result = executeAppFileEdit(
476
490
  {
477
- app_id: 'app-1',
478
- path: 'index.html',
479
- old_string: '',
480
- new_string: 'new',
491
+ app_id: "app-1",
492
+ path: "index.html",
493
+ old_string: "",
494
+ new_string: "new",
481
495
  },
482
496
  store,
483
497
  );
484
498
  expect(result.isError).toBe(true);
485
499
  expect(JSON.parse(result.content)).toEqual({
486
- error: 'old_string must not be empty',
500
+ error: "old_string must not be empty",
487
501
  });
488
502
  });
489
503
 
490
- test('passes replace_all through to store', () => {
504
+ test("passes replace_all through to store", () => {
491
505
  let capturedReplaceAll: boolean | undefined;
492
506
  const store = makeMockStore({
493
507
  editAppFile: (_appId, _path, _old, _new, replaceAll) => {
494
508
  capturedReplaceAll = replaceAll;
495
- return { ok: true, updatedContent: '', matchCount: 1, matchMethod: 'exact' as const, similarity: 1, actualOld: '', actualNew: '' };
509
+ return {
510
+ ok: true,
511
+ updatedContent: "",
512
+ matchCount: 1,
513
+ matchMethod: "exact" as const,
514
+ similarity: 1,
515
+ actualOld: "",
516
+ actualNew: "",
517
+ };
496
518
  },
497
519
  });
498
520
  executeAppFileEdit(
499
521
  {
500
- app_id: 'app-1',
501
- path: 'f.txt',
502
- old_string: 'x',
503
- new_string: 'y',
522
+ app_id: "app-1",
523
+ path: "f.txt",
524
+ old_string: "x",
525
+ new_string: "y",
504
526
  replace_all: true,
505
527
  },
506
528
  store,
@@ -508,39 +530,47 @@ describe('executeAppFileEdit', () => {
508
530
  expect(capturedReplaceAll).toBe(true);
509
531
  });
510
532
 
511
- test('defaults replace_all to false', () => {
533
+ test("defaults replace_all to false", () => {
512
534
  let capturedReplaceAll: boolean | undefined;
513
535
  const store = makeMockStore({
514
536
  editAppFile: (_appId, _path, _old, _new, replaceAll) => {
515
537
  capturedReplaceAll = replaceAll;
516
- return { ok: true, updatedContent: '', matchCount: 1, matchMethod: 'exact' as const, similarity: 1, actualOld: '', actualNew: '' };
538
+ return {
539
+ ok: true,
540
+ updatedContent: "",
541
+ matchCount: 1,
542
+ matchMethod: "exact" as const,
543
+ similarity: 1,
544
+ actualOld: "",
545
+ actualNew: "",
546
+ };
517
547
  },
518
548
  });
519
549
  executeAppFileEdit(
520
550
  {
521
- app_id: 'app-1',
522
- path: 'f.txt',
523
- old_string: 'x',
524
- new_string: 'y',
551
+ app_id: "app-1",
552
+ path: "f.txt",
553
+ old_string: "x",
554
+ new_string: "y",
525
555
  },
526
556
  store,
527
557
  );
528
558
  expect(capturedReplaceAll).toBe(false);
529
559
  });
530
560
 
531
- test('passes status through to result', () => {
561
+ test("passes status through to result", () => {
532
562
  const store = makeMockStore();
533
563
  const result = executeAppFileEdit(
534
564
  {
535
- app_id: 'app-1',
536
- path: 'f.txt',
537
- old_string: 'x',
538
- new_string: 'y',
539
- status: 'updating styles',
565
+ app_id: "app-1",
566
+ path: "f.txt",
567
+ old_string: "x",
568
+ new_string: "y",
569
+ status: "updating styles",
540
570
  },
541
571
  store,
542
572
  );
543
- expect(result.status).toBe('updating styles');
573
+ expect(result.status).toBe("updating styles");
544
574
  });
545
575
  });
546
576
 
@@ -548,8 +578,8 @@ describe('executeAppFileEdit', () => {
548
578
  // app_file_write
549
579
  // ---------------------------------------------------------------------------
550
580
 
551
- describe('executeAppFileWrite', () => {
552
- test('writes file and returns confirmation', () => {
581
+ describe("executeAppFileWrite", () => {
582
+ test("writes file and returns confirmation", () => {
553
583
  let writtenPath: string | undefined;
554
584
  let writtenContent: string | undefined;
555
585
  const store = makeMockStore({
@@ -559,22 +589,22 @@ describe('executeAppFileWrite', () => {
559
589
  },
560
590
  });
561
591
  const result = executeAppFileWrite(
562
- { app_id: 'app-1', path: 'new.html', content: '<div/>' },
592
+ { app_id: "app-1", path: "new.html", content: "<div/>" },
563
593
  store,
564
594
  );
565
595
  expect(result.isError).toBe(false);
566
596
  expect(JSON.parse(result.content)).toEqual({
567
597
  written: true,
568
- path: 'new.html',
598
+ path: "new.html",
569
599
  });
570
- expect(writtenPath).toBe('new.html');
571
- expect(writtenContent).toBe('<div/>');
600
+ expect(writtenPath).toBe("new.html");
601
+ expect(writtenContent).toBe("<div/>");
572
602
  });
573
603
 
574
- test('returns error when app is not found', () => {
604
+ test("returns error when app is not found", () => {
575
605
  const store = makeMockStore({ getApp: () => null });
576
606
  const result = executeAppFileWrite(
577
- { app_id: 'missing', path: 'f.txt', content: 'hi' },
607
+ { app_id: "missing", path: "f.txt", content: "hi" },
578
608
  store,
579
609
  );
580
610
  expect(result.isError).toBe(true);
@@ -583,21 +613,21 @@ describe('executeAppFileWrite', () => {
583
613
  });
584
614
  });
585
615
 
586
- test('passes status through to result', () => {
616
+ test("passes status through to result", () => {
587
617
  const store = makeMockStore();
588
618
  const result = executeAppFileWrite(
589
619
  {
590
- app_id: 'app-1',
591
- path: 'f.txt',
592
- content: 'hi',
593
- status: 'adding dark mode styles',
620
+ app_id: "app-1",
621
+ path: "f.txt",
622
+ content: "hi",
623
+ status: "adding dark mode styles",
594
624
  },
595
625
  store,
596
626
  );
597
- expect(result.status).toBe('adding dark mode styles');
627
+ expect(result.status).toBe("adding dark mode styles");
598
628
  });
599
629
 
600
- test('does not call writeAppFile when app not found', () => {
630
+ test("does not call writeAppFile when app not found", () => {
601
631
  let writeCalled = false;
602
632
  const store = makeMockStore({
603
633
  getApp: () => null,
@@ -605,10 +635,7 @@ describe('executeAppFileWrite', () => {
605
635
  writeCalled = true;
606
636
  },
607
637
  });
608
- executeAppFileWrite(
609
- { app_id: 'bad', path: 'f.txt', content: 'x' },
610
- store,
611
- );
638
+ executeAppFileWrite({ app_id: "bad", path: "f.txt", content: "x" }, store);
612
639
  expect(writeCalled).toBe(false);
613
640
  });
614
641
  });