@vellumai/assistant 0.5.5 → 0.5.7

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 (382) hide show
  1. package/.env.example +16 -2
  2. package/ARCHITECTURE.md +6 -75
  3. package/Dockerfile +4 -5
  4. package/README.md +0 -2
  5. package/bun.lock +0 -414
  6. package/docs/architecture/keychain-broker.md +45 -240
  7. package/docs/architecture/security.md +0 -17
  8. package/docs/credential-execution-service.md +2 -2
  9. package/node_modules/@vellumai/ces-contracts/package.json +1 -0
  10. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +119 -0
  11. package/node_modules/@vellumai/credential-storage/package.json +1 -0
  12. package/node_modules/@vellumai/egress-proxy/package.json +1 -0
  13. package/package.json +2 -3
  14. package/src/__tests__/actor-token-service.test.ts +1 -2
  15. package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
  16. package/src/__tests__/browser-skill-endstate.test.ts +6 -5
  17. package/src/__tests__/btw-routes.test.ts +0 -39
  18. package/src/__tests__/call-domain.test.ts +0 -128
  19. package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
  20. package/src/__tests__/channel-approval-routes.test.ts +0 -5
  21. package/src/__tests__/channel-readiness-service.test.ts +1 -60
  22. package/src/__tests__/checker.test.ts +4 -2
  23. package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
  24. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  25. package/src/__tests__/config-schema.test.ts +3 -3
  26. package/src/__tests__/context-window-manager.test.ts +78 -0
  27. package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
  28. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  29. package/src/__tests__/conversation-skill-tools.test.ts +0 -54
  30. package/src/__tests__/conversation-title-service.test.ts +117 -1
  31. package/src/__tests__/credential-execution-feature-gates.test.ts +28 -14
  32. package/src/__tests__/credential-execution-managed-contract.test.ts +33 -18
  33. package/src/__tests__/credential-security-e2e.test.ts +0 -66
  34. package/src/__tests__/credential-security-invariants.test.ts +4 -45
  35. package/src/__tests__/credentials-cli.test.ts +78 -0
  36. package/src/__tests__/db-migration-rollback.test.ts +2015 -1
  37. package/src/__tests__/docker-signing-key-bootstrap.test.ts +98 -0
  38. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
  39. package/src/__tests__/guardian-routing-state.test.ts +0 -5
  40. package/src/__tests__/host-shell-tool.test.ts +6 -7
  41. package/src/__tests__/http-user-message-parity.test.ts +3 -103
  42. package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
  43. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
  44. package/src/__tests__/intent-routing.test.ts +0 -13
  45. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
  46. package/src/__tests__/keychain-broker-client.test.ts +161 -22
  47. package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
  48. package/src/__tests__/memory-regressions.test.ts +8 -30
  49. package/src/__tests__/migration-export-http.test.ts +2 -2
  50. package/src/__tests__/migration-import-commit-http.test.ts +2 -2
  51. package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
  52. package/src/__tests__/migration-validate-http.test.ts +2 -2
  53. package/src/__tests__/non-member-access-request.test.ts +0 -5
  54. package/src/__tests__/notification-decision-fallback.test.ts +4 -0
  55. package/src/__tests__/notification-decision-identity.test.ts +4 -0
  56. package/src/__tests__/permission-types.test.ts +1 -0
  57. package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
  58. package/src/__tests__/qdrant-manager.test.ts +28 -2
  59. package/src/__tests__/registry.test.ts +0 -6
  60. package/src/__tests__/require-fresh-approval.test.ts +4 -0
  61. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
  62. package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
  63. package/src/__tests__/secure-keys.test.ts +83 -263
  64. package/src/__tests__/shell-identity.test.ts +96 -6
  65. package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
  66. package/src/__tests__/skill-feature-flags.test.ts +46 -45
  67. package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
  68. package/src/__tests__/skill-load-inline-command.test.ts +8 -12
  69. package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
  70. package/src/__tests__/skill-load-tool.test.ts +0 -2
  71. package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
  72. package/src/__tests__/skills.test.ts +0 -2
  73. package/src/__tests__/slack-inbound-verification.test.ts +0 -4
  74. package/src/__tests__/suggestion-routes.test.ts +1 -32
  75. package/src/__tests__/system-prompt.test.ts +0 -1
  76. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -0
  77. package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
  78. package/src/__tests__/tool-executor.test.ts +4 -0
  79. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
  80. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
  81. package/src/__tests__/update-bulletin.test.ts +0 -2
  82. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
  83. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -6
  84. package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
  85. package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +218 -0
  86. package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
  87. package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
  88. package/src/calls/audio-store.test.ts +97 -0
  89. package/src/calls/audio-store.ts +205 -0
  90. package/src/calls/call-controller.ts +85 -7
  91. package/src/calls/call-domain.ts +3 -0
  92. package/src/calls/call-store.ts +10 -3
  93. package/src/calls/fish-audio-client.ts +117 -0
  94. package/src/calls/relay-server.ts +27 -0
  95. package/src/calls/twilio-routes.ts +2 -1
  96. package/src/calls/types.ts +1 -0
  97. package/src/calls/voice-ingress-preflight.ts +0 -42
  98. package/src/calls/voice-quality.ts +26 -5
  99. package/src/calls/voice-session-bridge.ts +6 -12
  100. package/src/cli/commands/config.ts +1 -4
  101. package/src/cli/commands/conversations.ts +0 -18
  102. package/src/cli/commands/credentials.ts +34 -4
  103. package/src/cli/commands/oauth/index.ts +7 -0
  104. package/src/cli/commands/oauth/platform.ts +179 -0
  105. package/src/cli/commands/platform.ts +3 -3
  106. package/src/config/assistant-feature-flags.ts +186 -5
  107. package/src/config/bundled-skills/messaging/SKILL.md +5 -5
  108. package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
  109. package/src/config/bundled-skills/settings/TOOLS.json +2 -2
  110. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
  111. package/src/config/bundled-tool-registry.ts +1 -11
  112. package/src/config/env-registry.ts +1 -1
  113. package/src/config/env.ts +16 -16
  114. package/src/config/feature-flag-registry.json +48 -16
  115. package/src/config/loader.ts +98 -31
  116. package/src/config/schema.ts +4 -25
  117. package/src/config/schemas/calls.ts +13 -0
  118. package/src/config/schemas/fish-audio.ts +39 -0
  119. package/src/config/schemas/memory.ts +0 -4
  120. package/src/config/schemas/platform.ts +1 -1
  121. package/src/config/schemas/security.ts +4 -4
  122. package/src/config/types.ts +0 -1
  123. package/src/contacts/contact-store.ts +39 -0
  124. package/src/contacts/types.ts +2 -0
  125. package/src/context/window-manager.ts +53 -2
  126. package/src/credential-execution/approval-bridge.ts +1 -0
  127. package/src/credential-execution/executable-discovery.ts +28 -4
  128. package/src/credential-execution/feature-gates.ts +16 -0
  129. package/src/credential-execution/process-manager.ts +38 -0
  130. package/src/daemon/assistant-attachments.ts +9 -0
  131. package/src/daemon/config-watcher.ts +6 -4
  132. package/src/daemon/conversation-agent-loop.ts +0 -60
  133. package/src/daemon/conversation-memory.ts +0 -117
  134. package/src/daemon/conversation-runtime-assembly.ts +0 -2
  135. package/src/daemon/conversation-tool-setup.ts +0 -105
  136. package/src/daemon/conversation.ts +10 -1
  137. package/src/daemon/handlers/config-vercel.ts +92 -0
  138. package/src/daemon/handlers/conversations.ts +0 -11
  139. package/src/daemon/handlers/skills.ts +2 -15
  140. package/src/daemon/install-symlink.ts +195 -0
  141. package/src/daemon/lifecycle.ts +229 -96
  142. package/src/daemon/message-types/conversations.ts +3 -4
  143. package/src/daemon/message-types/diagnostics.ts +3 -22
  144. package/src/daemon/message-types/messages.ts +0 -2
  145. package/src/daemon/message-types/upgrades.ts +8 -0
  146. package/src/daemon/server.ts +30 -92
  147. package/src/events/domain-events.ts +2 -1
  148. package/src/followups/followup-store.ts +5 -2
  149. package/src/inbound/platform-callback-registration.ts +3 -3
  150. package/src/instrument.ts +8 -5
  151. package/src/memory/conversation-crud.ts +0 -236
  152. package/src/memory/conversation-title-service.ts +76 -11
  153. package/src/memory/db-init.ts +15 -11
  154. package/src/memory/indexer.ts +15 -106
  155. package/src/memory/items-extractor.ts +15 -1
  156. package/src/memory/job-handlers/conversation-starters.ts +4 -1
  157. package/src/memory/job-handlers/embedding.ts +0 -79
  158. package/src/memory/job-utils.ts +1 -1
  159. package/src/memory/jobs-store.ts +30 -13
  160. package/src/memory/jobs-worker.ts +31 -27
  161. package/src/memory/migrations/001-job-deferrals.ts +19 -0
  162. package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
  163. package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
  164. package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
  165. package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
  166. package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
  167. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
  168. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
  169. package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
  170. package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
  171. package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
  172. package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
  173. package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
  174. package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
  175. package/src/memory/migrations/116-messages-fts.ts +106 -1
  176. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
  177. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
  178. package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
  179. package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
  180. package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
  181. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
  182. package/src/memory/migrations/141-rename-verification-table.ts +54 -0
  183. package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
  184. package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
  185. package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
  186. package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
  187. package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
  188. package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
  189. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
  190. package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
  191. package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
  192. package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
  193. package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
  194. package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
  195. package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
  196. package/src/memory/migrations/189-drop-simplified-memory.ts +42 -0
  197. package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
  198. package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
  199. package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
  200. package/src/memory/migrations/index.ts +5 -3
  201. package/src/memory/migrations/registry.ts +90 -0
  202. package/src/memory/migrations/validate-migration-state.ts +137 -11
  203. package/src/memory/qdrant-circuit-breaker.ts +9 -0
  204. package/src/memory/qdrant-client.ts +4 -6
  205. package/src/memory/qdrant-manager.ts +64 -7
  206. package/src/memory/schema/calls.ts +1 -0
  207. package/src/memory/schema/contacts.ts +1 -0
  208. package/src/memory/schema/conversations.ts +0 -3
  209. package/src/memory/schema/index.ts +0 -2
  210. package/src/messaging/draft-store.ts +2 -2
  211. package/src/notifications/decision-engine.ts +4 -1
  212. package/src/oauth/connection-resolver.ts +6 -4
  213. package/src/permissions/checker.ts +0 -38
  214. package/src/permissions/defaults.ts +3 -3
  215. package/src/permissions/shell-identity.ts +76 -22
  216. package/src/permissions/trust-client.ts +2 -13
  217. package/src/permissions/trust-store.ts +8 -3
  218. package/src/permissions/types.ts +4 -2
  219. package/src/platform/client.ts +35 -7
  220. package/src/prompts/persona-resolver.ts +138 -0
  221. package/src/prompts/system-prompt.ts +36 -4
  222. package/src/prompts/templates/users/default.md +1 -0
  223. package/src/providers/registry.ts +27 -40
  224. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
  225. package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
  226. package/src/runtime/auth/external-assistant-id.ts +13 -59
  227. package/src/runtime/auth/route-policy.ts +29 -1
  228. package/src/runtime/auth/token-service.ts +53 -15
  229. package/src/runtime/channel-readiness-service.ts +1 -16
  230. package/src/runtime/http-server.ts +29 -2
  231. package/src/runtime/middleware/error-handler.ts +1 -9
  232. package/src/runtime/routes/audio-routes.ts +40 -0
  233. package/src/runtime/routes/btw-routes.ts +0 -17
  234. package/src/runtime/routes/conversation-management-routes.ts +0 -36
  235. package/src/runtime/routes/conversation-query-routes.ts +106 -2
  236. package/src/runtime/routes/conversation-routes.ts +4 -43
  237. package/src/runtime/routes/diagnostics-routes.ts +1 -477
  238. package/src/runtime/routes/identity-routes.ts +18 -29
  239. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
  240. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
  241. package/src/runtime/routes/integrations/vercel.ts +89 -0
  242. package/src/runtime/routes/log-export-routes.ts +5 -0
  243. package/src/runtime/routes/memory-item-routes.test.ts +221 -3
  244. package/src/runtime/routes/memory-item-routes.ts +144 -4
  245. package/src/runtime/routes/migration-rollback-routes.ts +209 -0
  246. package/src/runtime/routes/migration-routes.ts +17 -1
  247. package/src/runtime/routes/notification-routes.ts +58 -0
  248. package/src/runtime/routes/schedule-routes.ts +65 -0
  249. package/src/runtime/routes/settings-routes.ts +41 -1
  250. package/src/runtime/routes/tts-routes.ts +86 -0
  251. package/src/runtime/routes/upgrade-broadcast-routes.ts +175 -0
  252. package/src/runtime/routes/workspace-commit-routes.ts +62 -0
  253. package/src/runtime/routes/workspace-routes.test.ts +22 -1
  254. package/src/runtime/routes/workspace-routes.ts +1 -1
  255. package/src/runtime/routes/workspace-utils.ts +86 -2
  256. package/src/schedule/schedule-store.ts +0 -21
  257. package/src/security/ces-credential-client.ts +59 -22
  258. package/src/security/ces-rpc-credential-backend.ts +85 -0
  259. package/src/security/credential-backend.ts +12 -88
  260. package/src/security/keychain-broker-client.ts +10 -2
  261. package/src/security/secure-keys.ts +94 -113
  262. package/src/skills/catalog-install.ts +13 -7
  263. package/src/skills/inline-command-render.ts +5 -1
  264. package/src/skills/inline-command-runner.ts +30 -2
  265. package/src/telemetry/usage-telemetry-reporter.ts +4 -2
  266. package/src/tools/calls/call-start.ts +1 -0
  267. package/src/tools/executor.ts +0 -4
  268. package/src/tools/memory/handlers.ts +1 -129
  269. package/src/tools/network/script-proxy/session-manager.ts +19 -4
  270. package/src/tools/network/web-fetch.ts +3 -1
  271. package/src/tools/permission-checker.ts +18 -0
  272. package/src/tools/skills/execute.ts +1 -1
  273. package/src/tools/skills/load.ts +9 -2
  274. package/src/tools/types.ts +0 -8
  275. package/src/util/errors.ts +0 -12
  276. package/src/util/platform.ts +8 -55
  277. package/src/util/xml.ts +8 -0
  278. package/src/workspace/git-service.ts +5 -2
  279. package/src/workspace/heartbeat-service.ts +5 -24
  280. package/src/workspace/migrations/001-avatar-rename.ts +15 -0
  281. package/src/workspace/migrations/003-seed-device-id.ts +17 -1
  282. package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
  283. package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
  284. package/src/workspace/migrations/006-services-config.ts +49 -0
  285. package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
  286. package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
  287. package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
  288. package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
  289. package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
  290. package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
  291. package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
  292. package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
  293. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
  294. package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
  295. package/src/workspace/migrations/017-seed-persona-dirs.ts +95 -0
  296. package/src/workspace/migrations/migrate-to-workspace-volume.ts +23 -1
  297. package/src/workspace/migrations/registry.ts +8 -0
  298. package/src/workspace/migrations/runner.ts +106 -2
  299. package/src/workspace/migrations/types.ts +4 -0
  300. package/src/__tests__/archive-recall.test.ts +0 -560
  301. package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
  302. package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
  303. package/src/__tests__/conversation-memory-dirty-tail.test.ts +0 -150
  304. package/src/__tests__/conversation-switch-memory-reduction.test.ts +0 -474
  305. package/src/__tests__/db-memory-archive-migration.test.ts +0 -372
  306. package/src/__tests__/db-memory-brief-state-migration.test.ts +0 -213
  307. package/src/__tests__/db-memory-reducer-checkpoints.test.ts +0 -273
  308. package/src/__tests__/diagnostics-export.test.ts +0 -288
  309. package/src/__tests__/local-gateway-health.test.ts +0 -209
  310. package/src/__tests__/memory-brief-open-loops.test.ts +0 -530
  311. package/src/__tests__/memory-brief-time.test.ts +0 -285
  312. package/src/__tests__/memory-brief-wrapper.test.ts +0 -311
  313. package/src/__tests__/memory-chunk-archive.test.ts +0 -400
  314. package/src/__tests__/memory-chunk-dual-write.test.ts +0 -453
  315. package/src/__tests__/memory-episode-archive.test.ts +0 -370
  316. package/src/__tests__/memory-episode-dual-write.test.ts +0 -626
  317. package/src/__tests__/memory-observation-archive.test.ts +0 -375
  318. package/src/__tests__/memory-observation-dual-write.test.ts +0 -318
  319. package/src/__tests__/memory-reducer-job.test.ts +0 -538
  320. package/src/__tests__/memory-reducer-scheduling.test.ts +0 -473
  321. package/src/__tests__/memory-reducer-store.test.ts +0 -728
  322. package/src/__tests__/memory-reducer-types.test.ts +0 -707
  323. package/src/__tests__/memory-reducer.test.ts +0 -704
  324. package/src/__tests__/memory-simplified-config.test.ts +0 -281
  325. package/src/__tests__/secret-ingress-handler.test.ts +0 -120
  326. package/src/__tests__/simplified-memory-e2e.test.ts +0 -666
  327. package/src/__tests__/simplified-memory-runtime.test.ts +0 -616
  328. package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
  329. package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
  330. package/src/__tests__/swarm-orchestrator.test.ts +0 -463
  331. package/src/__tests__/swarm-plan-validator.test.ts +0 -384
  332. package/src/__tests__/swarm-recursion.test.ts +0 -197
  333. package/src/__tests__/swarm-router-planner.test.ts +0 -234
  334. package/src/__tests__/swarm-tool.test.ts +0 -185
  335. package/src/__tests__/swarm-worker-backend.test.ts +0 -144
  336. package/src/__tests__/swarm-worker-runner.test.ts +0 -288
  337. package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
  338. package/src/commands/cc-command-registry.ts +0 -248
  339. package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
  340. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
  341. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
  342. package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
  343. package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
  344. package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
  345. package/src/config/schemas/memory-simplified.ts +0 -101
  346. package/src/config/schemas/swarm.ts +0 -82
  347. package/src/logfire.ts +0 -135
  348. package/src/memory/archive-recall.ts +0 -516
  349. package/src/memory/archive-store.ts +0 -400
  350. package/src/memory/brief-formatting.ts +0 -33
  351. package/src/memory/brief-open-loops.ts +0 -266
  352. package/src/memory/brief-time.ts +0 -162
  353. package/src/memory/brief.ts +0 -75
  354. package/src/memory/job-handlers/backfill-simplified-memory.ts +0 -462
  355. package/src/memory/job-handlers/reduce-conversation-memory.ts +0 -229
  356. package/src/memory/migrations/185-memory-brief-state.ts +0 -52
  357. package/src/memory/migrations/186-memory-archive.ts +0 -109
  358. package/src/memory/migrations/187-memory-reducer-checkpoints.ts +0 -19
  359. package/src/memory/reducer-scheduler.ts +0 -242
  360. package/src/memory/reducer-store.ts +0 -271
  361. package/src/memory/reducer-types.ts +0 -106
  362. package/src/memory/reducer.ts +0 -467
  363. package/src/memory/schema/memory-archive.ts +0 -121
  364. package/src/memory/schema/memory-brief.ts +0 -55
  365. package/src/runtime/local-gateway-health.ts +0 -275
  366. package/src/security/secret-ingress.ts +0 -68
  367. package/src/swarm/backend-claude-code.ts +0 -225
  368. package/src/swarm/checkpoint.ts +0 -137
  369. package/src/swarm/graph-utils.ts +0 -53
  370. package/src/swarm/index.ts +0 -55
  371. package/src/swarm/limits.ts +0 -66
  372. package/src/swarm/orchestrator.ts +0 -424
  373. package/src/swarm/plan-validator.ts +0 -117
  374. package/src/swarm/router-planner.ts +0 -162
  375. package/src/swarm/router-prompts.ts +0 -39
  376. package/src/swarm/synthesizer.ts +0 -81
  377. package/src/swarm/types.ts +0 -72
  378. package/src/swarm/worker-backend.ts +0 -131
  379. package/src/swarm/worker-prompts.ts +0 -80
  380. package/src/swarm/worker-runner.ts +0 -170
  381. package/src/tools/claude-code/claude-code.ts +0 -610
  382. package/src/tools/swarm/delegate.ts +0 -205
