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