comisai 1.0.11 → 1.0.13

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 (255) hide show
  1. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +1 -0
  2. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +9 -9
  3. package/node_modules/@comis/agent/package.json +1 -1
  4. package/node_modules/@comis/channels/package.json +1 -1
  5. package/node_modules/@comis/cli/package.json +1 -1
  6. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +2 -0
  7. package/node_modules/@comis/core/package.json +1 -1
  8. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +12 -1
  9. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +1 -0
  10. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +1 -0
  11. package/node_modules/@comis/daemon/package.json +1 -1
  12. package/node_modules/@comis/gateway/package.json +1 -1
  13. package/node_modules/@comis/infra/package.json +1 -1
  14. package/node_modules/@comis/memory/package.json +1 -1
  15. package/node_modules/@comis/scheduler/dist/cron/cron-types.d.ts +6 -0
  16. package/node_modules/@comis/scheduler/dist/cron/cron-types.js +2 -0
  17. package/node_modules/@comis/scheduler/package.json +1 -1
  18. package/node_modules/@comis/shared/package.json +1 -1
  19. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +1 -1
  20. package/node_modules/@comis/skills/package.json +1 -1
  21. package/package.json +18 -18
  22. package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
  23. package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
  24. package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
  25. package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
  26. package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
  27. package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
  28. package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
  29. package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
  30. package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
  31. package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
  32. package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
  33. package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
  34. package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
  35. package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
  36. package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
  37. package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
  38. package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
  39. package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
  40. package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
  41. package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
  42. package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
  43. package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
  44. package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
  45. package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
  46. package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
  47. package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
  48. package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
  49. package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
  50. package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
  51. package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
  52. package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
  53. package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
  54. package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
  55. package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
  56. package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
  57. package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
  58. package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
  59. package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
  60. package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
  61. package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
  62. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
  63. package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
  64. package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
  65. package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
  66. package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
  67. package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
  68. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
  69. package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
  70. package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
  71. package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
  72. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
  73. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
  74. package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
  75. package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
  76. package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
  77. package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
  78. package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
  79. package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
  80. package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
  81. package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
  82. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
  83. package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
  84. package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
  85. package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
  86. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
  87. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
  88. package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
  89. package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
  90. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
  91. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
  92. package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
  93. package/node_modules/@comis/core/dist/context/context.test.js +0 -276
  94. package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
  95. package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
  96. package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
  97. package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
  98. package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
  99. package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
  100. package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
  101. package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
  102. package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
  103. package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
  104. package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
  105. package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
  106. package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
  107. package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
  108. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
  109. package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
  110. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
  111. package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
  112. package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
  113. package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
  114. package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
  115. package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
  116. package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
  117. package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
  118. package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
  119. package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
  120. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
  121. package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
  122. package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
  123. package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
  124. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
  125. package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
  126. package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
  127. package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
  128. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
  129. package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
  130. package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
  131. package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
  132. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
  133. package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
  134. package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
  135. package/node_modules/@comis/core/dist/load-env.test.js +0 -21
  136. package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
  137. package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
  138. package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
  139. package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
  140. package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
  141. package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
  142. package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
  143. package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
  144. package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
  145. package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
  146. package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
  147. package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
  148. package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
  149. package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
  150. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
  151. package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
  152. package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
  153. package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
  154. package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
  155. package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
  156. package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
  157. package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
  158. package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
  159. package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
  160. package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
  161. package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
  162. package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
  163. package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
  164. package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
  165. package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
  166. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
  167. package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
  168. package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
  169. package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
  170. package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
  171. package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
  172. package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
  173. package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
  174. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
  175. package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
  176. package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
  177. package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
  178. package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
  179. package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
  180. package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
  181. package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
  182. package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
  183. package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
  184. package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
  185. package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
  186. package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
  187. package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
  188. package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
  189. package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
  190. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
  191. package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
  192. package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
  193. package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
  194. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
  195. package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
  196. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
  197. package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
  198. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
  199. package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
  200. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
  201. package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
  202. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
  203. package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
  204. package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
  205. package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
  206. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
  207. package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
  208. package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
  209. package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
  210. package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
  211. package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
  212. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
  213. package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
  214. package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
  215. package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
  216. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
  217. package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
  218. package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
  219. package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
  220. package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
  221. package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
  222. package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
  223. package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
  224. package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
  225. package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
  226. package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
  227. package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
  228. package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
  229. package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
  230. package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
  231. package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
  232. package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
  233. package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
  234. package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
  235. package/node_modules/@comis/memory/dist/schema.test.js +0 -240
  236. package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
  237. package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
  238. package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
  239. package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
  240. package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
  241. package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
  242. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
  243. package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
  244. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
  245. package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
  246. package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
  247. package/node_modules/@comis/shared/dist/abort.test.js +0 -71
  248. package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
  249. package/node_modules/@comis/shared/dist/result.test.js +0 -178
  250. package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
  251. package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
  252. package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
  253. package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
  254. package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
  255. package/node_modules/@comis/shared/dist/ttl-cache.test.js +0 -81