@@ -5,7 +5,7 @@
5
5
  * Covers:
6
6
  * - Flag OFF blocks all exposure paths
7
7
  * - Missing persisted value falls back to code default
8
- * - New assistantFeatureFlagValues is the sole override mechanism
8
+ * - Protected feature-flags.json is the sole override mechanism
9
9
  * - Undeclared keys default to enabled
10
10
  */
11
11
  import {
@@ -101,7 +101,6 @@ mock.module("../config/loader.js", () => ({
101
101
  invalidateConfigCache: () => {},
102
102
  getNestedValue: () => undefined,
103
103
  setNestedValue: () => {},
104
- syncConfigToLockfile: () => {},
105
104
  }));
106
105
 
107
106
  // eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -120,7 +119,7 @@ mock.module("../tools/credentials/metadata-store.js", () => ({
120
119
  }));
121
120
 
122
121
  const { buildSystemPrompt } = await import("../prompts/system-prompt.js");
123
- const { isAssistantFeatureFlagEnabled } =
122
+ const { isAssistantFeatureFlagEnabled, _setOverridesForTesting } =
124
123
  await import("../config/assistant-feature-flags.js");
125
124
  const { skillFlagKey } = await import("../config/skill-state.js");
126
125
 
@@ -130,6 +129,7 @@ const { skillFlagKey } = await import("../config/skill-state.js");
130
129
 
