@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,28 +1,29 @@
1
- import { mkdtempSync, rmSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
3
- import { join } from 'node:path';
1
+ import { mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
4
5
 
5
- import { afterAll, beforeEach, describe, expect, mock,test } from 'bun:test';
6
- import { eq } from 'drizzle-orm';
6
+ import { eq } from "drizzle-orm";
7
7
 
8
- const testDir = mkdtempSync(join(tmpdir(), 'conflict-store-test-'));
8
+ const testDir = mkdtempSync(join(tmpdir(), "conflict-store-test-"));
9
9
 
10
- mock.module('../util/platform.js', () => ({
10
+ mock.module("../util/platform.js", () => ({
11
11
  getDataDir: () => testDir,
12
- isMacOS: () => process.platform === 'darwin',
13
- isLinux: () => process.platform === 'linux',
14
- isWindows: () => process.platform === 'win32',
15
- getSocketPath: () => join(testDir, 'test.sock'),
16
- getPidPath: () => join(testDir, 'test.pid'),
17
- getDbPath: () => join(testDir, 'test.db'),
18
- getLogPath: () => join(testDir, 'test.log'),
12
+ isMacOS: () => process.platform === "darwin",
13
+ isLinux: () => process.platform === "linux",
14
+ isWindows: () => process.platform === "win32",
15
+ getSocketPath: () => join(testDir, "test.sock"),
16
+ getPidPath: () => join(testDir, "test.pid"),
17
+ getDbPath: () => join(testDir, "test.db"),
18
+ getLogPath: () => join(testDir, "test.log"),
19
19
  ensureDataDir: () => {},
20
20
  }));
21
21
 
22
- mock.module('../util/logger.js', () => ({
23
- getLogger: () => new Proxy({} as Record<string, unknown>, {
24
- get: () => () => {},
25
- }),
22
+ mock.module("../util/logger.js", () => ({
23
+ getLogger: () =>
24
+ new Proxy({} as Record<string, unknown>, {
25
+ get: () => () => {},
26
+ }),
26
27
  }));
27
28
 
28
29
  import {
@@ -34,183 +35,196 @@ import {
34
35
  listPendingConflicts,
35
36
  markConflictAsked,
36
37
  resolveConflict,
37
- } from '../memory/conflict-store.js';
38
- import { getDb, initializeDb, resetDb } from '../memory/db.js';
39
- import { memoryItems } from '../memory/schema.js';
38
+ } from "../memory/conflict-store.js";
39
+ import { getDb, initializeDb, resetDb } from "../memory/db.js";
40
+ import { memoryItems } from "../memory/schema.js";
40
41
 
41
42
  initializeDb();
42
43
 
43
44
  afterAll(() => {
44
45
  resetDb();
45
- try { rmSync(testDir, { recursive: true }); } catch { /* best effort */ }
46
+ try {
47
+ rmSync(testDir, { recursive: true });
48
+ } catch {
49
+ /* best effort */
50
+ }
46
51
  });
47
52
 
48
53
  function resetTables() {
49
54
  const db = getDb();
50
- db.run('DELETE FROM memory_item_conflicts');
51
- db.run('DELETE FROM memory_item_sources');
52
- db.run('DELETE FROM memory_items');
55
+ db.run("DELETE FROM memory_item_conflicts");
56
+ db.run("DELETE FROM memory_item_sources");
57
+ db.run("DELETE FROM memory_items");
53
58
  }
54
59
 
55
- function insertItemPair(suffix: string, scopeId = 'default'): { existingItemId: string; candidateItemId: string } {
60
+ function insertItemPair(
61
+ suffix: string,
62
+ scopeId = "default",
63
+ ): { existingItemId: string; candidateItemId: string } {
56
64
  const db = getDb();
57
65
  const now = Date.now();
58
66
  const existingItemId = `existing-${suffix}`;
59
67
  const candidateItemId = `candidate-${suffix}`;
60
- db.insert(memoryItems).values([
61
- {
62
- id: existingItemId,
63
- kind: 'fact',
64
- subject: 'framework preference',
65
- statement: `Existing statement ${suffix}`,
66
- status: 'active',
67
- confidence: 0.8,
68
- importance: 0.5,
69
- fingerprint: `fp-existing-${suffix}`,
70
- verificationState: 'assistant_inferred',
71
- scopeId,
72
- firstSeenAt: now,
73
- lastSeenAt: now,
74
- },
75
- {
76
- id: candidateItemId,
77
- kind: 'fact',
78
- subject: 'framework preference',
79
- statement: `Candidate statement ${suffix}`,
80
- status: 'pending_clarification',
81
- confidence: 0.8,
82
- importance: 0.5,
83
- fingerprint: `fp-candidate-${suffix}`,
84
- verificationState: 'assistant_inferred',
85
- scopeId,
86
- firstSeenAt: now,
87
- lastSeenAt: now,
88
- },
89
- ]).run();
68
+ db.insert(memoryItems)
69
+ .values([
70
+ {
71
+ id: existingItemId,
72
+ kind: "fact",
73
+ subject: "framework preference",
74
+ statement: `Existing statement ${suffix}`,
75
+ status: "active",
76
+ confidence: 0.8,
77
+ importance: 0.5,
78
+ fingerprint: `fp-existing-${suffix}`,
79
+ verificationState: "assistant_inferred",
80
+ scopeId,
81
+ firstSeenAt: now,
82
+ lastSeenAt: now,
83
+ },
84
+ {
85
+ id: candidateItemId,
86
+ kind: "fact",
87
+ subject: "framework preference",
88
+ statement: `Candidate statement ${suffix}`,
89
+ status: "pending_clarification",
90
+ confidence: 0.8,
91
+ importance: 0.5,
92
+ fingerprint: `fp-candidate-${suffix}`,
93
+ verificationState: "assistant_inferred",
94
+ scopeId,
95
+ firstSeenAt: now,
96
+ lastSeenAt: now,
97
+ },
98
+ ])
99
+ .run();
90
100
 
91
101
  return { existingItemId, candidateItemId };
92
102
  }
93
103
 
94
- describe('conflict-store', () => {
104
+ describe("conflict-store", () => {
95
105
  beforeEach(() => {
96
106
  resetTables();
97
107
  });
98
108
 
99
- test('creates and fetches a pending conflict', () => {
100
- const pair = insertItemPair('create');
109
+ test("creates and fetches a pending conflict", () => {
110
+ const pair = insertItemPair("create");
101
111
  const conflict = createOrUpdatePendingConflict({
102
- scopeId: 'default',
112
+ scopeId: "default",
103
113
  existingItemId: pair.existingItemId,
104
114
  candidateItemId: pair.candidateItemId,
105
- relationship: 'ambiguous_contradiction',
106
- clarificationQuestion: 'Do you prefer React or Vue?',
115
+ relationship: "ambiguous_contradiction",
116
+ clarificationQuestion: "Do you prefer React or Vue?",
107
117
  });
108
118
 
109
119
  expect(conflict.id).toBeDefined();
110
- expect(conflict.status).toBe('pending_clarification');
111
- expect(conflict.scopeId).toBe('default');
112
- expect(conflict.relationship).toBe('ambiguous_contradiction');
113
- expect(conflict.clarificationQuestion).toBe('Do you prefer React or Vue?');
114
-
115
- const byPair = getPendingConflictByPair('default', pair.existingItemId, pair.candidateItemId);
120
+ expect(conflict.status).toBe("pending_clarification");
121
+ expect(conflict.scopeId).toBe("default");
122
+ expect(conflict.relationship).toBe("ambiguous_contradiction");
123
+ expect(conflict.clarificationQuestion).toBe("Do you prefer React or Vue?");
124
+
125
+ const byPair = getPendingConflictByPair(
126
+ "default",
127
+ pair.existingItemId,
128
+ pair.candidateItemId,
129
+ );
116
130
  expect(byPair?.id).toBe(conflict.id);
117
131
  });
118
132
 
119
- test('deduplicates unresolved pair and updates fields in place', () => {
120
- const pair = insertItemPair('dedupe');
133
+ test("deduplicates unresolved pair and updates fields in place", () => {
134
+ const pair = insertItemPair("dedupe");
121
135
  const first = createOrUpdatePendingConflict({
122
- scopeId: 'default',
136
+ scopeId: "default",
123
137
  existingItemId: pair.existingItemId,
124
138
  candidateItemId: pair.candidateItemId,
125
- relationship: 'contradiction',
126
- clarificationQuestion: 'First question',
139
+ relationship: "contradiction",
140
+ clarificationQuestion: "First question",
127
141
  });
128
142
 
129
143
  const second = createOrUpdatePendingConflict({
130
- scopeId: 'default',
144
+ scopeId: "default",
131
145
  existingItemId: pair.existingItemId,
132
146
  candidateItemId: pair.candidateItemId,
133
- relationship: 'ambiguous_contradiction',
134
- clarificationQuestion: 'Second question',
147
+ relationship: "ambiguous_contradiction",
148
+ clarificationQuestion: "Second question",
135
149
  });
136
150
 
137
151
  expect(second.id).toBe(first.id);
138
- expect(second.relationship).toBe('ambiguous_contradiction');
139
- expect(second.clarificationQuestion).toBe('Second question');
140
- expect(listPendingConflicts('default')).toHaveLength(1);
152
+ expect(second.relationship).toBe("ambiguous_contradiction");
153
+ expect(second.clarificationQuestion).toBe("Second question");
154
+ expect(listPendingConflicts("default")).toHaveLength(1);
141
155
  });
142
156
 
143
- test('allows a new pending row for the same pair after resolution', () => {
144
- const pair = insertItemPair('reopen');
157
+ test("allows a new pending row for the same pair after resolution", () => {
158
+ const pair = insertItemPair("reopen");
145
159
  const first = createOrUpdatePendingConflict({
146
- scopeId: 'default',
160
+ scopeId: "default",
147
161
  existingItemId: pair.existingItemId,
148
162
  candidateItemId: pair.candidateItemId,
149
- relationship: 'ambiguous_contradiction',
163
+ relationship: "ambiguous_contradiction",
150
164
  });
151
165
 
152
166
  const resolved = resolveConflict(first.id, {
153
- status: 'resolved_keep_existing',
154
- resolutionNote: 'User confirmed existing statement is correct.',
167
+ status: "resolved_keep_existing",
168
+ resolutionNote: "User confirmed existing statement is correct.",
155
169
  });
156
- expect(resolved?.status).toBe('resolved_keep_existing');
157
- expect(typeof resolved?.resolvedAt).toBe('number');
170
+ expect(resolved?.status).toBe("resolved_keep_existing");
171
+ expect(typeof resolved?.resolvedAt).toBe("number");
158
172
 
159
173
  const reopened = createOrUpdatePendingConflict({
160
- scopeId: 'default',
174
+ scopeId: "default",
161
175
  existingItemId: pair.existingItemId,
162
176
  candidateItemId: pair.candidateItemId,
163
- relationship: 'ambiguous_contradiction',
164
- clarificationQuestion: 'Please confirm again',
177
+ relationship: "ambiguous_contradiction",
178
+ clarificationQuestion: "Please confirm again",
165
179
  });
166
180
 
167
181
  expect(reopened.id).not.toBe(first.id);
168
- expect(getConflictById(first.id)?.status).toBe('resolved_keep_existing');
169
- expect(listPendingConflicts('default')).toHaveLength(1);
182
+ expect(getConflictById(first.id)?.status).toBe("resolved_keep_existing");
183
+ expect(listPendingConflicts("default")).toHaveLength(1);
170
184
  });
171
185
 
172
- test('lists only pending conflicts for a scope', () => {
173
- const defaultA = insertItemPair('scope-a');
174
- const defaultB = insertItemPair('scope-b');
175
- const otherScope = insertItemPair('scope-other', 'workspace-b');
186
+ test("lists only pending conflicts for a scope", () => {
187
+ const defaultA = insertItemPair("scope-a");
188
+ const defaultB = insertItemPair("scope-b");
189
+ const otherScope = insertItemPair("scope-other", "workspace-b");
176
190
 
177
191
  const conflictA = createOrUpdatePendingConflict({
178
- scopeId: 'default',
192
+ scopeId: "default",
179
193
  existingItemId: defaultA.existingItemId,
180
194
  candidateItemId: defaultA.candidateItemId,
181
- relationship: 'ambiguous_contradiction',
195
+ relationship: "ambiguous_contradiction",
182
196
  });
183
197
  const conflictB = createOrUpdatePendingConflict({
184
- scopeId: 'default',
198
+ scopeId: "default",
185
199
  existingItemId: defaultB.existingItemId,
186
200
  candidateItemId: defaultB.candidateItemId,
187
- relationship: 'ambiguous_contradiction',
201
+ relationship: "ambiguous_contradiction",
188
202
  });
189
203
  createOrUpdatePendingConflict({
190
- scopeId: 'workspace-b',
204
+ scopeId: "workspace-b",
191
205
  existingItemId: otherScope.existingItemId,
192
206
  candidateItemId: otherScope.candidateItemId,
193
- relationship: 'ambiguous_contradiction',
207
+ relationship: "ambiguous_contradiction",
194
208
  });
195
209
 
196
210
  resolveConflict(conflictB.id, {
197
- status: 'dismissed',
198
- resolutionNote: 'Irrelevant to active context',
211
+ status: "dismissed",
212
+ resolutionNote: "Irrelevant to active context",
199
213
  });
200
214
 
201
- const pendingDefault = listPendingConflicts('default');
215
+ const pendingDefault = listPendingConflicts("default");
202
216
  expect(pendingDefault).toHaveLength(1);
203
217
  expect(pendingDefault[0].id).toBe(conflictA.id);
204
- expect(pendingDefault[0].status).toBe('pending_clarification');
218
+ expect(pendingDefault[0].status).toBe("pending_clarification");
205
219
  });
206
220
 
207
- test('markConflictAsked updates lastAskedAt', () => {
208
- const pair = insertItemPair('asked');
221
+ test("markConflictAsked updates lastAskedAt", () => {
222
+ const pair = insertItemPair("asked");
209
223
  const conflict = createOrUpdatePendingConflict({
210
- scopeId: 'default',
224
+ scopeId: "default",
211
225
  existingItemId: pair.existingItemId,
212
226
  candidateItemId: pair.candidateItemId,
213
- relationship: 'ambiguous_contradiction',
227
+ relationship: "ambiguous_contradiction",
214
228
  });
215
229
 
216
230
  const askedAt = 1_734_000_000_000;
@@ -220,80 +234,104 @@ describe('conflict-store', () => {
220
234
  expect(updated?.updatedAt).toBe(askedAt);
221
235
  });
222
236
 
223
- test('listPendingConflictDetails joins current statements', () => {
224
- const pair = insertItemPair('details', 'workspace-a');
237
+ test("listPendingConflictDetails joins current statements", () => {
238
+ const pair = insertItemPair("details", "workspace-a");
225
239
  createOrUpdatePendingConflict({
226
- scopeId: 'workspace-a',
240
+ scopeId: "workspace-a",
227
241
  existingItemId: pair.existingItemId,
228
242
  candidateItemId: pair.candidateItemId,
229
- relationship: 'ambiguous_contradiction',
230
- clarificationQuestion: 'Which framework should I keep?',
243
+ relationship: "ambiguous_contradiction",
244
+ clarificationQuestion: "Which framework should I keep?",
231
245
  });
232
246
 
233
- const details = listPendingConflictDetails('workspace-a');
247
+ const details = listPendingConflictDetails("workspace-a");
234
248
  expect(details).toHaveLength(1);
235
- expect(details[0].existingStatement).toBe('Existing statement details');
236
- expect(details[0].candidateStatement).toBe('Candidate statement details');
237
- expect(details[0].existingKind).toBe('fact');
238
- expect(details[0].candidateKind).toBe('fact');
249
+ expect(details[0].existingStatement).toBe("Existing statement details");
250
+ expect(details[0].candidateStatement).toBe("Candidate statement details");
251
+ expect(details[0].existingKind).toBe("fact");
252
+ expect(details[0].candidateKind).toBe("fact");
239
253
  });
240
254
 
241
- test('applyConflictResolution keeps candidate and resolves conflict row', () => {
242
- const pair = insertItemPair('apply-candidate');
255
+ test("applyConflictResolution keeps candidate and resolves conflict row", () => {
256
+ const pair = insertItemPair("apply-candidate");
243
257
  const conflict = createOrUpdatePendingConflict({
244
- scopeId: 'default',
258
+ scopeId: "default",
245
259
  existingItemId: pair.existingItemId,
246
260
  candidateItemId: pair.candidateItemId,
247
- relationship: 'ambiguous_contradiction',
261
+ relationship: "ambiguous_contradiction",
248
262
  });
249
263
 
250
- expect(applyConflictResolution({
251
- conflictId: conflict.id,
252
- resolution: 'keep_candidate',
253
- resolutionNote: 'User confirmed candidate statement.',
254
- })).toBe(true);
264
+ expect(
265
+ applyConflictResolution({
266
+ conflictId: conflict.id,
267
+ resolution: "keep_candidate",
268
+ resolutionNote: "User confirmed candidate statement.",
269
+ }),
270
+ ).toBe(true);
255
271
 
256
272
  const db = getDb();
257
- const existing = db.select().from(memoryItems).where(eq(memoryItems.id, pair.existingItemId)).get();
258
- const candidate = db.select().from(memoryItems).where(eq(memoryItems.id, pair.candidateItemId)).get();
273
+ const existing = db
274
+ .select()
275
+ .from(memoryItems)
276
+ .where(eq(memoryItems.id, pair.existingItemId))
277
+ .get();
278
+ const candidate = db
279
+ .select()
280
+ .from(memoryItems)
281
+ .where(eq(memoryItems.id, pair.candidateItemId))
282
+ .get();
259
283
  const updatedConflict = getConflictById(conflict.id);
260
284
 
261
- expect(typeof existing?.invalidAt).toBe('number');
262
- expect(existing?.status).toBe('superseded');
263
- expect(candidate?.status).toBe('active');
264
- expect(updatedConflict?.status).toBe('resolved_keep_candidate');
285
+ expect(typeof existing?.invalidAt).toBe("number");
286
+ expect(existing?.status).toBe("superseded");
287
+ expect(candidate?.status).toBe("active");
288
+ expect(updatedConflict?.status).toBe("resolved_keep_candidate");
265
289
  });
266
290
 
267
- test('applyConflictResolution merge updates existing item statement', () => {
268
- const pair = insertItemPair('apply-merge');
291
+ test("applyConflictResolution merge updates existing item statement", () => {
292
+ const pair = insertItemPair("apply-merge");
269
293
  const conflict = createOrUpdatePendingConflict({
270
- scopeId: 'default',
294
+ scopeId: "default",
271
295
  existingItemId: pair.existingItemId,
272
296
  candidateItemId: pair.candidateItemId,
273
- relationship: 'ambiguous_contradiction',
297
+ relationship: "ambiguous_contradiction",
274
298
  });
275
299
 
276
- const merged = 'Use React for dashboard pages and Vue for marketing pages.';
277
- expect(applyConflictResolution({
278
- conflictId: conflict.id,
279
- resolution: 'merge',
280
- mergedStatement: merged,
281
- resolutionNote: 'User clarified both apply in different contexts.',
282
- })).toBe(true);
300
+ const merged = "Use React for dashboard pages and Vue for marketing pages.";
301
+ expect(
302
+ applyConflictResolution({
303
+ conflictId: conflict.id,
304
+ resolution: "merge",
305
+ mergedStatement: merged,
306
+ resolutionNote: "User clarified both apply in different contexts.",
307
+ }),
308
+ ).toBe(true);
283
309
 
284
310
  const db = getDb();
285
- const existing = db.select().from(memoryItems).where(eq(memoryItems.id, pair.existingItemId)).get();
286
- const candidate = db.select().from(memoryItems).where(eq(memoryItems.id, pair.candidateItemId)).get();
311
+ const existing = db
312
+ .select()
313
+ .from(memoryItems)
314
+ .where(eq(memoryItems.id, pair.existingItemId))
315
+ .get();
316
+ const candidate = db
317
+ .select()
318
+ .from(memoryItems)
319
+ .where(eq(memoryItems.id, pair.candidateItemId))
320
+ .get();
287
321
  const updatedConflict = getConflictById(conflict.id);
288
322
 
289
323
  expect(existing?.statement).toBe(merged);
290
- expect(candidate?.status).toBe('superseded');
291
- expect(updatedConflict?.status).toBe('resolved_merge');
324
+ expect(candidate?.status).toBe("superseded");
325
+ expect(updatedConflict?.status).toBe("resolved_merge");
292
326
  });
293
327
 
294
- test('enforces pending-pair uniqueness with a partial index', () => {
295
- const pair = insertItemPair('index');
296
- const raw = (getDb() as unknown as { $client: import('bun:sqlite').Database }).$client;
328
+ test("enforces pending-pair uniqueness with a partial index", () => {
329
+ const pair = insertItemPair("index");
330
+ const raw = (
331
+ getDb() as unknown as {
332
+ $client: import("bun:sqlite").Database;
333
+ }
334
+ ).$client;
297
335
  const now = Date.now();
298
336
 
299
337
  raw.run(
@@ -312,8 +350,12 @@ describe('conflict-store', () => {
312
350
  id, scope_id, existing_item_id, candidate_item_id, relationship, status,
313
351
  clarification_question, resolution_note, last_asked_at, resolved_at, created_at, updated_at
314
352
  ) VALUES (
315
- 'conflict-index-b', 'default', '${pair.existingItemId}', '${pair.candidateItemId}',
316
- 'ambiguous_contradiction', 'pending_clarification', NULL, NULL, NULL, NULL, ${now + 1}, ${now + 1}
353
+ 'conflict-index-b', 'default', '${pair.existingItemId}', '${
354
+ pair.candidateItemId
355
+ }',
356
+ 'ambiguous_contradiction', 'pending_clarification', NULL, NULL, NULL, NULL, ${
357
+ now + 1
358
+ }, ${now + 1}
317
359
  )`,
318
360
  );
319
361
  }).toThrow();
@@ -324,8 +366,12 @@ describe('conflict-store', () => {
324
366
  id, scope_id, existing_item_id, candidate_item_id, relationship, status,
325
367
  clarification_question, resolution_note, last_asked_at, resolved_at, created_at, updated_at
326
368
  ) VALUES (
327
- 'conflict-index-c', 'default', '${pair.existingItemId}', '${pair.candidateItemId}',
328
- 'ambiguous_contradiction', 'resolved_keep_candidate', NULL, NULL, NULL, ${now + 2}, ${now + 2}, ${now + 2}
369
+ 'conflict-index-c', 'default', '${pair.existingItemId}', '${
370
+ pair.candidateItemId
371
+ }',
372
+ 'ambiguous_contradiction', 'resolved_keep_candidate', NULL, NULL, NULL, ${
373
+ now + 2
374
+ }, ${now + 2}, ${now + 2}
329
375
  )`,
330
376
  );
331
377
  }).not.toThrow();