@@ -1,135 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { parseCredentialMapping } from "./credential-mapping.js";
3
- function validMapping(overrides = {}) {
4
- return {
5
- id: "map-001",
6
- secretName: "OPENAI_API_KEY",
7
- injectionType: "bearer_header",
8
- urlPattern: "https://api.openai.com/*",
9
- ...overrides,
10
- };
11
- }
12
- describe("CredentialMapping", () => {
13
- describe("valid data", () => {
14
- it("parses a bearer_header mapping without injectionKey", () => {
15
- const result = parseCredentialMapping(validMapping());
16
- expect(result.ok).toBe(true);
17
- if (result.ok) {
18
- expect(result.value.id).toBe("map-001");
19
- expect(result.value.secretName).toBe("OPENAI_API_KEY");
20
- expect(result.value.injectionType).toBe("bearer_header");
21
- expect(result.value.urlPattern).toBe("https://api.openai.com/*");
22
- expect(result.value.injectionKey).toBeUndefined();
23
- expect(result.value.toolName).toBeUndefined();
24
- }
25
- });
26
- it("parses a custom_header mapping with injectionKey", () => {
27
- const result = parseCredentialMapping(validMapping({
28
- injectionType: "custom_header",
29
- injectionKey: "X-Api-Key",
30
- }));
31
- expect(result.ok).toBe(true);
32
- if (result.ok) {
33
- expect(result.value.injectionType).toBe("custom_header");
34
- expect(result.value.injectionKey).toBe("X-Api-Key");
35
- }
36
- });
37
- it("parses a query_param mapping with injectionKey", () => {
38
- const result = parseCredentialMapping(validMapping({
39
- injectionType: "query_param",
40
- injectionKey: "api_key",
41
- urlPattern: "https://api.example.com/*",
42
- }));
43
- expect(result.ok).toBe(true);
44
- if (result.ok) {
45
- expect(result.value.injectionType).toBe("query_param");
46
- expect(result.value.injectionKey).toBe("api_key");
47
- }
48
- });
49
- it("parses a basic_auth mapping without injectionKey", () => {
50
- const result = parseCredentialMapping(validMapping({
51
- injectionType: "basic_auth",
52
- urlPattern: "https://internal.example.com/*",
53
- }));
54
- expect(result.ok).toBe(true);
55
- if (result.ok) {
56
- expect(result.value.injectionType).toBe("basic_auth");
57
- expect(result.value.injectionKey).toBeUndefined();
58
- }
59
- });
60
- it("accepts optional toolName", () => {
61
- const result = parseCredentialMapping(validMapping({ toolName: "brave_search" }));
62
- expect(result.ok).toBe(true);
63
- if (result.ok) {
64
- expect(result.value.toolName).toBe("brave_search");
65
- }
66
- });
67
- it("bearer_header succeeds without injectionKey (optional for bearer/basic_auth)", () => {
68
- const result = parseCredentialMapping(validMapping());
69
- expect(result.ok).toBe(true);
70
- });
71
- });
72
- describe("injectionKey refinement", () => {
73
- it("rejects custom_header without injectionKey", () => {
74
- const result = parseCredentialMapping(validMapping({ injectionType: "custom_header" }));
75
- expect(result.ok).toBe(false);
76
- if (!result.ok) {
77
- const messages = result.error.issues.map((i) => i.message);
78
- expect(messages).toContain("injectionKey is required for custom_header and query_param injection types");
79
- }
80
- });
81
- it("rejects custom_header with empty injectionKey", () => {
82
- const result = parseCredentialMapping(validMapping({ injectionType: "custom_header", injectionKey: "" }));
83
- expect(result.ok).toBe(false);
84
- });
85
- it("rejects query_param without injectionKey", () => {
86
- const result = parseCredentialMapping(validMapping({ injectionType: "query_param" }));
87
- expect(result.ok).toBe(false);
88
- if (!result.ok) {
89
- const messages = result.error.issues.map((i) => i.message);
90
- expect(messages).toContain("injectionKey is required for custom_header and query_param injection types");
91
- }
92
- });
93
- it("rejects query_param with empty injectionKey", () => {
94
- const result = parseCredentialMapping(validMapping({ injectionType: "query_param", injectionKey: "" }));
95
- expect(result.ok).toBe(false);
96
- });
97
- });
98
- describe("invalid data", () => {
99
- it("rejects unknown injectionType", () => {
100
- const result = parseCredentialMapping(validMapping({ injectionType: "oauth2_token" }));
101
- expect(result.ok).toBe(false);
102
- });
103
- it("rejects missing required fields", () => {
104
- const result = parseCredentialMapping({});
105
- expect(result.ok).toBe(false);
106
- if (!result.ok) {
107
- const paths = result.error.issues.map((i) => i.path[0]);
108
- expect(paths).toContain("id");
109
- expect(paths).toContain("secretName");
110
- expect(paths).toContain("injectionType");
111
- expect(paths).toContain("urlPattern");
112
- }
113
- });
114
- it("rejects empty id", () => {
115
- const result = parseCredentialMapping(validMapping({ id: "" }));
116
- expect(result.ok).toBe(false);
117
- });
118
- it("rejects empty secretName", () => {
119
- const result = parseCredentialMapping(validMapping({ secretName: "" }));
120
- expect(result.ok).toBe(false);
121
- });
122
- it("rejects empty urlPattern", () => {
123
- const result = parseCredentialMapping(validMapping({ urlPattern: "" }));
124
- expect(result.ok).toBe(false);
125
- });
126
- it("rejects non-object input", () => {
127
- const result = parseCredentialMapping(42);
128
- expect(result.ok).toBe(false);
129
- });
130
- it("rejects null input", () => {
131
- const result = parseCredentialMapping(null);
132
- expect(result.ok).toBe(false);
133
- });
134
- });
135
- });
@@ -1,68 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { DeliveryOriginSchema, createDeliveryOrigin } from "./delivery-origin.js";
3
- describe("DeliveryOrigin", () => {
4
- const validInput = {
5
- channelType: "telegram",
6
- channelId: "chat-123",
7
- userId: "user-456",
8
- threadId: "thread-789",
9
- tenantId: "acme",
10
- };
11
- describe("createDeliveryOrigin", () => {
12
- it("creates a frozen DeliveryOrigin with all fields", () => {
13
- const origin = createDeliveryOrigin(validInput);
14
- expect(origin.channelType).toBe("telegram");
15
- expect(origin.channelId).toBe("chat-123");
16
- expect(origin.userId).toBe("user-456");
17
- expect(origin.threadId).toBe("thread-789");
18
- expect(origin.tenantId).toBe("acme");
19
- expect(Object.isFrozen(origin)).toBe(true);
20
- });
21
- it("defaults tenantId to 'default' when omitted", () => {
22
- const origin = createDeliveryOrigin({
23
- channelType: "discord",
24
- channelId: "ch-1",
25
- userId: "u-1",
26
- });
27
- expect(origin.tenantId).toBe("default");
28
- });
29
- it("allows threadId to be omitted (undefined)", () => {
30
- const origin = createDeliveryOrigin({
31
- channelType: "discord",
32
- channelId: "ch-1",
33
- userId: "u-1",
34
- });
35
- expect(origin.threadId).toBeUndefined();
36
- });
37
- it("rejects empty channelType", () => {
38
- expect(() => createDeliveryOrigin({ ...validInput, channelType: "" })).toThrow();
39
- });
40
- it("rejects empty channelId", () => {
41
- expect(() => createDeliveryOrigin({ ...validInput, channelId: "" })).toThrow();
42
- });
43
- it("rejects empty userId", () => {
44
- expect(() => createDeliveryOrigin({ ...validInput, userId: "" })).toThrow();
45
- });
46
- it("produces a frozen object that rejects property assignment", () => {
47
- const origin = createDeliveryOrigin(validInput);
48
- expect(Object.isFrozen(origin)).toBe(true);
49
- // In strict mode, assignment to frozen properties throws
50
- expect(() => {
51
- origin["channelType"] = "hacked";
52
- }).toThrow(TypeError);
53
- });
54
- });
55
- describe("DeliveryOriginSchema (z.strictObject)", () => {
56
- it("rejects unknown extra fields", () => {
57
- const result = DeliveryOriginSchema.safeParse({
58
- ...validInput,
59
- extra: "not-allowed",
60
- });
61
- expect(result.success).toBe(false);
62
- });
63
- it("rejects missing required fields", () => {
64
- const result = DeliveryOriginSchema.safeParse({});
65
- expect(result.success).toBe(false);
66
- });
67
- });
68
- });
@@ -1,441 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { GraphNodeSchema, ExecutionGraphSchema, parseExecutionGraph, topologicalSort, validateAndSortGraph, GraphValidationError, NodeTypeIdSchema, } from "./execution-graph.js";
3
- // ---------------------------------------------------------------------------
4
- // Helpers
5
- // ---------------------------------------------------------------------------
6
- function node(nodeId, dependsOn = []) {
7
- return GraphNodeSchema.parse({ nodeId, task: `Do ${nodeId}`, dependsOn });
8
- }
9
- // ---------------------------------------------------------------------------
10
- // GraphNodeSchema
11
- // ---------------------------------------------------------------------------
12
- describe("GraphNodeSchema", () => {
13
- const validNode = {
14
- nodeId: "research",
15
- task: "Research the topic",
16
- agentId: "agent-1",
17
- model: "claude-sonnet-4-20250514",
18
- dependsOn: ["setup"],
19
- timeoutMs: 30000,
20
- maxSteps: 5,
21
- };
22
- it("accepts a valid node with all fields", () => {
23
- const result = GraphNodeSchema.safeParse(validNode);
24
- expect(result.success).toBe(true);
25
- if (result.success) {
26
- expect(result.data.nodeId).toBe("research");
27
- expect(result.data.task).toBe("Research the topic");
28
- expect(result.data.agentId).toBe("agent-1");
29
- expect(result.data.dependsOn).toEqual(["setup"]);
30
- expect(result.data.maxSteps).toBe(5);
31
- }
32
- });
33
- it("accepts a minimal node (only nodeId + task), defaults dependsOn to []", () => {
34
- const result = GraphNodeSchema.safeParse({ nodeId: "a", task: "Do A" });
35
- expect(result.success).toBe(true);
36
- if (result.success) {
37
- expect(result.data.dependsOn).toEqual([]);
38
- expect(result.data.agentId).toBeUndefined();
39
- expect(result.data.model).toBeUndefined();
40
- expect(result.data.timeoutMs).toBeUndefined();
41
- expect(result.data.maxSteps).toBeUndefined();
42
- }
43
- });
44
- it("rejects empty nodeId", () => {
45
- const result = GraphNodeSchema.safeParse({ nodeId: "", task: "Do it" });
46
- expect(result.success).toBe(false);
47
- });
48
- it("rejects empty task", () => {
49
- const result = GraphNodeSchema.safeParse({ nodeId: "a", task: "" });
50
- expect(result.success).toBe(false);
51
- });
52
- it("rejects unknown extra fields (strictObject enforcement)", () => {
53
- const result = GraphNodeSchema.safeParse({
54
- ...validNode,
55
- extra: "not-allowed",
56
- });
57
- expect(result.success).toBe(false);
58
- });
59
- it("rejects inputFrom as unknown field (strictObject enforcement)", () => {
60
- const result = GraphNodeSchema.safeParse({
61
- ...validNode,
62
- inputFrom: { setup: "setupResult" },
63
- });
64
- expect(result.success).toBe(false);
65
- });
66
- it("rejects negative timeoutMs", () => {
67
- const result = GraphNodeSchema.safeParse({
68
- nodeId: "a",
69
- task: "Do A",
70
- timeoutMs: -1,
71
- });
72
- expect(result.success).toBe(false);
73
- });
74
- it("rejects zero timeoutMs", () => {
75
- const result = GraphNodeSchema.safeParse({
76
- nodeId: "a",
77
- task: "Do A",
78
- timeoutMs: 0,
79
- });
80
- expect(result.success).toBe(false);
81
- });
82
- it("defaults contextMode to full when not provided", () => {
83
- const result = GraphNodeSchema.safeParse({ nodeId: "a", task: "Do A" });
84
- expect(result.success).toBe(true);
85
- if (result.success) {
86
- expect(result.data.contextMode).toBe("full");
87
- }
88
- });
89
- it("accepts contextMode summary and none", () => {
90
- const summaryResult = GraphNodeSchema.safeParse({
91
- nodeId: "a",
92
- task: "Do A",
93
- contextMode: "summary",
94
- });
95
- expect(summaryResult.success).toBe(true);
96
- if (summaryResult.success) {
97
- expect(summaryResult.data.contextMode).toBe("summary");
98
- }
99
- const noneResult = GraphNodeSchema.safeParse({
100
- nodeId: "b",
101
- task: "Do B",
102
- contextMode: "none",
103
- });
104
- expect(noneResult.success).toBe(true);
105
- if (noneResult.success) {
106
- expect(noneResult.data.contextMode).toBe("none");
107
- }
108
- });
109
- it("rejects debate field as unknown (removed in Phase 452)", () => {
110
- const result = GraphNodeSchema.safeParse({
111
- nodeId: "a",
112
- task: "Do A",
113
- debate: { agents: ["a1"] },
114
- });
115
- expect(result.success).toBe(false);
116
- });
117
- });
118
- // ---------------------------------------------------------------------------
119
- // NodeTypeIdSchema
120
- // ---------------------------------------------------------------------------
121
- describe("NodeTypeIdSchema", () => {
122
- const validValues = [
123
- "agent",
124
- "debate",
125
- "vote",
126
- "refine",
127
- "collaborate",
128
- "approval-gate",
129
- "map-reduce",
130
- ];
131
- it("accepts all 7 valid node type IDs", () => {
132
- for (const value of validValues) {
133
- const result = NodeTypeIdSchema.safeParse(value);
134
- expect(result.success).toBe(true);
135
- if (result.success) {
136
- expect(result.data).toBe(value);
137
- }
138
- }
139
- });
140
- it("rejects unknown values", () => {
141
- expect(NodeTypeIdSchema.safeParse("custom").success).toBe(false);
142
- expect(NodeTypeIdSchema.safeParse("unknown").success).toBe(false);
143
- expect(NodeTypeIdSchema.safeParse("").success).toBe(false);
144
- });
145
- });
146
- // ---------------------------------------------------------------------------
147
- // GraphNodeSchema typeId/typeConfig
148
- // ---------------------------------------------------------------------------
149
- describe("GraphNodeSchema typeId/typeConfig", () => {
150
- it("accepts both typeId and typeConfig present", () => {
151
- const result = GraphNodeSchema.safeParse({
152
- nodeId: "a",
153
- task: "Do A",
154
- typeId: "debate",
155
- typeConfig: { agents: ["a1", "a2"], rounds: 2 },
156
- });
157
- expect(result.success).toBe(true);
158
- if (result.success) {
159
- expect(result.data.typeId).toBe("debate");
160
- expect(result.data.typeConfig).toEqual({ agents: ["a1", "a2"], rounds: 2 });
161
- }
162
- });
163
- it("accepts neither typeId nor typeConfig (regular node)", () => {
164
- const result = GraphNodeSchema.safeParse({
165
- nodeId: "a",
166
- task: "Do A",
167
- });
168
- expect(result.success).toBe(true);
169
- if (result.success) {
170
- expect(result.data.typeId).toBeUndefined();
171
- expect(result.data.typeConfig).toBeUndefined();
172
- }
173
- });
174
- it("rejects only typeId without typeConfig", () => {
175
- const result = GraphNodeSchema.safeParse({
176
- nodeId: "a",
177
- task: "Do A",
178
- typeId: "debate",
179
- });
180
- expect(result.success).toBe(false);
181
- if (!result.success) {
182
- const message = result.error.issues.map((i) => i.message).join(" ");
183
- expect(message).toContain("typeId and typeConfig must both be present or both absent");
184
- }
185
- });
186
- it("rejects only typeConfig without typeId", () => {
187
- const result = GraphNodeSchema.safeParse({
188
- nodeId: "a",
189
- task: "Do A",
190
- typeConfig: { rounds: 2 },
191
- });
192
- expect(result.success).toBe(false);
193
- if (!result.success) {
194
- const message = result.error.issues.map((i) => i.message).join(" ");
195
- expect(message).toContain("typeId and typeConfig must both be present or both absent");
196
- }
197
- });
198
- });
199
- // ---------------------------------------------------------------------------
200
- // ExecutionGraphSchema
201
- // ---------------------------------------------------------------------------
202
- describe("ExecutionGraphSchema", () => {
203
- const validGraph = {
204
- nodes: [
205
- { nodeId: "a", task: "Do A" },
206
- { nodeId: "b", task: "Do B", dependsOn: ["a"] },
207
- ],
208
- label: "Test graph",
209
- };
210
- it("accepts a valid graph with multiple nodes", () => {
211
- const result = ExecutionGraphSchema.safeParse(validGraph);
212
- expect(result.success).toBe(true);
213
- if (result.success) {
214
- expect(result.data.nodes).toHaveLength(2);
215
- expect(result.data.label).toBe("Test graph");
216
- }
217
- });
218
- it("rejects empty nodes array", () => {
219
- const result = ExecutionGraphSchema.safeParse({ nodes: [] });
220
- expect(result.success).toBe(false);
221
- });
222
- it("rejects more than 20 nodes", () => {
223
- const nodes = Array.from({ length: 21 }, (_, i) => ({
224
- nodeId: `n${i}`,
225
- task: `Task ${i}`,
226
- }));
227
- const result = ExecutionGraphSchema.safeParse({ nodes });
228
- expect(result.success).toBe(false);
229
- });
230
- it("defaults onFailure to 'fail-fast'", () => {
231
- const result = ExecutionGraphSchema.safeParse(validGraph);
232
- expect(result.success).toBe(true);
233
- if (result.success) {
234
- expect(result.data.onFailure).toBe("fail-fast");
235
- }
236
- });
237
- it("accepts onFailure 'continue'", () => {
238
- const result = ExecutionGraphSchema.safeParse({
239
- ...validGraph,
240
- onFailure: "continue",
241
- });
242
- expect(result.success).toBe(true);
243
- if (result.success) {
244
- expect(result.data.onFailure).toBe("continue");
245
- }
246
- });
247
- it("rejects unknown extra fields (strictObject enforcement)", () => {
248
- const result = ExecutionGraphSchema.safeParse({
249
- ...validGraph,
250
- extra: "not-allowed",
251
- });
252
- expect(result.success).toBe(false);
253
- });
254
- });
255
- // ---------------------------------------------------------------------------
256
- // parseExecutionGraph
257
- // ---------------------------------------------------------------------------
258
- describe("parseExecutionGraph", () => {
259
- it("returns ok for a valid graph", () => {
260
- const result = parseExecutionGraph({
261
- nodes: [{ nodeId: "a", task: "Do A" }],
262
- });
263
- expect(result.ok).toBe(true);
264
- if (result.ok) {
265
- expect(result.value.nodes).toHaveLength(1);
266
- expect(result.value.onFailure).toBe("fail-fast");
267
- }
268
- });
269
- it("returns err for invalid input (not a thrown ZodError)", () => {
270
- const result = parseExecutionGraph({ nodes: [] });
271
- expect(result.ok).toBe(false);
272
- if (!result.ok) {
273
- expect(result.error).toBeDefined();
274
- expect(result.error.issues).toBeDefined();
275
- }
276
- });
277
- });
278
- // ---------------------------------------------------------------------------
279
- // topologicalSort
280
- // ---------------------------------------------------------------------------
281
- describe("topologicalSort", () => {
282
- it("sorts a linear chain A -> B -> C", () => {
283
- const nodes = [node("A"), node("B", ["A"]), node("C", ["B"])];
284
- const result = topologicalSort(nodes);
285
- expect(result.ok).toBe(true);
286
- if (result.ok) {
287
- expect(result.value).toEqual(["A", "B", "C"]);
288
- }
289
- });
290
- it("sorts a diamond DAG (A first, D last)", () => {
291
- const nodes = [
292
- node("A"),
293
- node("B", ["A"]),
294
- node("C", ["A"]),
295
- node("D", ["B", "C"]),
296
- ];
297
- const result = topologicalSort(nodes);
298
- expect(result.ok).toBe(true);
299
- if (result.ok) {
300
- expect(result.value[0]).toBe("A");
301
- expect(result.value[result.value.length - 1]).toBe("D");
302
- expect(result.value).toHaveLength(4);
303
- // B and C can be in any order, but both must come after A and before D
304
- expect(result.value.indexOf("B")).toBeGreaterThan(result.value.indexOf("A"));
305
- expect(result.value.indexOf("C")).toBeGreaterThan(result.value.indexOf("A"));
306
- expect(result.value.indexOf("B")).toBeLessThan(result.value.indexOf("D"));
307
- expect(result.value.indexOf("C")).toBeLessThan(result.value.indexOf("D"));
308
- }
309
- });
310
- it("returns all independent nodes (any order)", () => {
311
- const nodes = [node("X"), node("Y"), node("Z")];
312
- const result = topologicalSort(nodes);
313
- expect(result.ok).toBe(true);
314
- if (result.ok) {
315
- expect(result.value).toHaveLength(3);
316
- expect(new Set(result.value)).toEqual(new Set(["X", "Y", "Z"]));
317
- }
318
- });
319
- it("handles single node with no dependencies", () => {
320
- const nodes = [node("solo")];
321
- const result = topologicalSort(nodes);
322
- expect(result.ok).toBe(true);
323
- if (result.ok) {
324
- expect(result.value).toEqual(["solo"]);
325
- }
326
- });
327
- it("detects a cycle: A -> B -> C -> A", () => {
328
- const nodes = [
329
- node("A", ["C"]),
330
- node("B", ["A"]),
331
- node("C", ["B"]),
332
- ];
333
- const result = topologicalSort(nodes);
334
- expect(result.ok).toBe(false);
335
- if (!result.ok) {
336
- expect(result.error).toBeInstanceOf(GraphValidationError);
337
- expect(result.error.kind).toBe("cycle");
338
- expect(result.error.message).toContain("Cycle detected");
339
- // Error message should include cycle path with arrows
340
- expect(result.error.message).toContain("->");
341
- }
342
- });
343
- it("detects self-dependency", () => {
344
- const nodes = [
345
- GraphNodeSchema.parse({ nodeId: "A", task: "Do A", dependsOn: ["A"] }),
346
- ];
347
- const result = topologicalSort(nodes);
348
- expect(result.ok).toBe(false);
349
- if (!result.ok) {
350
- expect(result.error).toBeInstanceOf(GraphValidationError);
351
- expect(result.error.kind).toBe("self_dependency");
352
- expect(result.error.nodes).toEqual(["A"]);
353
- expect(result.error.message).toContain("depends on itself");
354
- }
355
- });
356
- it("detects missing dependency", () => {
357
- const nodes = [
358
- GraphNodeSchema.parse({ nodeId: "A", task: "Do A", dependsOn: ["Z"] }),
359
- ];
360
- const result = topologicalSort(nodes);
361
- expect(result.ok).toBe(false);
362
- if (!result.ok) {
363
- expect(result.error).toBeInstanceOf(GraphValidationError);
364
- expect(result.error.kind).toBe("missing_dependency");
365
- expect(result.error.nodes).toContain("A");
366
- expect(result.error.nodes).toContain("Z");
367
- expect(result.error.message).toContain("non-existent");
368
- }
369
- });
370
- it("detects duplicate node IDs", () => {
371
- const nodes = [
372
- node("A"),
373
- GraphNodeSchema.parse({ nodeId: "A", task: "Another A" }),
374
- ];
375
- const result = topologicalSort(nodes);
376
- expect(result.ok).toBe(false);
377
- if (!result.ok) {
378
- expect(result.error).toBeInstanceOf(GraphValidationError);
379
- expect(result.error.kind).toBe("duplicate_node_id");
380
- expect(result.error.nodes).toEqual(["A"]);
381
- }
382
- });
383
- it("handles complex graph (5+ nodes) with correct dependency ordering", () => {
384
- // Graph: A -> B -> D -> E, A -> C -> D, C -> E
385
- const nodes = [
386
- node("A"),
387
- node("B", ["A"]),
388
- node("C", ["A"]),
389
- node("D", ["B", "C"]),
390
- node("E", ["D", "C"]),
391
- ];
392
- const result = topologicalSort(nodes);
393
- expect(result.ok).toBe(true);
394
- if (result.ok) {
395
- const order = result.value;
396
- expect(order).toHaveLength(5);
397
- // Verify all dependencies are satisfied: for each node, all its
398
- // dependsOn appear earlier in the sorted output
399
- for (const n of nodes) {
400
- const nodeIdx = order.indexOf(n.nodeId);
401
- for (const dep of n.dependsOn) {
402
- const depIdx = order.indexOf(dep);
403
- expect(depIdx).toBeLessThan(nodeIdx);
404
- }
405
- }
406
- }
407
- });
408
- });
409
- // ---------------------------------------------------------------------------
410
- // validateAndSortGraph
411
- // ---------------------------------------------------------------------------
412
- describe("validateAndSortGraph", () => {
413
- it("returns ValidatedGraph with graph and executionOrder for valid DAG", () => {
414
- const graph = ExecutionGraphSchema.parse({
415
- nodes: [
416
- { nodeId: "a", task: "Do A" },
417
- { nodeId: "b", task: "Do B", dependsOn: ["a"] },
418
- ],
419
- });
420
- const result = validateAndSortGraph(graph);
421
- expect(result.ok).toBe(true);
422
- if (result.ok) {
423
- expect(result.value.graph).toBe(graph);
424
- expect(result.value.executionOrder).toEqual(["a", "b"]);
425
- }
426
- });
427
- it("returns GraphValidationError for cyclic graph", () => {
428
- const graph = ExecutionGraphSchema.parse({
429
- nodes: [
430
- { nodeId: "a", task: "Do A", dependsOn: ["b"] },
431
- { nodeId: "b", task: "Do B", dependsOn: ["a"] },
432
- ],
433
- });
434
- const result = validateAndSortGraph(graph);
435
- expect(result.ok).toBe(false);
436
- if (!result.ok) {
437
- expect(result.error).toBeInstanceOf(GraphValidationError);
438
- expect(result.error.kind).toBe("cycle");
439
- }
440
- });
441
- });