131
130
  beforeEach(() => {
132
131
  mkdirSync(TEST_DIR, { recursive: true });
132
+ _setOverridesForTesting({});
133
133
  currentConfig = {
134
134
  services: {
135
135
  inference: {
@@ -148,6 +148,7 @@ beforeEach(() => {
148
148
  });
149
149
 
150
150
  afterEach(() => {
151
+ _setOverridesForTesting({});
151
152
  if (existsSync(TEST_DIR)) {
152
153
  rmSync(TEST_DIR, { recursive: true, force: true });
153
154
  }
@@ -198,11 +199,12 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
198
199
  "browser",
199
200
  );
200
201
 
202
+ _setOverridesForTesting({
203
+ [DECLARED_FLAG_KEY]: false,
204
+ "feature_flags.browser.enabled": true,
205
+ });
206
+
201
207
  currentConfig = {
202
- assistantFeatureFlagValues: {
203
- [DECLARED_FLAG_KEY]: false,
204
- "feature_flags.browser.enabled": true,
205
- },
206
208
  services: {
207
209
  inference: {
208
210
  mode: "your-own",
@@ -282,11 +284,12 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
282
284
  "email-channel",
283
285
  );
284
286
 
287
+ _setOverridesForTesting({
288
+ [DECLARED_FLAG_KEY]: false,
289
+ "feature_flags.email-channel.enabled": false,
290
+ });
291
+
285
292
  currentConfig = {
286
- assistantFeatureFlagValues: {
287
- [DECLARED_FLAG_KEY]: false,
288
- "feature_flags.email-channel.enabled": false,
289
- },
290
293
  services: {
291
294
  inference: {
292
295
  mode: "your-own",
@@ -311,7 +314,7 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
311
314
  expect(result).not.toContain("**email-channel**");
312
315
  });
313
316
 
314
- test("assistantFeatureFlagValues overrides control visibility", () => {
317
+ test("file-based overrides control visibility", () => {
315
318
  createSkillOnDisk(
316
319
  DECLARED_SKILL_ID,
317
320
  "Contacts",
@@ -319,8 +322,9 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
319
322
  DECLARED_FLAG_ID,
320
323
  );
321
324
 
325
+ _setOverridesForTesting({ [DECLARED_FLAG_KEY]: true });
326
+
322
327
  currentConfig = {
323
- assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: true },
324
328
  services: {
325
329
  inference: {
326
330
  mode: "your-own",
@@ -352,8 +356,9 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
352
356
  "browser",
353
357
  );
354
358
 
359
+ _setOverridesForTesting({ "feature_flags.browser.enabled": false });
360
+
355
361
  currentConfig = {
356
- assistantFeatureFlagValues: { "feature_flags.browser.enabled": false },
357
362
  services: {
358
363
  inference: {
359
364
  mode: "your-own",
@@ -446,18 +451,16 @@ describe("buildSystemPrompt assistant feature flag filtering", () => {
446
451
  // ---------------------------------------------------------------------------
447
452
 
448
453
  describe("isAssistantFeatureFlagEnabled", () => {
449
- test("reads from assistantFeatureFlagValues", () => {
450
- const config = {
451
- assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: true },
452
- } as any;
454
+ test("reads from file-based overrides", () => {
455
+ _setOverridesForTesting({ [DECLARED_FLAG_KEY]: true });
456
+ const config = {} as any;
453
457
 
454
458
  expect(isAssistantFeatureFlagEnabled(DECLARED_FLAG_KEY, config)).toBe(true);
455
459
  });
456
460
 
457
- test("explicit false override in assistantFeatureFlagValues", () => {
458
- const config = {
459
- assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: false },
460
- } as any;
461
+ test("explicit false override in file-based overrides", () => {
462
+ _setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
463
+ const config = {} as any;
461
464
 
462
465
  expect(isAssistantFeatureFlagEnabled(DECLARED_FLAG_KEY, config)).toBe(
463
466
  false,
@@ -483,10 +486,9 @@ describe("isAssistantFeatureFlagEnabled", () => {
483
486
  ).toBe(true);
484
487
  });
485
488
 
486
- test("undeclared flag respects persisted canonical override", () => {
487
- const config = {
488
- assistantFeatureFlagValues: { "feature_flags.browser.enabled": false },
489
- } as any;
489
+ test("undeclared flag respects persisted override", () => {
490
+ _setOverridesForTesting({ "feature_flags.browser.enabled": false });
491
+ const config = {} as any;
490
492
 
491
493
  expect(
492
494
  isAssistantFeatureFlagEnabled("feature_flags.browser.enabled", config),
@@ -496,9 +498,8 @@ describe("isAssistantFeatureFlagEnabled", () => {
496
498
 
497
499
  describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
498
500
  test("resolves skill flag via canonical path", () => {
499
- const config = {
500
- assistantFeatureFlagValues: { [DECLARED_FLAG_KEY]: false },
501
- } as any;
501
+ _setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
502
+ const config = {} as any;
502
503
 
503
504
  expect(
504
505
  isAssistantFeatureFlagEnabled(
@@ -7,13 +7,10 @@
7
7
  import { afterAll, beforeAll, describe, expect, mock, test } from "bun:test";
8
8
 
9
9
  mock.module("../config/loader.js", () => ({
10
- getConfig: () => ({
11
- assistantFeatureFlagValues: {
12
- "feature_flags.browser.enabled": true,
13
- },
14
- }),
10
+ getConfig: () => ({}),
15
11
  }));
16
12
 
13
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
17
14
  import {
18
15
  projectSkillTools,
19
16
  resetSkillToolProjection,
@@ -35,11 +32,15 @@ import {
35
32
 
36
33
  afterAll(() => {
37
34
  __resetRegistryForTesting();
35
+ _setOverridesForTesting({});
38
36
  });
39
37
 
40
38
  describe("browser skill migration end-state", () => {
41
39
  beforeAll(async () => {
42
40
  __resetRegistryForTesting();
41
+ _setOverridesForTesting({
42
+ "feature_flags.browser.enabled": true,
43
+ });
43
44
  await initializeTools();
44
45
  });
45
46
 
@@ -54,17 +54,6 @@ mock.module("../daemon/conversation-tool-setup.js", () => ({
54
54
  buildToolDefinitions: () => MOCK_TOOLS,
55
55
  }));
56
56
 
57
- const mockCheckIngressForSecrets = mock((content: string) => ({
58
- blocked: false,
59
- userNotice: "",
60
- detectedTypes: [] as string[],
61
- normalizedContent: content,
62
- }));
63
-
64
- mock.module("../security/secret-ingress.js", () => ({
65
- checkIngressForSecrets: mockCheckIngressForSecrets,
66
- }));
67
-
68
57
  const MOCK_SYSTEM_PROMPT = "You are a helpful assistant.";
69
58
  const mockBuildSystemPrompt = mock(() => MOCK_SYSTEM_PROMPT);
70
59
 
@@ -236,34 +225,6 @@ describe("POST /v1/btw", () => {
236
225
  expect(body.error.message).toContain("content");
237
226
  });
238
227
 
239
- test("returns 422 when content includes a blocked secret", async () => {
240
- mockCheckIngressForSecrets.mockReturnValueOnce({
241
- blocked: true,
242
- userNotice: "Secret detected",
243
- detectedTypes: ["api_key"],
244
- normalizedContent: "sk-test-123",
245
- });
246
-
247
- const provider = makeMockProvider();
248
- const session = makeMockSession(provider);
249
- const res = await callHandler(
250
- { conversationKey: "key", content: "sk-test-123" },
251
- { sendMessageDeps: makeSendMessageDeps(session) },
252
- );
253
-
254
- expect(res.status).toBe(422);
255
- const body = (await res.json()) as {
256
- accepted: boolean;
257
- error: string;
258
- message: string;
259
- detectedTypes: string[];
260
- };
261
- expect(body.accepted).toBe(false);
262
- expect(body.error).toBe("secret_blocked");
263
- expect(body.detectedTypes).toEqual(["api_key"]);
264
- expect(provider.sendMessage).not.toHaveBeenCalled();
265
- });
266
-
267
228
  // -- Service unavailability (503) --
268
229
 
269
230
  test("returns 503 when sendMessageDeps is unavailable", async () => {
@@ -40,46 +40,6 @@ let twilioInitiateCallArgs: Array<Record<string, unknown>> = [];
40
40
  let mockIngressEnabled = true;
41
41
  let mockIngressPublicBaseUrl = "https://test.example.com";
42
42
 
43
- interface MockGatewayHealthResult {
44
- target: string;
45
- healthy: boolean;
46
- localDeployment: boolean;
47
- error?: string;
48
- }
49
-
50
- interface MockEnsureLocalGatewayReadyResult extends MockGatewayHealthResult {
51
- recovered: boolean;
52
- recoveryAttempted: boolean;
53
- recoverySkipped: boolean;
54
- }
55
-
56
- let probeLocalGatewayHealthResults: MockGatewayHealthResult[] = [];
57
- let probeLocalGatewayHealthCallCount = 0;
58
- let ensureLocalGatewayReadyResult: MockEnsureLocalGatewayReadyResult;
59
- let ensureLocalGatewayReadyCallCount = 0;
60
-
61
- function makeGatewayHealthResult(
62
- overrides: Partial<MockGatewayHealthResult> = {},
63
- ): MockGatewayHealthResult {
64
- return {
65
- target: "http://127.0.0.1:7830",
66
- healthy: true,
67
- localDeployment: true,
68
- ...overrides,
69
- };
70
- }
71
-
72
- function makeRecoveryResult(
73
- overrides: Partial<MockEnsureLocalGatewayReadyResult> = {},
74
- ): MockEnsureLocalGatewayReadyResult {
75
- return {
76
- ...makeGatewayHealthResult(),
77
- recovered: false,
78
- recoveryAttempted: false,
79
- recoverySkipped: false,
80
- ...overrides,
81
- };
82
- }
83
43
 
84
44
  mock.module("../calls/twilio-config.js", () => ({
85
45
  getTwilioConfig: (assistantId?: string) => ({
@@ -160,18 +120,6 @@ mock.module("../memory/conversation-title-service.js", () => ({
160
120
  queueGenerateConversationTitle: () => {},
161
121
  }));
162
122
 
163
- mock.module("../runtime/local-gateway-health.js", () => ({
164
- probeLocalGatewayHealth: async () => {
165
- probeLocalGatewayHealthCallCount++;
166
- const next =
167
- probeLocalGatewayHealthResults.shift() ?? makeGatewayHealthResult();
168
- return next;
169
- },
170
- ensureLocalGatewayReady: async () => {
171
- ensureLocalGatewayReadyCallCount++;
172
- return ensureLocalGatewayReadyResult;
173
- },
174
- }));
175
123
 
176
124
  mock.module("../daemon/handlers/config-ingress.js", () => ({
177
125
  computeGatewayTarget: () => "http://127.0.0.1:7830",
@@ -204,13 +152,6 @@ beforeEach(() => {
204
152
  twilioInitiateCallArgs = [];
205
153
  mockIngressEnabled = true;
206
154
  mockIngressPublicBaseUrl = "https://test.example.com";
207
- probeLocalGatewayHealthResults = [
208
- makeGatewayHealthResult(),
209
- makeGatewayHealthResult(),
210
- ];
211
- probeLocalGatewayHealthCallCount = 0;
212
- ensureLocalGatewayReadyResult = makeRecoveryResult();
213
- ensureLocalGatewayReadyCallCount = 0;
214
155
  });
215
156
 
216
157
  let ensuredConvIds = new Set<string>();
@@ -446,9 +387,6 @@ describe("startCall — pointer message regression", () => {
446
387
  expect(result.status).toBe(503);
447
388
  expect(result.error).toContain("Public ingress");
448
389
  }
449
- expect(probeLocalGatewayHealthCallCount).toBe(0);
450
- expect(ensureLocalGatewayReadyCallCount).toBe(0);
451
- // No reconcile calls expected (reconcile triggers removed).
452
390
  expect(twilioInitiateCallCount).toBe(0);
453
391
 
454
392
  await new Promise((r) => setTimeout(r, 50));
@@ -459,72 +397,6 @@ describe("startCall — pointer message regression", () => {
459
397
  expect(text!).toContain("failed");
460
398
  });
461
399
 
462
- test("never dials Twilio when the local callback gateway stays unhealthy", async () => {
463
- const convId = "conv-domain-preflight-unhealthy";
464
- ensureConversation(convId);
465
- probeLocalGatewayHealthResults = [
466
- makeGatewayHealthResult({
467
- healthy: false,
468
- error: "Gateway health check returned HTTP 503",
469
- }),
470
- makeGatewayHealthResult({
471
- healthy: false,
472
- error: "Gateway health check returned HTTP 503",
473
- }),
474
- ];
475
- ensureLocalGatewayReadyResult = makeRecoveryResult({
476
- healthy: false,
477
- error: "Gateway health check returned HTTP 503",
478
- recovered: false,
479
- recoveryAttempted: true,
480
- });
481
-
482
- const result = await startCall({
483
- phoneNumber: "+15559876543",
484
- task: "Test call",
485
- conversationId: convId,
486
- });
487
-
488
- expect(result.ok).toBe(false);
489
- if (!result.ok) {
490
- expect(result.status).toBe(503);
491
- expect(result.error).toContain("still unhealthy");
492
- }
493
- expect(probeLocalGatewayHealthCallCount).toBe(2);
494
- expect(ensureLocalGatewayReadyCallCount).toBe(1);
495
- // No reconcile calls expected (reconcile triggers removed).
496
- expect(twilioInitiateCallCount).toBe(0);
497
- });
498
-
499
- test("can recover a local gateway and then place exactly one outbound Twilio call", async () => {
500
- const convId = "conv-domain-preflight-recovery";
501
- ensureConversation(convId);
502
- probeLocalGatewayHealthResults = [
503
- makeGatewayHealthResult({
504
- healthy: false,
505
- error: "Gateway health check returned HTTP 503",
506
- }),
507
- makeGatewayHealthResult(),
508
- ];
509
- ensureLocalGatewayReadyResult = makeRecoveryResult({
510
- healthy: true,
511
- recovered: true,
512
- recoveryAttempted: true,
513
- });
514
-
515
- const result = await startCall({
516
- phoneNumber: "+15559876543",
517
- task: "Test call",
518
- conversationId: convId,
519
- });
520
-
521
- expect(result.ok).toBe(true);
522
- expect(probeLocalGatewayHealthCallCount).toBe(2);
523
- expect(ensureLocalGatewayReadyCallCount).toBe(1);
524
- // Gateway reconcile triggers have been removed; the gateway reads
525
- // credentials and config via TTL caches.
526
- expect(twilioInitiateCallCount).toBe(1);
527
- });
528
400
 
529
401
  test("failed call writes a failed pointer to the initiating conversation", async () => {
530
402
  const convId = "conv-domain-ptr-fail";
@@ -0,0 +1,199 @@
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ import { CesRpcMethod } from "@vellumai/ces-contracts";
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Mock state
7
+ // ---------------------------------------------------------------------------
8
+
9
+ const callFn = mock(
10
+ async (_method: string, _request: unknown): Promise<unknown> => ({}),
11
+ );
12
+
13
+ const isReadyFn = mock((): boolean => true);
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Mock modules — before importing module under test
17
+ // ---------------------------------------------------------------------------
18
+
19
+ mock.module("../util/logger.js", () => ({
20
+ getLogger: () =>
21
+ new Proxy({} as Record<string, unknown>, {
22
+ get: () => () => {},
23
+ }),
24
+ }));
25
+
26
+ // Import after mocking
27
+ import type { CesClient } from "../credential-execution/client.js";
28
+ import { CesRpcCredentialBackend } from "../security/ces-rpc-credential-backend.js";
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Helpers
32
+ // ---------------------------------------------------------------------------
33
+
34
+ function createMockClient(): CesClient {
35
+ return {
36
+ handshake: mock(async () => ({ accepted: true })),
37
+ call: callFn as CesClient["call"],
38
+ updateAssistantApiKey: mock(async () => ({ updated: true })),
39
+ isReady: isReadyFn,
40
+ close: mock(() => {}),
41
+ };
42
+ }
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Tests
46
+ // ---------------------------------------------------------------------------
47
+
48
+ describe("CesRpcCredentialBackend", () => {
49
+ let client: CesClient;
50
+ let backend: CesRpcCredentialBackend;
51
+
52
+ beforeEach(() => {
53
+ callFn.mockClear();
54
+ isReadyFn.mockClear();
55
+
56
+ isReadyFn.mockReturnValue(true);
57
+
58
+ client = createMockClient();
59
+ backend = new CesRpcCredentialBackend(client);
60
+ });
61
+
62
+ test("has name 'ces-rpc'", () => {
63
+ expect(backend.name).toBe("ces-rpc");
64
+ });
65
+
66
+ // -------------------------------------------------------------------------
67
+ // isAvailable
68
+ // -------------------------------------------------------------------------
69
+
70
+ describe("isAvailable", () => {
71
+ test("returns true when client is ready", () => {
72
+ isReadyFn.mockReturnValue(true);
73
+ expect(backend.isAvailable()).toBe(true);
74
+ });
75
+
76
+ test("returns false when client is not ready", () => {
77
+ isReadyFn.mockReturnValue(false);
78
+ expect(backend.isAvailable()).toBe(false);
79
+ });
80
+ });
81
+
82
+ // -------------------------------------------------------------------------
83
+ // get
84
+ // -------------------------------------------------------------------------
85
+
86
+ describe("get", () => {
87
+ test("delegates to CesRpcMethod.GetCredential and returns value when found", async () => {
88
+ callFn.mockResolvedValue({ found: true, value: "my-secret" });
89
+
90
+ const result = await backend.get("test-account");
91
+
92
+ expect(callFn).toHaveBeenCalledWith(CesRpcMethod.GetCredential, {
93
+ account: "test-account",
94
+ });
95
+ expect(result).toEqual({ value: "my-secret", unreachable: false });
96
+ });
97
+
98
+ test("returns undefined value when credential not found", async () => {
99
+ callFn.mockResolvedValue({ found: false });
100
+
101
+ const result = await backend.get("missing-account");
102
+
103
+ expect(callFn).toHaveBeenCalledWith(CesRpcMethod.GetCredential, {
104
+ account: "missing-account",
105
+ });
106
+ expect(result).toEqual({ value: undefined, unreachable: false });
107
+ });
108
+
109
+ test("returns unreachable when RPC call throws", async () => {
110
+ callFn.mockRejectedValue(new Error("transport error"));
111
+
112
+ const result = await backend.get("broken-account");
113
+
114
+ expect(result).toEqual({ value: undefined, unreachable: true });
115
+ });
116
+ });
117
+
118
+ // -------------------------------------------------------------------------
119
+ // set
120
+ // -------------------------------------------------------------------------
121
+
122
+ describe("set", () => {
123
+ test("delegates to CesRpcMethod.SetCredential and returns true on success", async () => {
124
+ callFn.mockResolvedValue({ ok: true });
125
+
126
+ const result = await backend.set("test-account", "new-secret");
127
+
128
+ expect(callFn).toHaveBeenCalledWith(CesRpcMethod.SetCredential, {
129
+ account: "test-account",
130
+ value: "new-secret",
131
+ });
132
+ expect(result).toBe(true);
133
+ });
134
+
135
+ test("returns false when RPC call throws", async () => {
136
+ callFn.mockRejectedValue(new Error("transport error"));
137
+
138
+ const result = await backend.set("test-account", "new-secret");
139
+
140
+ expect(result).toBe(false);
141
+ });
142
+ });
143
+
144
+ // -------------------------------------------------------------------------
145
+ // delete
146
+ // -------------------------------------------------------------------------
147
+
148
+ describe("delete", () => {
149
+ test("delegates to CesRpcMethod.DeleteCredential and returns the result", async () => {
150
+ callFn.mockResolvedValue({ result: "deleted" });
151
+
152
+ const result = await backend.delete("test-account");
153
+
154
+ expect(callFn).toHaveBeenCalledWith(CesRpcMethod.DeleteCredential, {
155
+ account: "test-account",
156
+ });
157
+ expect(result).toBe("deleted");
158
+ });
159
+
160
+ test("returns not-found result from CES", async () => {
161
+ callFn.mockResolvedValue({ result: "not-found" });
162
+
163
+ const result = await backend.delete("nonexistent-account");
164
+
165
+ expect(result).toBe("not-found");
166
+ });
167
+
168
+ test("returns 'error' when RPC call throws", async () => {
169
+ callFn.mockRejectedValue(new Error("transport error"));
170
+
171
+ const result = await backend.delete("test-account");
172
+
173
+ expect(result).toBe("error");
174
+ });
175
+ });
176
+
177
+ // -------------------------------------------------------------------------
178
+ // list
179
+ // -------------------------------------------------------------------------
180
+
181
+ describe("list", () => {
182
+ test("delegates to CesRpcMethod.ListCredentials and returns accounts", async () => {
183
+ callFn.mockResolvedValue({ accounts: ["account-a", "account-b"] });
184
+
185
+ const result = await backend.list();
186
+
187
+ expect(callFn).toHaveBeenCalledWith(CesRpcMethod.ListCredentials, {});
188
+ expect(result).toEqual(["account-a", "account-b"]);
189
+ });
190
+
191
+ test("returns empty array when RPC call throws", async () => {
192
+ callFn.mockRejectedValue(new Error("transport error"));
193
+
194
+ const result = await backend.list();
195
+
196
+ expect(result).toEqual([]);
197
+ });
198
+ });
199
+ });
@@ -38,11 +38,6 @@ mock.module("../util/logger.js", () => ({
38
38
  }),
39
39
  }));
40
40
 
41
- // Mock security check to always pass
42
- mock.module("../security/secret-ingress.js", () => ({
43
- checkIngressForSecrets: () => ({ blocked: false }),
44
- }));
45
-
46
41
  // Mock render to return the raw content as text
47
42
  mock.module("../daemon/handlers/shared.js", () => ({
48
43
  renderHistoryContent: (content: unknown) => ({