@cleocode/core 2026.3.76 → 2026.4.2

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 (473) hide show
  1. package/dist/agents/agent-schema.d.ts.map +1 -1
  2. package/dist/audit.d.ts +1 -1
  3. package/dist/audit.d.ts.map +1 -1
  4. package/dist/bootstrap.d.ts +2 -2
  5. package/dist/bootstrap.d.ts.map +1 -1
  6. package/dist/caamp/adapter.d.ts +6 -49
  7. package/dist/caamp/adapter.d.ts.map +1 -1
  8. package/dist/caamp/index.d.ts +2 -2
  9. package/dist/caamp/index.d.ts.map +1 -1
  10. package/dist/code/index.d.ts +10 -0
  11. package/dist/code/index.d.ts.map +1 -0
  12. package/dist/code/outline.d.ts +51 -0
  13. package/dist/code/outline.d.ts.map +1 -0
  14. package/dist/code/parser.d.ts +32 -0
  15. package/dist/code/parser.d.ts.map +1 -0
  16. package/dist/code/search.d.ts +42 -0
  17. package/dist/code/search.d.ts.map +1 -0
  18. package/dist/code/unfold.d.ts +44 -0
  19. package/dist/code/unfold.d.ts.map +1 -0
  20. package/dist/compliance/protocol-enforcement.d.ts +1 -1
  21. package/dist/compliance/protocol-rules.d.ts +1 -1
  22. package/dist/compliance/protocol-types.d.ts +2 -3
  23. package/dist/compliance/protocol-types.d.ts.map +1 -1
  24. package/dist/conduit/conduit-client.d.ts +14 -0
  25. package/dist/conduit/conduit-client.d.ts.map +1 -1
  26. package/dist/conduit/factory.d.ts +11 -1
  27. package/dist/conduit/factory.d.ts.map +1 -1
  28. package/dist/conduit/http-transport.d.ts +17 -5
  29. package/dist/conduit/http-transport.d.ts.map +1 -1
  30. package/dist/conduit/index.d.ts +5 -2
  31. package/dist/conduit/index.d.ts.map +1 -1
  32. package/dist/conduit/local-transport.d.ts +91 -0
  33. package/dist/conduit/local-transport.d.ts.map +1 -0
  34. package/dist/conduit/sse-transport.d.ts +68 -0
  35. package/dist/conduit/sse-transport.d.ts.map +1 -0
  36. package/dist/crypto/credentials.d.ts.map +1 -1
  37. package/dist/error-catalog.d.ts +3 -3
  38. package/dist/error-catalog.d.ts.map +1 -1
  39. package/dist/errors.d.ts +1 -1
  40. package/dist/hooks/handlers/index.d.ts +2 -2
  41. package/dist/hooks/handlers/index.d.ts.map +1 -1
  42. package/dist/hooks/handlers/notification-hooks.d.ts +31 -0
  43. package/dist/hooks/handlers/notification-hooks.d.ts.map +1 -0
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +4646 -3476
  47. package/dist/index.js.map +4 -4
  48. package/dist/init.d.ts +6 -6
  49. package/dist/init.d.ts.map +1 -1
  50. package/dist/injection.d.ts.map +1 -1
  51. package/dist/internal.d.ts +7 -5
  52. package/dist/internal.d.ts.map +1 -1
  53. package/dist/lib/index.d.ts +1 -0
  54. package/dist/lib/index.d.ts.map +1 -1
  55. package/dist/lib/tree-sitter-languages.d.ts +29 -0
  56. package/dist/lib/tree-sitter-languages.d.ts.map +1 -0
  57. package/dist/logger.d.ts +3 -3
  58. package/dist/memory/brain-links.d.ts.map +1 -1
  59. package/dist/memory/brain-maintenance.d.ts +13 -0
  60. package/dist/memory/brain-maintenance.d.ts.map +1 -1
  61. package/dist/memory/brain-retrieval.d.ts +1 -1
  62. package/dist/memory/brain-retrieval.d.ts.map +1 -1
  63. package/dist/memory/decisions.d.ts.map +1 -1
  64. package/dist/memory/engine-compat.d.ts +392 -25
  65. package/dist/memory/engine-compat.d.ts.map +1 -1
  66. package/dist/memory/index.d.ts +416 -3
  67. package/dist/memory/index.d.ts.map +1 -1
  68. package/dist/metrics/token-service.d.ts +3 -3
  69. package/dist/metrics/token-service.d.ts.map +1 -1
  70. package/dist/orchestration/hierarchy.d.ts +32 -0
  71. package/dist/orchestration/hierarchy.d.ts.map +1 -0
  72. package/dist/orchestration/index.d.ts +1 -0
  73. package/dist/orchestration/index.d.ts.map +1 -1
  74. package/dist/paths.d.ts +335 -2
  75. package/dist/paths.d.ts.map +1 -1
  76. package/dist/routing/capability-matrix.d.ts +3 -3
  77. package/dist/routing/capability-matrix.d.ts.map +1 -1
  78. package/dist/scaffold.d.ts +422 -11
  79. package/dist/scaffold.d.ts.map +1 -1
  80. package/dist/security/input-sanitization.d.ts +2 -2
  81. package/dist/skills/dynamic-skill-generator.d.ts +3 -2
  82. package/dist/skills/dynamic-skill-generator.d.ts.map +1 -1
  83. package/dist/skills/routing-table.d.ts +4 -4
  84. package/dist/skills/routing-table.d.ts.map +1 -1
  85. package/dist/store/agent-registry-accessor.d.ts +10 -433
  86. package/dist/store/agent-registry-accessor.d.ts.map +1 -1
  87. package/dist/store/cross-db-cleanup.d.ts +34 -0
  88. package/dist/store/cross-db-cleanup.d.ts.map +1 -1
  89. package/dist/store/provider.d.ts +1 -1
  90. package/dist/store/signaldock-sqlite.d.ts.map +1 -1
  91. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  92. package/dist/store/sqlite.d.ts +1 -1
  93. package/dist/store/task-store.d.ts.map +1 -1
  94. package/dist/store/tasks-schema.d.ts +4 -228
  95. package/dist/store/tasks-schema.d.ts.map +1 -1
  96. package/dist/store/validation-schemas.d.ts +4 -5
  97. package/dist/store/validation-schemas.d.ts.map +1 -1
  98. package/dist/system/archive-analytics.d.ts +1 -1
  99. package/dist/system/health.d.ts +2 -2
  100. package/dist/system/health.d.ts.map +1 -1
  101. package/dist/system/runtime.d.ts +2 -1
  102. package/dist/system/runtime.d.ts.map +1 -1
  103. package/dist/tasks/list.d.ts +1 -1
  104. package/dist/tasks/list.d.ts.map +1 -1
  105. package/dist/tasks/task-ops.d.ts +415 -3
  106. package/dist/tasks/task-ops.d.ts.map +1 -1
  107. package/dist/templates/parser.d.ts +1 -1
  108. package/dist/ui/index.d.ts +1 -1
  109. package/dist/upgrade.d.ts +1 -1
  110. package/dist/upgrade.d.ts.map +1 -1
  111. package/dist/validation/operation-gate-validators.d.ts +1 -1
  112. package/dist/validation/operation-verification-gates.d.ts +3 -3
  113. package/dist/validation/param-utils.d.ts +6 -5
  114. package/dist/validation/param-utils.d.ts.map +1 -1
  115. package/dist/validation/validate-ops.d.ts +1 -1
  116. package/dist/validation/validate-ops.d.ts.map +1 -1
  117. package/package.json +19 -7
  118. package/src/__tests__/caamp-skill-install.test.js +0 -15
  119. package/src/__tests__/caamp-skill-install.test.js.map +1 -1
  120. package/src/__tests__/caamp-skill-install.test.ts +0 -16
  121. package/src/__tests__/injection-mvi-tiers.test.js +7 -7
  122. package/src/__tests__/injection-mvi-tiers.test.js.map +1 -1
  123. package/src/__tests__/injection-mvi-tiers.test.ts +55 -103
  124. package/src/agents/agent-schema.ts +2 -5
  125. package/src/audit.ts +2 -2
  126. package/src/bootstrap.ts +5 -39
  127. package/src/caamp/adapter.ts +3 -219
  128. package/src/caamp/index.ts +1 -13
  129. package/src/cant/__tests__/cant-agent-parse.test.d.ts.map +1 -0
  130. package/src/cant/__tests__/cant-agent-parse.test.js +77 -0
  131. package/src/cant/__tests__/cant-agent-parse.test.js.map +1 -0
  132. package/src/code/index.ts +10 -0
  133. package/src/code/outline.ts +214 -0
  134. package/src/code/parser.ts +331 -0
  135. package/src/code/search.ts +173 -0
  136. package/src/code/unfold.ts +204 -0
  137. package/src/codebase-map/analyzers/architecture.ts +2 -2
  138. package/src/compliance/protocol-enforcement.ts +1 -1
  139. package/src/compliance/protocol-rules.ts +1 -1
  140. package/src/compliance/protocol-types.ts +2 -3
  141. package/src/conduit/__tests__/dual-api-e2e.test.d.ts.map +1 -0
  142. package/src/conduit/__tests__/dual-api-e2e.test.js +178 -0
  143. package/src/conduit/__tests__/dual-api-e2e.test.js.map +1 -0
  144. package/src/conduit/__tests__/dual-api-e2e.test.ts +212 -0
  145. package/src/conduit/__tests__/local-credential-flow.test.d.ts.map +1 -0
  146. package/src/conduit/__tests__/local-credential-flow.test.js +185 -0
  147. package/src/conduit/__tests__/local-credential-flow.test.js.map +1 -0
  148. package/src/conduit/__tests__/local-credential-flow.test.ts +230 -0
  149. package/src/conduit/__tests__/local-transport.test.d.ts.map +1 -0
  150. package/src/conduit/__tests__/local-transport.test.js +404 -0
  151. package/src/conduit/__tests__/local-transport.test.js.map +1 -0
  152. package/src/conduit/__tests__/local-transport.test.ts +509 -0
  153. package/src/conduit/__tests__/sse-transport.test.d.ts.map +1 -0
  154. package/src/conduit/__tests__/sse-transport.test.js +291 -0
  155. package/src/conduit/__tests__/sse-transport.test.js.map +1 -0
  156. package/src/conduit/__tests__/sse-transport.test.ts +344 -0
  157. package/src/conduit/conduit-client.ts +14 -0
  158. package/src/conduit/factory.ts +29 -8
  159. package/src/conduit/http-transport.ts +78 -16
  160. package/src/conduit/index.ts +5 -2
  161. package/src/conduit/local-transport.ts +309 -0
  162. package/src/conduit/sse-transport.ts +382 -0
  163. package/src/crypto/credentials.ts +59 -13
  164. package/src/error-catalog.ts +3 -3
  165. package/src/errors.ts +1 -1
  166. package/src/hooks/__tests__/provider-hooks.test.js +4 -4
  167. package/src/hooks/__tests__/provider-hooks.test.js.map +1 -1
  168. package/src/hooks/__tests__/provider-hooks.test.ts +4 -4
  169. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js +2 -2
  170. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js.map +1 -1
  171. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.ts +6 -4
  172. package/src/hooks/handlers/index.ts +2 -6
  173. package/src/hooks/handlers/notification-hooks.ts +65 -0
  174. package/src/index.ts +2 -1
  175. package/src/init.ts +14 -54
  176. package/src/injection.ts +4 -3
  177. package/src/internal.ts +7 -5
  178. package/src/lib/index.ts +8 -0
  179. package/src/lib/tree-sitter-languages.ts +88 -0
  180. package/src/logger.ts +5 -5
  181. package/src/memory/__tests__/brain-links.test.js +13 -0
  182. package/src/memory/__tests__/brain-links.test.js.map +1 -1
  183. package/src/memory/__tests__/brain-links.test.ts +14 -0
  184. package/src/memory/__tests__/brain-retrieval.test.js +9 -0
  185. package/src/memory/__tests__/brain-retrieval.test.js.map +1 -1
  186. package/src/memory/__tests__/brain-retrieval.test.ts +10 -0
  187. package/src/memory/__tests__/session-memory.test.js +16 -0
  188. package/src/memory/__tests__/session-memory.test.js.map +1 -1
  189. package/src/memory/__tests__/session-memory.test.ts +17 -0
  190. package/src/memory/brain-links.ts +17 -0
  191. package/src/memory/brain-maintenance.ts +33 -1
  192. package/src/memory/brain-retrieval.ts +19 -3
  193. package/src/memory/decisions.ts +18 -2
  194. package/src/memory/engine-compat.ts +392 -25
  195. package/src/memory/index.ts +417 -4
  196. package/src/metrics/token-service.ts +4 -4
  197. package/src/migration/index.ts +1 -1
  198. package/src/orchestration/hierarchy.ts +202 -0
  199. package/src/orchestration/index.ts +1 -0
  200. package/src/paths.ts +340 -5
  201. package/src/routing/capability-matrix.ts +49 -49
  202. package/src/scaffold.ts +428 -70
  203. package/src/security/input-sanitization.ts +4 -4
  204. package/src/sessions/__tests__/session-grade.integration.test.js +9 -9
  205. package/src/sessions/__tests__/session-grade.integration.test.ts +9 -9
  206. package/src/sessions/__tests__/session-grade.test.js +10 -10
  207. package/src/sessions/__tests__/session-grade.test.js.map +1 -1
  208. package/src/sessions/__tests__/session-grade.test.ts +10 -10
  209. package/src/sessions/session-grade.ts +4 -4
  210. package/src/skills/__tests__/dynamic-skill-generator.test.js +24 -26
  211. package/src/skills/__tests__/dynamic-skill-generator.test.js.map +1 -1
  212. package/src/skills/__tests__/dynamic-skill-generator.test.ts +24 -26
  213. package/src/skills/__tests__/routing-table.test.js +22 -22
  214. package/src/skills/__tests__/routing-table.test.js.map +1 -1
  215. package/src/skills/__tests__/routing-table.test.ts +23 -23
  216. package/src/skills/dynamic-skill-generator.ts +13 -24
  217. package/src/skills/routing-table.ts +4 -4
  218. package/src/store/__tests__/data-safety-central.test.js +8 -0
  219. package/src/store/__tests__/data-safety-central.test.js.map +1 -1
  220. package/src/store/__tests__/data-safety-central.test.ts +8 -0
  221. package/src/store/__tests__/safety-accessor.test.js +8 -0
  222. package/src/store/__tests__/safety-accessor.test.js.map +1 -1
  223. package/src/store/__tests__/safety-accessor.test.ts +8 -0
  224. package/src/store/agent-registry-accessor.ts +284 -108
  225. package/src/store/cross-db-cleanup.ts +175 -1
  226. package/src/store/provider.ts +2 -2
  227. package/src/store/signaldock-sqlite.ts +262 -60
  228. package/src/store/sqlite-data-accessor.ts +3 -0
  229. package/src/store/sqlite.ts +2 -2
  230. package/src/store/task-store.ts +8 -1
  231. package/src/store/tasks-schema.ts +5 -40
  232. package/src/system/__tests__/health.test.js +2 -2
  233. package/src/system/__tests__/health.test.js.map +1 -1
  234. package/src/system/__tests__/health.test.ts +2 -2
  235. package/src/system/archive-analytics.ts +1 -1
  236. package/src/system/health.ts +43 -19
  237. package/src/system/inject-generate.ts +20 -20
  238. package/src/system/runtime.ts +5 -4
  239. package/src/tasks/atomicity.ts +1 -1
  240. package/src/tasks/list.ts +1 -1
  241. package/src/tasks/task-ops.ts +415 -3
  242. package/src/templates/parser.ts +1 -1
  243. package/src/ui/index.ts +4 -4
  244. package/src/upgrade.ts +3 -14
  245. package/src/validation/operation-gate-validators.ts +1 -1
  246. package/src/validation/operation-verification-gates.ts +3 -3
  247. package/src/validation/param-utils.ts +11 -10
  248. package/src/validation/validate-ops.ts +6 -6
  249. package/templates/CLEO-INJECTION.md +38 -110
  250. package/dist/hooks/handlers/mcp-hooks.d.ts +0 -48
  251. package/dist/hooks/handlers/mcp-hooks.d.ts.map +0 -1
  252. package/dist/mcp/index.d.ts +0 -42
  253. package/dist/mcp/index.d.ts.map +0 -1
  254. package/src/__tests__/audit-prune.test.d.ts +0 -2
  255. package/src/__tests__/caamp-skill-install.test.d.ts +0 -14
  256. package/src/__tests__/cli-mcp-parity.integration.test.d.ts +0 -34
  257. package/src/__tests__/cli-mcp-parity.integration.test.d.ts.map +0 -1
  258. package/src/__tests__/cli-mcp-parity.integration.test.js +0 -898
  259. package/src/__tests__/cli-mcp-parity.integration.test.js.map +0 -1
  260. package/src/__tests__/cli-parity.test.d.ts +0 -9
  261. package/src/__tests__/config.test.d.ts +0 -7
  262. package/src/__tests__/core-parity.test.d.ts +0 -17
  263. package/src/__tests__/error-catalog.test.d.ts +0 -2
  264. package/src/__tests__/golden-parity.test.d.ts +0 -12
  265. package/src/__tests__/hooks.test.d.ts +0 -5
  266. package/src/__tests__/human-output.test.d.ts +0 -12
  267. package/src/__tests__/index-api-compat.test.d.ts +0 -2
  268. package/src/__tests__/init-e2e.test.d.ts +0 -12
  269. package/src/__tests__/injection-chain.test.d.ts +0 -18
  270. package/src/__tests__/injection-mvi-tiers.test.d.ts +0 -14
  271. package/src/__tests__/injection-shared.test.d.ts +0 -10
  272. package/src/__tests__/lafs-conformance.test.d.ts +0 -18
  273. package/src/__tests__/logger.test.d.ts +0 -2
  274. package/src/__tests__/mcp-install-verify.test.d.ts +0 -13
  275. package/src/__tests__/mcp-install-verify.test.d.ts.map +0 -1
  276. package/src/__tests__/mcp-install-verify.test.js +0 -177
  277. package/src/__tests__/mcp-install-verify.test.js.map +0 -1
  278. package/src/__tests__/mcp-install-verify.test.ts +0 -217
  279. package/src/__tests__/paths.test.d.ts +0 -7
  280. package/src/__tests__/project-info.test.d.ts +0 -2
  281. package/src/__tests__/rcsd-pipeline-e2e.test.d.ts +0 -14
  282. package/src/__tests__/remote.test.d.ts +0 -6
  283. package/src/__tests__/scaffold.test.d.ts +0 -6
  284. package/src/__tests__/schema-management.test.d.ts +0 -5
  285. package/src/__tests__/schema.test.d.ts +0 -2
  286. package/src/__tests__/sharing.test.d.ts +0 -6
  287. package/src/__tests__/snapshot.test.d.ts +0 -6
  288. package/src/__tests__/upgrade.test.d.ts +0 -7
  289. package/src/adapters/__tests__/discovery.test.d.ts +0 -6
  290. package/src/adapters/__tests__/manager.test.d.ts +0 -6
  291. package/src/agents/__tests__/agent-registry.test.d.ts +0 -12
  292. package/src/agents/__tests__/capacity.test.d.ts +0 -7
  293. package/src/agents/__tests__/execution-learning.test.d.ts +0 -14
  294. package/src/agents/__tests__/health-monitor.test.d.ts +0 -10
  295. package/src/agents/__tests__/registry.test.d.ts +0 -8
  296. package/src/agents/__tests__/retry.test.d.ts +0 -7
  297. package/src/compliance/__tests__/sync.test.d.ts +0 -5
  298. package/src/hooks/__tests__/provider-hooks.test.d.ts +0 -2
  299. package/src/hooks/__tests__/registry.test.d.ts +0 -2
  300. package/src/hooks/handlers/__tests__/error-hooks.test.d.ts +0 -2
  301. package/src/hooks/handlers/__tests__/file-hooks.test.d.ts +0 -2
  302. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.d.ts +0 -13
  303. package/src/hooks/handlers/__tests__/mcp-hooks.test.d.ts +0 -2
  304. package/src/hooks/handlers/__tests__/mcp-hooks.test.d.ts.map +0 -1
  305. package/src/hooks/handlers/__tests__/mcp-hooks.test.js +0 -119
  306. package/src/hooks/handlers/__tests__/mcp-hooks.test.js.map +0 -1
  307. package/src/hooks/handlers/__tests__/mcp-hooks.test.ts +0 -150
  308. package/src/hooks/handlers/__tests__/session-hooks.test.d.ts +0 -2
  309. package/src/hooks/handlers/__tests__/task-hooks.test.d.ts +0 -2
  310. package/src/hooks/handlers/mcp-hooks.ts +0 -162
  311. package/src/intelligence/__tests__/adaptive-validation.test.d.ts +0 -11
  312. package/src/intelligence/__tests__/impact.test.d.ts +0 -16
  313. package/src/intelligence/__tests__/patterns.test.d.ts +0 -8
  314. package/src/intelligence/__tests__/prediction.test.d.ts +0 -8
  315. package/src/lib/__tests__/retry.test.d.ts +0 -7
  316. package/src/lifecycle/__tests__/chain-store.test.d.ts +0 -10
  317. package/src/lifecycle/__tests__/consolidate-rcasd.test.d.ts +0 -7
  318. package/src/lifecycle/__tests__/default-chain.test.d.ts +0 -7
  319. package/src/lifecycle/__tests__/frontmatter.test.d.ts +0 -7
  320. package/src/lifecycle/__tests__/lifecycle.test.d.ts +0 -7
  321. package/src/lifecycle/__tests__/pipeline.integration.test.d.ts +0 -19
  322. package/src/lifecycle/__tests__/rcasd-paths.test.d.ts +0 -7
  323. package/src/lifecycle/__tests__/resume-schema-contract.test.d.ts +0 -16
  324. package/src/lifecycle/__tests__/stage-record-provenance.integration.test.d.ts +0 -7
  325. package/src/lifecycle/__tests__/tessera-engine.test.d.ts +0 -10
  326. package/src/mcp/index.ts +0 -163
  327. package/src/memory/__tests__/auto-extract.test.d.ts +0 -7
  328. package/src/memory/__tests__/brain-automation.test.d.ts +0 -11
  329. package/src/memory/__tests__/brain-embedding.test.d.ts +0 -2
  330. package/src/memory/__tests__/brain-links.test.d.ts +0 -8
  331. package/src/memory/__tests__/brain-migration.test.d.ts +0 -8
  332. package/src/memory/__tests__/brain-retrieval.test.d.ts +0 -10
  333. package/src/memory/__tests__/brain-search.test.d.ts +0 -8
  334. package/src/memory/__tests__/claude-mem-migration.test.d.ts +0 -12
  335. package/src/memory/__tests__/decisions.test.d.ts +0 -8
  336. package/src/memory/__tests__/engine-compat.test.d.ts +0 -12
  337. package/src/memory/__tests__/memory-bridge.test.d.ts +0 -10
  338. package/src/memory/__tests__/pipeline-manifest-sqlite.test.d.ts +0 -13
  339. package/src/memory/__tests__/session-memory.test.d.ts +0 -9
  340. package/src/metrics/__tests__/model-provider-registry.test.d.ts +0 -2
  341. package/src/metrics/__tests__/provider-detection.test.d.ts +0 -2
  342. package/src/migration/__tests__/checksum.test.d.ts +0 -8
  343. package/src/migration/__tests__/logger.test.d.ts +0 -5
  344. package/src/migration/__tests__/migration-failure.integration.test.d.ts +0 -15
  345. package/src/migration/__tests__/migration.test.d.ts +0 -13
  346. package/src/migration/__tests__/state.test.d.ts +0 -8
  347. package/src/migration/__tests__/validate.test.d.ts +0 -8
  348. package/src/nexus/__tests__/deps.test.d.ts +0 -7
  349. package/src/nexus/__tests__/nexus-e2e.test.d.ts +0 -12
  350. package/src/nexus/__tests__/permissions.test.d.ts +0 -7
  351. package/src/nexus/__tests__/query.test.d.ts +0 -7
  352. package/src/nexus/__tests__/reconcile.test.d.ts +0 -7
  353. package/src/nexus/__tests__/registry.test.d.ts +0 -7
  354. package/src/nexus/__tests__/transfer.test.d.ts +0 -8
  355. package/src/observability/__tests__/index.test.d.ts +0 -7
  356. package/src/observability/__tests__/log-filter.test.d.ts +0 -7
  357. package/src/observability/__tests__/log-parser.test.d.ts +0 -7
  358. package/src/observability/__tests__/log-reader.test.d.ts +0 -7
  359. package/src/orchestration/__tests__/autonomous-spec.test.d.ts +0 -9
  360. package/src/orchestration/__tests__/orchestration.test.d.ts +0 -7
  361. package/src/orchestration/__tests__/protocol-validators.test.d.ts +0 -9
  362. package/src/phases/__tests__/deps.test.d.ts +0 -7
  363. package/src/phases/__tests__/phases.test.d.ts +0 -7
  364. package/src/release/__tests__/artifacts.test.d.ts +0 -7
  365. package/src/release/__tests__/cancel-release.test.d.ts +0 -10
  366. package/src/release/__tests__/changelog-writer.test.d.ts +0 -6
  367. package/src/release/__tests__/push-policy.test.d.ts +0 -14
  368. package/src/release/__tests__/release.test.d.ts +0 -11
  369. package/src/sequence/__tests__/allocate.test.d.ts +0 -6
  370. package/src/sessions/__tests__/briefing-blocked.test.d.ts +0 -6
  371. package/src/sessions/__tests__/briefing.test.d.ts +0 -11
  372. package/src/sessions/__tests__/handoff-integration.test.d.ts +0 -8
  373. package/src/sessions/__tests__/handoff.test.d.ts +0 -11
  374. package/src/sessions/__tests__/index.test.d.ts +0 -2
  375. package/src/sessions/__tests__/session-cleanup.test.d.ts +0 -7
  376. package/src/sessions/__tests__/session-edge-cases.test.d.ts +0 -9
  377. package/src/sessions/__tests__/session-find.test.d.ts +0 -9
  378. package/src/sessions/__tests__/session-grade.integration.test.d.ts +0 -11
  379. package/src/sessions/__tests__/session-grade.test.d.ts +0 -6
  380. package/src/sessions/__tests__/session-memory-bridge.test.d.ts +0 -2
  381. package/src/sessions/__tests__/sessions.test.d.ts +0 -7
  382. package/src/skills/__tests__/discovery.test.d.ts +0 -6
  383. package/src/skills/__tests__/dispatch.test.d.ts +0 -6
  384. package/src/skills/__tests__/dynamic-skill-generator.test.d.ts +0 -2
  385. package/src/skills/__tests__/manifests.test.d.ts +0 -6
  386. package/src/skills/__tests__/precedence.test.d.ts +0 -6
  387. package/src/skills/__tests__/routing-table.test.d.ts +0 -2
  388. package/src/skills/__tests__/skill-paths.test.d.ts +0 -7
  389. package/src/skills/__tests__/test-utility.test.d.ts +0 -7
  390. package/src/skills/__tests__/token.test.d.ts +0 -6
  391. package/src/skills/__tests__/validation.test.d.ts +0 -6
  392. package/src/skills/__tests__/version.test.d.ts +0 -5
  393. package/src/skills/injection/__tests__/subagent.test.d.ts +0 -2
  394. package/src/skills/orchestrator/__tests__/spawn-tier.test.d.ts +0 -2
  395. package/src/spawn/__tests__/adapter-registry.test.d.ts +0 -2
  396. package/src/stats/__tests__/stats.test.d.ts +0 -7
  397. package/src/sticky/__tests__/purge.test.d.ts +0 -9
  398. package/src/store/__tests__/atomic.test.d.ts +0 -7
  399. package/src/store/__tests__/backup.test.d.ts +0 -7
  400. package/src/store/__tests__/brain-accessor-pageindex.test.d.ts +0 -12
  401. package/src/store/__tests__/brain-accessor.test.d.ts +0 -10
  402. package/src/store/__tests__/brain-pageindex.test.d.ts +0 -11
  403. package/src/store/__tests__/brain-schema.test.d.ts +0 -11
  404. package/src/store/__tests__/brain-vec.test.d.ts +0 -11
  405. package/src/store/__tests__/collision-detection.test.d.ts +0 -11
  406. package/src/store/__tests__/data-safety-central.test.d.ts +0 -20
  407. package/src/store/__tests__/db-helpers.test.d.ts +0 -7
  408. package/src/store/__tests__/e2e-safety-integration.test.d.ts +0 -13
  409. package/src/store/__tests__/git-checkpoint.test.d.ts +0 -7
  410. package/src/store/__tests__/idempotent-migration.test.d.ts +0 -5
  411. package/src/store/__tests__/import-logging.test.d.ts +0 -7
  412. package/src/store/__tests__/import-sort.test.d.ts +0 -7
  413. package/src/store/__tests__/json.test.d.ts +0 -7
  414. package/src/store/__tests__/lifecycle-schema-parity.test.d.ts +0 -2
  415. package/src/store/__tests__/migration-integration.test.d.ts +0 -15
  416. package/src/store/__tests__/migration-retry.test.d.ts +0 -10
  417. package/src/store/__tests__/migration-safety.test.d.ts +0 -21
  418. package/src/store/__tests__/migration-sqlite.test.d.ts +0 -11
  419. package/src/store/__tests__/performance-safety.test.d.ts +0 -17
  420. package/src/store/__tests__/project-detect.test.d.ts +0 -6
  421. package/src/store/__tests__/project-registry.test.d.ts +0 -7
  422. package/src/store/__tests__/provider.test.d.ts +0 -9
  423. package/src/store/__tests__/relations.test.d.ts +0 -9
  424. package/src/store/__tests__/safety-accessor.test.d.ts +0 -18
  425. package/src/store/__tests__/sequence-validation.test.d.ts +0 -11
  426. package/src/store/__tests__/session-store.test.d.ts +0 -11
  427. package/src/store/__tests__/sqlite-backup.test.d.ts +0 -14
  428. package/src/store/__tests__/sqlite.test.d.ts +0 -11
  429. package/src/store/__tests__/task-store.test.d.ts +0 -11
  430. package/src/store/__tests__/test-db-helper.d.ts +0 -61
  431. package/src/store/__tests__/write-verification.test.d.ts +0 -11
  432. package/src/system/__tests__/cleanup.test.d.ts +0 -2
  433. package/src/system/__tests__/health.test.d.ts +0 -2
  434. package/src/task-work/__tests__/start-deps.test.d.ts +0 -6
  435. package/src/tasks/__tests__/add.test.d.ts +0 -7
  436. package/src/tasks/__tests__/archive.test.d.ts +0 -7
  437. package/src/tasks/__tests__/assignee.test.d.ts +0 -14
  438. package/src/tasks/__tests__/atomicity.test.d.ts +0 -6
  439. package/src/tasks/__tests__/cancel-ops.test.d.ts +0 -7
  440. package/src/tasks/__tests__/complete-unblocks.test.d.ts +0 -6
  441. package/src/tasks/__tests__/complete.test.d.ts +0 -7
  442. package/src/tasks/__tests__/delete.test.d.ts +0 -7
  443. package/src/tasks/__tests__/dependency-check.test.d.ts +0 -7
  444. package/src/tasks/__tests__/deps-ready.test.d.ts +0 -6
  445. package/src/tasks/__tests__/epic-enforcement.test.d.ts +0 -15
  446. package/src/tasks/__tests__/find.test.d.ts +0 -7
  447. package/src/tasks/__tests__/graph-ops.test.d.ts +0 -7
  448. package/src/tasks/__tests__/hierarchy-policy.test.d.ts +0 -6
  449. package/src/tasks/__tests__/hierarchy.test.d.ts +0 -7
  450. package/src/tasks/__tests__/id-generator.test.d.ts +0 -2
  451. package/src/tasks/__tests__/labels.test.d.ts +0 -7
  452. package/src/tasks/__tests__/list.test.d.ts +0 -7
  453. package/src/tasks/__tests__/minimal-test.test.d.ts +0 -2
  454. package/src/tasks/__tests__/phase-tracking.test.d.ts +0 -7
  455. package/src/tasks/__tests__/pipeline-stage.test.d.ts +0 -14
  456. package/src/tasks/__tests__/plan-priority.test.d.ts +0 -10
  457. package/src/tasks/__tests__/priority-normalization.test.d.ts +0 -7
  458. package/src/tasks/__tests__/relates.test.d.ts +0 -9
  459. package/src/tasks/__tests__/show-deps.test.d.ts +0 -6
  460. package/src/tasks/__tests__/show.test.d.ts +0 -7
  461. package/src/tasks/__tests__/staleness.test.d.ts +0 -7
  462. package/src/tasks/__tests__/task-ops-depends.test.d.ts +0 -6
  463. package/src/tasks/__tests__/update.test.d.ts +0 -7
  464. package/src/validation/__tests__/chain-validation.test.d.ts +0 -7
  465. package/src/validation/__tests__/compliance.test.d.ts +0 -7
  466. package/src/validation/__tests__/docs-sync.test.d.ts +0 -7
  467. package/src/validation/__tests__/doctor-gitignore.test.d.ts +0 -7
  468. package/src/validation/__tests__/doctor-injection.test.d.ts +0 -11
  469. package/src/validation/__tests__/doctor.test.d.ts +0 -7
  470. package/src/validation/__tests__/engine.test.d.ts +0 -7
  471. package/src/validation/__tests__/manifest.test.d.ts +0 -7
  472. package/src/validation/__tests__/protocol-common.test.d.ts +0 -7
  473. package/src/validation/__tests__/verification.test.d.ts +0 -7
@@ -1,898 +0,0 @@
1
- /**
2
- * CLI/MCP Parity Integration Tests
3
- *
4
- * Verifies that the CLI and MCP paths produce identical results for shared
5
- * operations. Both CLI and MCP ultimately route through the same domain
6
- * handlers (TasksHandler, SessionHandler, etc.), which delegate to the same
7
- * src/core/ functions.
8
- *
9
- * Test strategy:
10
- * 1. Direct domain handler parity — call handler.query()/handler.mutate()
11
- * and dispatchRaw() for the same operation; assert identical data.
12
- * 2. CLI dispatch path — call dispatchRaw() and verify it reaches the same
13
- * handler as MCP would via createDomainHandlers().
14
- * 3. Cross-adapter data identity — same mock engine function is called with
15
- * identical args from both CLI and MCP code paths.
16
- * 4. MCP gateway normalization gap — document that handleMcpToolCall passes
17
- * 'cleo_query' as gateway but the registry expects 'query' (a real gap).
18
- *
19
- * Architecture under test:
20
- * CLI: dispatchRaw('query', domain, op, params)
21
- * → getCliDispatcher() → Dispatcher (sanitizer mw)
22
- * → TasksHandler.query(op, params)
23
- * → task-engine fn → core/tasks/*
24
- *
25
- * MCP: handleMcpToolCall('cleo_query', domain, op, params)
26
- * → getMcpDispatcher() → Dispatcher (sanitizer+rl+gates+protocol+audit mw)
27
- * → same TasksHandler.query(op, params) [same handler instance via createDomainHandlers()]
28
- * → same task-engine fn → same core/tasks/*
29
- *
30
- * @task T4796
31
- * @epic T4654
32
- */
33
- import { beforeEach, describe, expect, it, vi } from 'vitest';
34
- // ===========================================================================
35
- // Mocks — all engine functions and MCP-only middleware
36
- // ===========================================================================
37
- // --- task-engine mocks ---
38
- vi.mock('../../dispatch/engines/task-engine.js', () => ({
39
- taskShow: vi.fn(),
40
- taskList: vi.fn(),
41
- taskFind: vi.fn(),
42
- taskExists: vi.fn(),
43
- taskCreate: vi.fn(),
44
- taskUpdate: vi.fn(),
45
- taskComplete: vi.fn(),
46
- taskDelete: vi.fn(),
47
- taskArchive: vi.fn(),
48
- taskNext: vi.fn(),
49
- taskBlockers: vi.fn(),
50
- taskTree: vi.fn(),
51
- taskRelates: vi.fn(),
52
- taskRelatesAdd: vi.fn(),
53
- taskAnalyze: vi.fn(),
54
- taskRestore: vi.fn(),
55
- taskReorder: vi.fn(),
56
- taskReparent: vi.fn(),
57
- taskPromote: vi.fn(),
58
- taskReopen: vi.fn(),
59
- taskComplexityEstimate: vi.fn(),
60
- taskDepends: vi.fn(),
61
- }));
62
- // --- session-engine mocks (hosts taskStart/taskStop/taskCurrentGet) ---
63
- vi.mock('../../dispatch/engines/session-engine.js', () => ({
64
- sessionStatus: vi.fn(),
65
- sessionList: vi.fn(),
66
- sessionShow: vi.fn(),
67
- sessionStart: vi.fn(),
68
- sessionEnd: vi.fn(),
69
- sessionResume: vi.fn(),
70
- sessionSuspend: vi.fn(),
71
- sessionGc: vi.fn(),
72
- sessionHistory: vi.fn(),
73
- sessionRecordDecision: vi.fn(),
74
- sessionDecisionLog: vi.fn(),
75
- sessionContextDrift: vi.fn(),
76
- sessionRecordAssumption: vi.fn(),
77
- taskCurrentGet: vi.fn(),
78
- taskStart: vi.fn(),
79
- taskStop: vi.fn(),
80
- }));
81
- // --- system-engine mocks ---
82
- vi.mock('../../dispatch/engines/system-engine.js', () => ({
83
- systemDash: vi.fn(),
84
- systemStats: vi.fn(),
85
- systemLog: vi.fn(),
86
- systemContext: vi.fn(),
87
- systemSequence: vi.fn(),
88
- systemHealth: vi.fn(),
89
- systemInjectGenerate: vi.fn(),
90
- systemBackup: vi.fn(),
91
- systemRestore: vi.fn(),
92
- systemMigrate: vi.fn(),
93
- systemCleanup: vi.fn(),
94
- systemSync: vi.fn(),
95
- systemSafestop: vi.fn(),
96
- }));
97
- // --- lifecycle-engine mocks ---
98
- vi.mock('../../dispatch/engines/lifecycle-engine.js', () => ({
99
- lifecycleStatus: vi.fn(),
100
- lifecycleHistory: vi.fn(),
101
- lifecycleGates: vi.fn(),
102
- lifecyclePrerequisites: vi.fn(),
103
- lifecycleCheck: vi.fn(),
104
- lifecycleProgress: vi.fn(),
105
- lifecycleSkip: vi.fn(),
106
- lifecycleReset: vi.fn(),
107
- lifecycleGatePass: vi.fn(),
108
- lifecycleGateFail: vi.fn(),
109
- LIFECYCLE_STAGES: [
110
- 'research',
111
- 'consensus',
112
- 'architecture_decision',
113
- 'specification',
114
- 'decomposition',
115
- 'implementation',
116
- 'validation',
117
- 'testing',
118
- 'release',
119
- 'contribution',
120
- ],
121
- }));
122
- // --- orchestrate-engine mocks ---
123
- vi.mock('../../dispatch/engines/orchestrate-engine.js', () => ({
124
- orchestrateStatus: vi.fn(),
125
- orchestrateAnalyze: vi.fn(),
126
- orchestrateReady: vi.fn(),
127
- orchestrateNext: vi.fn(),
128
- orchestrateWaves: vi.fn(),
129
- orchestrateContext: vi.fn(),
130
- orchestrateValidate: vi.fn(),
131
- orchestrateSpawn: vi.fn(),
132
- orchestrateStartup: vi.fn(),
133
- orchestrateBootstrap: vi.fn(),
134
- orchestrateCriticalPath: vi.fn(),
135
- orchestrateUnblockOpportunities: vi.fn(),
136
- orchestrateParallelStart: vi.fn(),
137
- orchestrateParallelEnd: vi.fn(),
138
- orchestrateCheck: vi.fn(),
139
- orchestrateSkillInject: vi.fn(),
140
- }));
141
- // --- validate-engine mocks ---
142
- vi.mock('../../dispatch/engines/validate-engine.js', () => ({
143
- validateSchemaOp: vi.fn(),
144
- validateTask: vi.fn(),
145
- validateProtocol: vi.fn(),
146
- validateManifest: vi.fn(),
147
- validateOutput: vi.fn(),
148
- validateComplianceSummary: vi.fn(),
149
- validateComplianceViolations: vi.fn(),
150
- validateComplianceRecord: vi.fn(),
151
- validateTestStatus: vi.fn(),
152
- validateTestCoverage: vi.fn(),
153
- validateCoherenceCheck: vi.fn(),
154
- validateTestRun: vi.fn(),
155
- validateBatchValidate: vi.fn(),
156
- }));
157
- // --- release-engine mocks ---
158
- vi.mock('../../dispatch/engines/release-engine.js', () => ({
159
- releasePrepare: vi.fn(),
160
- releaseChangelog: vi.fn(),
161
- releaseList: vi.fn(),
162
- releaseShow: vi.fn(),
163
- releaseCommit: vi.fn(),
164
- releaseTag: vi.fn(),
165
- releaseGatesRun: vi.fn(),
166
- releaseRollback: vi.fn(),
167
- releasePush: vi.fn(),
168
- }));
169
- // --- memory engine mock (brain.db backed after T5241 cutover) ---
170
- vi.mock('../../core/memory/engine-compat.js', () => ({
171
- memoryShow: vi.fn(),
172
- memoryFind: vi.fn(),
173
- memoryTimeline: vi.fn(),
174
- memoryFetch: vi.fn(),
175
- memoryObserve: vi.fn(),
176
- memoryBrainStats: vi.fn(),
177
- memoryDecisionFind: vi.fn(),
178
- memoryDecisionStore: vi.fn(),
179
- memoryPatternFind: vi.fn(),
180
- memoryPatternStats: vi.fn(),
181
- memoryPatternStore: vi.fn(),
182
- memoryLearningFind: vi.fn(),
183
- memoryLearningStats: vi.fn(),
184
- memoryLearningStore: vi.fn(),
185
- }));
186
- // --- pipeline manifest mock (moved from memory domain in T5241) ---
187
- vi.mock('../../core/memory/pipeline-manifest-sqlite.js', () => ({
188
- pipelineManifestShow: vi.fn(),
189
- pipelineManifestList: vi.fn(),
190
- pipelineManifestFind: vi.fn(),
191
- pipelineManifestPending: vi.fn(),
192
- pipelineManifestStats: vi.fn(),
193
- pipelineManifestRead: vi.fn(),
194
- pipelineManifestAppend: vi.fn(),
195
- pipelineManifestArchive: vi.fn(),
196
- pipelineManifestLink: vi.fn(),
197
- pipelineManifestContradictions: vi.fn(),
198
- pipelineManifestSuperseded: vi.fn(),
199
- pipelineManifestCompact: vi.fn(),
200
- pipelineManifestValidate: vi.fn(),
201
- readManifestEntries: vi.fn(),
202
- filterEntries: vi.fn(),
203
- }));
204
- // --- dispatch/lib/engine (config + init) ---
205
- vi.mock('../../dispatch/lib/engine.js', () => {
206
- return {
207
- // Tasks
208
- taskShow: vi.fn(),
209
- taskList: vi.fn(),
210
- taskFind: vi.fn(),
211
- taskCreate: vi.fn(),
212
- taskComplete: vi.fn(),
213
- taskUpdate: vi.fn(),
214
- taskDelete: vi.fn(),
215
- taskCurrentGet: vi.fn(),
216
- taskStart: vi.fn(),
217
- taskStop: vi.fn(),
218
- // Session
219
- sessionStatus: vi.fn(),
220
- sessionList: vi.fn(),
221
- sessionStart: vi.fn(),
222
- sessionContextInject: vi.fn(),
223
- configGet: vi.fn(),
224
- configSet: vi.fn(),
225
- getVersion: vi.fn(() => ({ success: true, data: { version: '1.0.0' } })),
226
- initProject: vi.fn(),
227
- isAutoInitEnabled: vi.fn(() => false),
228
- ensureInitialized: vi.fn(() => ({ success: true, data: { initialized: true } })),
229
- };
230
- });
231
- // --- template-parser mocks ---
232
- vi.mock('../../dispatch/engines/template-parser.js', () => ({
233
- parseIssueTemplates: vi.fn(),
234
- getTemplateForSubcommand: vi.fn(),
235
- generateTemplateConfig: vi.fn(),
236
- validateLabels: vi.fn(),
237
- }));
238
- // --- paths ---
239
- vi.mock('../../core/paths.js', () => ({
240
- getProjectRoot: vi.fn(() => '/mock/project'),
241
- }));
242
- // --- MCP-only middleware (passthrough stubs to avoid blocking tests) ---
243
- vi.mock('../../dispatch/middleware/rate-limiter.js', () => ({
244
- createRateLimiter: vi.fn(() => async (_req, next) => next()),
245
- }));
246
- vi.mock('../../dispatch/middleware/verification-gates.js', () => ({
247
- createVerificationGates: vi.fn(() => async (_req, next) => next()),
248
- }));
249
- vi.mock('../../dispatch/middleware/protocol-enforcement.js', () => ({
250
- createProtocolEnforcement: vi.fn(() => async (_req, next) => next()),
251
- }));
252
- vi.mock('../../dispatch/middleware/audit.js', () => ({
253
- createAudit: vi.fn(() => async (_req, next) => next()),
254
- }));
255
- // --- MCP rate-limiter config dependency ---
256
- vi.mock('../../mcp/lib/rate-limiter.js', () => ({
257
- RateLimiter: vi.fn(),
258
- createRateLimiter: vi.fn(),
259
- }));
260
- // --- security (sanitizer) ---
261
- vi.mock('../../dispatch/lib/security.js', () => ({
262
- sanitizeParams: vi.fn((p) => p),
263
- }));
264
- vi.mock('../../mcp/lib/security.js', () => ({
265
- sanitizeParams: vi.fn((p) => p),
266
- }));
267
- // ===========================================================================
268
- // Imports (AFTER all vi.mock() calls)
269
- // ===========================================================================
270
- import { dispatchRaw, resetCliDispatcher } from '../../dispatch/adapters/cli.js';
271
- import { handleMcpToolCall, resetMcpDispatcher } from '../../dispatch/adapters/mcp.js';
272
- import { SessionHandler } from '../../dispatch/domains/session.js';
273
- import { TasksHandler } from '../../dispatch/domains/tasks.js';
274
- import { sessionList, sessionStart, sessionStatus, taskComplete, taskCreate, taskCurrentGet, taskDelete, taskFind, taskList, taskShow, taskStart, taskStop, taskUpdate, } from '../../dispatch/lib/engine.js';
275
- // ===========================================================================
276
- // Helpers
277
- // ===========================================================================
278
- /**
279
- * Strip _meta from a DispatchResponse for data-only comparison.
280
- * _meta legitimately differs between CLI (source:'cli') and MCP (source:'mcp').
281
- */
282
- function stripMeta(response) {
283
- const { _meta: _ignored, ...rest } = response;
284
- return rest;
285
- }
286
- // ===========================================================================
287
- // Setup
288
- // ===========================================================================
289
- beforeEach(() => {
290
- vi.clearAllMocks();
291
- // Reset dispatcher singletons so each test gets a fresh dispatcher instance
292
- resetCliDispatcher();
293
- resetMcpDispatcher();
294
- });
295
- // ===========================================================================
296
- // Section 1: Direct Domain Handler Parity
297
- //
298
- // Calls the domain handler directly (simulating what both CLI dispatch and MCP
299
- // dispatch ultimately do) and verifies identical data for each operation.
300
- // ===========================================================================
301
- describe('Section 1: Direct domain handler parity (T4796)', () => {
302
- let tasksHandler;
303
- beforeEach(() => {
304
- tasksHandler = new TasksHandler();
305
- });
306
- // -------------------------------------------------------------------------
307
- // tasks.show
308
- // -------------------------------------------------------------------------
309
- describe('tasks.show', () => {
310
- const TASK_DATA = {
311
- task: {
312
- id: 'T001',
313
- title: 'Alpha task',
314
- status: 'pending',
315
- priority: 'high',
316
- },
317
- };
318
- beforeEach(() => {
319
- vi.mocked(taskShow).mockResolvedValue({ success: true, data: TASK_DATA });
320
- });
321
- it('handler.query("show") and dispatchRaw produce identical data', async () => {
322
- const handlerResult = await tasksHandler.query('show', { taskId: 'T001' });
323
- const cliResult = await dispatchRaw('query', 'tasks', 'show', {
324
- taskId: 'T001',
325
- });
326
- expect(handlerResult.success).toBe(true);
327
- expect(cliResult.success).toBe(true);
328
- // Both produce the same data payload
329
- expect(handlerResult.data).toEqual(TASK_DATA);
330
- expect(cliResult.data).toEqual(TASK_DATA);
331
- expect(handlerResult.data).toEqual(cliResult.data);
332
- });
333
- it('handler.query("show") and dispatchRaw both fail for missing taskId', async () => {
334
- const handlerResult = await tasksHandler.query('show', {});
335
- const cliResult = await dispatchRaw('query', 'tasks', 'show', {});
336
- expect(handlerResult.success).toBe(false);
337
- expect(cliResult.success).toBe(false);
338
- // Both return E_INVALID_INPUT
339
- expect(handlerResult.error?.code).toBe('E_INVALID_INPUT');
340
- expect(cliResult.error?.code).toBe('E_INVALID_INPUT');
341
- });
342
- it('taskShow engine called with identical args from handler and dispatchRaw', async () => {
343
- await tasksHandler.query('show', { taskId: 'T001' });
344
- await dispatchRaw('query', 'tasks', 'show', { taskId: 'T001' });
345
- expect(taskShow).toHaveBeenCalledTimes(2);
346
- // Both calls pass the same projectRoot and taskId
347
- expect(vi.mocked(taskShow).mock.calls[0]).toEqual(vi.mocked(taskShow).mock.calls[1]);
348
- });
349
- });
350
- // -------------------------------------------------------------------------
351
- // tasks.list
352
- // -------------------------------------------------------------------------
353
- describe('tasks.list', () => {
354
- const LIST_DATA = {
355
- tasks: [
356
- { id: 'T001', title: 'Alpha', status: 'pending', priority: 'medium' },
357
- { id: 'T002', title: 'Beta', status: 'active', priority: 'high' },
358
- ],
359
- total: 2,
360
- filtered: 2,
361
- };
362
- const LIST_PAGE = { mode: 'none' };
363
- beforeEach(() => {
364
- vi.mocked(taskList).mockResolvedValue({ success: true, data: LIST_DATA, page: LIST_PAGE });
365
- });
366
- it('handler.query("list") and dispatchRaw produce identical data (no filters)', async () => {
367
- const handlerResult = await tasksHandler.query('list', {});
368
- const cliResult = await dispatchRaw('query', 'tasks', 'list', {});
369
- expect(handlerResult.success).toBe(true);
370
- expect(cliResult.success).toBe(true);
371
- expect(handlerResult.data).toEqual(cliResult.data);
372
- expect(handlerResult.page).toEqual(cliResult.page);
373
- expect(cliResult.data).toEqual(LIST_DATA);
374
- expect(cliResult.page).toEqual(LIST_PAGE);
375
- });
376
- it('handler.query("list") and dispatchRaw produce identical data with status filter', async () => {
377
- const filteredData = {
378
- tasks: [{ id: 'T001', title: 'Alpha', status: 'pending' }],
379
- total: 1,
380
- filtered: 1,
381
- };
382
- vi.mocked(taskList).mockResolvedValue({ success: true, data: filteredData, page: LIST_PAGE });
383
- const handlerResult = await tasksHandler.query('list', { status: 'pending' });
384
- const cliResult = await dispatchRaw('query', 'tasks', 'list', {
385
- status: 'pending',
386
- });
387
- expect(handlerResult.data).toEqual(cliResult.data);
388
- expect(handlerResult.page).toEqual(cliResult.page);
389
- expect(cliResult.data).toEqual(filteredData);
390
- });
391
- it('taskList engine called with identical args from handler and dispatchRaw', async () => {
392
- await tasksHandler.query('list', { parent: 'T010', limit: 5 });
393
- await dispatchRaw('query', 'tasks', 'list', { parent: 'T010', limit: 5 });
394
- expect(taskList).toHaveBeenCalledTimes(2);
395
- expect(vi.mocked(taskList).mock.calls[0]).toEqual(vi.mocked(taskList).mock.calls[1]);
396
- });
397
- });
398
- // -------------------------------------------------------------------------
399
- // tasks.find
400
- // -------------------------------------------------------------------------
401
- describe('tasks.find', () => {
402
- const FIND_DATA = {
403
- results: [{ id: 'T001', title: 'Alpha task', status: 'pending' }],
404
- total: 1,
405
- };
406
- beforeEach(() => {
407
- vi.mocked(taskFind).mockResolvedValue({ success: true, data: FIND_DATA });
408
- });
409
- it('handler.query("find") and dispatchRaw produce identical data', async () => {
410
- const handlerResult = await tasksHandler.query('find', { query: 'alpha' });
411
- const cliResult = await dispatchRaw('query', 'tasks', 'find', {
412
- query: 'alpha',
413
- });
414
- expect(handlerResult.success).toBe(true);
415
- expect(cliResult.success).toBe(true);
416
- expect(handlerResult.data).toEqual(cliResult.data);
417
- });
418
- it('taskFind engine called with identical args from handler and dispatchRaw', async () => {
419
- const params = { query: 'test', limit: 10 };
420
- await tasksHandler.query('find', params);
421
- await dispatchRaw('query', 'tasks', 'find', params);
422
- expect(taskFind).toHaveBeenCalledTimes(2);
423
- expect(vi.mocked(taskFind).mock.calls[0]).toEqual(vi.mocked(taskFind).mock.calls[1]);
424
- });
425
- });
426
- // -------------------------------------------------------------------------
427
- // tasks.add (mutate)
428
- // -------------------------------------------------------------------------
429
- describe('tasks.add', () => {
430
- const CREATED_DATA = {
431
- task: {
432
- id: 'T100',
433
- title: 'New task',
434
- description: 'Created for parity test',
435
- status: 'pending',
436
- },
437
- };
438
- beforeEach(() => {
439
- vi.mocked(taskCreate).mockResolvedValue({
440
- success: true,
441
- data: CREATED_DATA,
442
- });
443
- });
444
- it('handler.mutate("add") and dispatchRaw produce identical data', async () => {
445
- const params = { title: 'New task', description: 'Created for parity test' };
446
- const handlerResult = await tasksHandler.mutate('add', params);
447
- const cliResult = await dispatchRaw('mutate', 'tasks', 'add', params);
448
- expect(handlerResult.success).toBe(true);
449
- expect(cliResult.success).toBe(true);
450
- expect(handlerResult.data).toEqual(cliResult.data);
451
- expect(cliResult.data).toEqual(CREATED_DATA);
452
- });
453
- it('handler.mutate("add") and dispatchRaw both fail with E_INVALID_INPUT when title missing', async () => {
454
- const handlerResult = await tasksHandler.mutate('add', {
455
- description: 'No title',
456
- });
457
- const cliResult = await dispatchRaw('mutate', 'tasks', 'add', {
458
- description: 'No title',
459
- });
460
- expect(handlerResult.success).toBe(false);
461
- expect(cliResult.success).toBe(false);
462
- expect(handlerResult.error?.code).toBe('E_INVALID_INPUT');
463
- expect(cliResult.error?.code).toBe('E_INVALID_INPUT');
464
- });
465
- it('taskCreate engine called with identical args from handler and dispatchRaw', async () => {
466
- const params = { title: 'New task', description: 'Parity test task' };
467
- await tasksHandler.mutate('add', params);
468
- await dispatchRaw('mutate', 'tasks', 'add', params);
469
- expect(taskCreate).toHaveBeenCalledTimes(2);
470
- expect(vi.mocked(taskCreate).mock.calls[0]).toEqual(vi.mocked(taskCreate).mock.calls[1]);
471
- });
472
- });
473
- // -------------------------------------------------------------------------
474
- // tasks.complete (mutate)
475
- // -------------------------------------------------------------------------
476
- describe('tasks.complete', () => {
477
- const COMPLETE_DATA = {
478
- taskId: 'T001',
479
- completed: true,
480
- completedAt: '2026-02-25T12:00:00Z',
481
- };
482
- beforeEach(() => {
483
- vi.mocked(taskComplete).mockResolvedValue({
484
- success: true,
485
- data: COMPLETE_DATA,
486
- });
487
- });
488
- it('handler.mutate("complete") and dispatchRaw produce identical data', async () => {
489
- const handlerResult = await tasksHandler.mutate('complete', { taskId: 'T001' });
490
- const cliResult = await dispatchRaw('mutate', 'tasks', 'complete', {
491
- taskId: 'T001',
492
- });
493
- expect(handlerResult.success).toBe(true);
494
- expect(cliResult.success).toBe(true);
495
- expect(handlerResult.data).toEqual(cliResult.data);
496
- expect(cliResult.data).toEqual(COMPLETE_DATA);
497
- });
498
- it('handler.mutate("complete") and dispatchRaw both fail with E_INVALID_INPUT when taskId missing', async () => {
499
- const handlerResult = await tasksHandler.mutate('complete', {});
500
- const cliResult = await dispatchRaw('mutate', 'tasks', 'complete', {});
501
- expect(handlerResult.success).toBe(false);
502
- expect(cliResult.success).toBe(false);
503
- expect(handlerResult.error?.code).toBe('E_INVALID_INPUT');
504
- expect(cliResult.error?.code).toBe('E_INVALID_INPUT');
505
- });
506
- it('taskComplete engine called with identical args from handler and dispatchRaw', async () => {
507
- await tasksHandler.mutate('complete', { taskId: 'T001', notes: 'Done' });
508
- await dispatchRaw('mutate', 'tasks', 'complete', { taskId: 'T001', notes: 'Done' });
509
- expect(taskComplete).toHaveBeenCalledTimes(2);
510
- expect(vi.mocked(taskComplete).mock.calls[0]).toEqual(vi.mocked(taskComplete).mock.calls[1]);
511
- });
512
- });
513
- // -------------------------------------------------------------------------
514
- // tasks.update (mutate)
515
- // -------------------------------------------------------------------------
516
- describe('tasks.update', () => {
517
- const UPDATED_DATA = {
518
- task: {
519
- id: 'T001',
520
- title: 'Updated title',
521
- status: 'active',
522
- },
523
- };
524
- beforeEach(() => {
525
- vi.mocked(taskUpdate).mockResolvedValue({
526
- success: true,
527
- data: UPDATED_DATA,
528
- });
529
- });
530
- it('handler.mutate("update") and dispatchRaw produce identical data', async () => {
531
- const params = { taskId: 'T001', title: 'Updated title', status: 'active' };
532
- const handlerResult = await tasksHandler.mutate('update', params);
533
- const cliResult = await dispatchRaw('mutate', 'tasks', 'update', params);
534
- expect(handlerResult.success).toBe(true);
535
- expect(cliResult.success).toBe(true);
536
- expect(handlerResult.data).toEqual(cliResult.data);
537
- });
538
- it('taskUpdate engine called with identical args from handler and dispatchRaw', async () => {
539
- const params = { taskId: 'T001', status: 'done' };
540
- await tasksHandler.mutate('update', params);
541
- await dispatchRaw('mutate', 'tasks', 'update', params);
542
- expect(taskUpdate).toHaveBeenCalledTimes(2);
543
- expect(vi.mocked(taskUpdate).mock.calls[0]).toEqual(vi.mocked(taskUpdate).mock.calls[1]);
544
- });
545
- });
546
- // -------------------------------------------------------------------------
547
- // tasks.delete (mutate)
548
- // -------------------------------------------------------------------------
549
- describe('tasks.delete', () => {
550
- const DELETE_DATA = { taskId: 'T001', deleted: true };
551
- beforeEach(() => {
552
- vi.mocked(taskDelete).mockResolvedValue({
553
- success: true,
554
- data: DELETE_DATA,
555
- });
556
- });
557
- it('handler.mutate("delete") and dispatchRaw produce identical data', async () => {
558
- const handlerResult = await tasksHandler.mutate('delete', { taskId: 'T001' });
559
- const cliResult = await dispatchRaw('mutate', 'tasks', 'delete', {
560
- taskId: 'T001',
561
- });
562
- expect(handlerResult.success).toBe(true);
563
- expect(cliResult.success).toBe(true);
564
- expect(handlerResult.data).toEqual(cliResult.data);
565
- expect(cliResult.data).toEqual(DELETE_DATA);
566
- });
567
- it('handler.mutate("delete") and dispatchRaw both fail with E_INVALID_INPUT when taskId missing', async () => {
568
- const handlerResult = await tasksHandler.mutate('delete', {});
569
- const cliResult = await dispatchRaw('mutate', 'tasks', 'delete', {});
570
- expect(handlerResult.success).toBe(false);
571
- expect(cliResult.success).toBe(false);
572
- expect(handlerResult.error?.code).toBe('E_INVALID_INPUT');
573
- expect(cliResult.error?.code).toBe('E_INVALID_INPUT');
574
- });
575
- });
576
- });
577
- // ===========================================================================
578
- // Section 2: Session domain parity (T4796)
579
- // ===========================================================================
580
- describe('Section 2: Session domain parity (T4796)', () => {
581
- let sessionHandler;
582
- beforeEach(() => {
583
- sessionHandler = new SessionHandler();
584
- });
585
- // -------------------------------------------------------------------------
586
- // session.status
587
- // -------------------------------------------------------------------------
588
- describe('session.status', () => {
589
- const STATUS_DATA = {
590
- hasActiveSession: false,
591
- currentSession: null,
592
- };
593
- beforeEach(() => {
594
- vi.mocked(sessionStatus).mockResolvedValue({
595
- success: true,
596
- data: STATUS_DATA,
597
- });
598
- });
599
- it('handler.query("status") and dispatchRaw produce identical data', async () => {
600
- const handlerResult = await sessionHandler.query('status', {});
601
- const cliResult = await dispatchRaw('query', 'session', 'status', {});
602
- expect(handlerResult.success).toBe(true);
603
- expect(cliResult.success).toBe(true);
604
- expect(handlerResult.data).toEqual(cliResult.data);
605
- expect(cliResult.data).toEqual(STATUS_DATA);
606
- });
607
- it('sessionStatus engine called with identical args from handler and dispatchRaw', async () => {
608
- await sessionHandler.query('status', {});
609
- await dispatchRaw('query', 'session', 'status', {});
610
- expect(sessionStatus).toHaveBeenCalledTimes(2);
611
- expect(vi.mocked(sessionStatus).mock.calls[0]).toEqual(vi.mocked(sessionStatus).mock.calls[1]);
612
- });
613
- });
614
- // -------------------------------------------------------------------------
615
- // session.list
616
- // -------------------------------------------------------------------------
617
- describe('session.list', () => {
618
- const LIST_DATA = {
619
- sessions: [
620
- { id: 'session_abc', status: 'active', name: 'Sprint 1' },
621
- { id: 'session_def', status: 'ended', name: 'Sprint 0' },
622
- ],
623
- total: 2,
624
- filtered: 2,
625
- _meta: { truncated: false, total: 2 },
626
- };
627
- const LIST_PAGE = { mode: 'offset', limit: 10, offset: 0, hasMore: false, total: 2 };
628
- beforeEach(() => {
629
- vi.mocked(sessionList).mockResolvedValue({
630
- success: true,
631
- data: LIST_DATA,
632
- page: LIST_PAGE,
633
- });
634
- });
635
- it('handler.query("list") and dispatchRaw produce identical data', async () => {
636
- const handlerResult = await sessionHandler.query('list', {});
637
- const cliResult = await dispatchRaw('query', 'session', 'list', {});
638
- expect(handlerResult.success).toBe(true);
639
- expect(cliResult.success).toBe(true);
640
- expect(handlerResult.data).toEqual(cliResult.data);
641
- expect(handlerResult.page).toEqual(cliResult.page);
642
- expect(cliResult.data).toEqual(LIST_DATA);
643
- expect(cliResult.page).toEqual(LIST_PAGE);
644
- });
645
- });
646
- // -------------------------------------------------------------------------
647
- // session.start (mutate)
648
- // -------------------------------------------------------------------------
649
- describe('session.start', () => {
650
- // Note: SessionHandler.mutate('start') enriches the response by adding
651
- // sessionId: session.id for easy top-level extraction. This is part of the
652
- // handler contract, so both paths (direct handler + dispatchRaw) produce this.
653
- const START_DATA = {
654
- id: 'session_xyz',
655
- status: 'active',
656
- scope: { rootTaskId: 'T010' },
657
- };
658
- const ENRICHED_START_DATA = {
659
- ...START_DATA,
660
- sessionId: 'session_xyz',
661
- };
662
- beforeEach(() => {
663
- vi.mocked(sessionStart).mockResolvedValue({
664
- success: true,
665
- data: START_DATA,
666
- });
667
- });
668
- it('handler.mutate("start") and dispatchRaw produce identical data', async () => {
669
- const params = { scope: 'epic:T010', name: 'Test Session', autoStart: true };
670
- const handlerResult = await sessionHandler.mutate('start', params);
671
- const cliResult = await dispatchRaw('mutate', 'session', 'start', params);
672
- expect(handlerResult.success).toBe(true);
673
- expect(cliResult.success).toBe(true);
674
- // Both paths (direct handler + dispatchRaw) produce the same enriched data
675
- expect(handlerResult.data).toEqual(cliResult.data);
676
- // The handler enriches the data with sessionId
677
- expect(cliResult.data).toEqual(ENRICHED_START_DATA);
678
- });
679
- });
680
- });
681
- // ===========================================================================
682
- // Section 3: tasks.start/stop/current — focus operations (T4796)
683
- // ===========================================================================
684
- describe('Section 3: Focus operations parity (tasks.start/stop/current) (T4796)', () => {
685
- let tasksHandler;
686
- beforeEach(() => {
687
- tasksHandler = new TasksHandler();
688
- });
689
- describe('tasks.start', () => {
690
- const START_DATA = { taskId: 'T001', started: true };
691
- beforeEach(() => {
692
- vi.mocked(taskStart).mockResolvedValue({ success: true, data: START_DATA });
693
- });
694
- it('handler.mutate("start") and dispatchRaw produce identical data', async () => {
695
- const handlerResult = await tasksHandler.mutate('start', { taskId: 'T001' });
696
- const cliResult = await dispatchRaw('mutate', 'tasks', 'start', {
697
- taskId: 'T001',
698
- });
699
- expect(handlerResult.success).toBe(true);
700
- expect(cliResult.success).toBe(true);
701
- expect(handlerResult.data).toEqual(cliResult.data);
702
- expect(cliResult.data).toEqual(START_DATA);
703
- });
704
- it('taskStart engine called with identical args from handler and dispatchRaw', async () => {
705
- await tasksHandler.mutate('start', { taskId: 'T005' });
706
- await dispatchRaw('mutate', 'tasks', 'start', { taskId: 'T005' });
707
- expect(taskStart).toHaveBeenCalledTimes(2);
708
- expect(vi.mocked(taskStart).mock.calls[0]).toEqual(vi.mocked(taskStart).mock.calls[1]);
709
- });
710
- });
711
- describe('tasks.stop', () => {
712
- const STOP_DATA = { cleared: true };
713
- beforeEach(() => {
714
- vi.mocked(taskStop).mockResolvedValue({ success: true, data: STOP_DATA });
715
- });
716
- it('handler.mutate("stop") and dispatchRaw produce identical data', async () => {
717
- const handlerResult = await tasksHandler.mutate('stop', {});
718
- const cliResult = await dispatchRaw('mutate', 'tasks', 'stop', {});
719
- expect(handlerResult.success).toBe(true);
720
- expect(cliResult.success).toBe(true);
721
- expect(handlerResult.data).toEqual(cliResult.data);
722
- });
723
- });
724
- describe('tasks.current', () => {
725
- const CURRENT_DATA = { currentTask: 'T001', since: '2026-02-25T00:00:00Z' };
726
- beforeEach(() => {
727
- vi.mocked(taskCurrentGet).mockResolvedValue({
728
- success: true,
729
- data: CURRENT_DATA,
730
- });
731
- });
732
- it('handler.query("current") and dispatchRaw produce identical data', async () => {
733
- const handlerResult = await tasksHandler.query('current', {});
734
- const cliResult = await dispatchRaw('query', 'tasks', 'current', {});
735
- expect(handlerResult.success).toBe(true);
736
- expect(cliResult.success).toBe(true);
737
- expect(handlerResult.data).toEqual(cliResult.data);
738
- });
739
- });
740
- });
741
- // ===========================================================================
742
- // Section 4: DispatchResponse shape consistency (T4796)
743
- // ===========================================================================
744
- describe('Section 4: DispatchResponse shape consistency (T4796)', () => {
745
- let tasksHandler;
746
- beforeEach(() => {
747
- tasksHandler = new TasksHandler();
748
- });
749
- it('_meta has required fields: gateway, domain, operation, timestamp, requestId', async () => {
750
- vi.mocked(taskShow).mockResolvedValue({
751
- success: true,
752
- data: { task: { id: 'T001' } },
753
- });
754
- const cliResult = await dispatchRaw('query', 'tasks', 'show', {
755
- taskId: 'T001',
756
- });
757
- expect(cliResult._meta).toBeDefined();
758
- expect(cliResult._meta.gateway).toBe('query');
759
- expect(cliResult._meta.domain).toBe('tasks');
760
- expect(cliResult._meta.operation).toBe('show');
761
- expect(typeof cliResult._meta.timestamp).toBe('string');
762
- expect(typeof cliResult._meta.requestId).toBe('string');
763
- expect(typeof cliResult._meta.duration_ms).toBe('number');
764
- });
765
- it('_meta.source is "cli" for dispatchRaw calls', async () => {
766
- vi.mocked(taskShow).mockResolvedValue({
767
- success: true,
768
- data: { task: { id: 'T001' } },
769
- });
770
- const cliResult = await dispatchRaw('query', 'tasks', 'show', {
771
- taskId: 'T001',
772
- });
773
- expect(cliResult._meta.source).toBe('cli');
774
- });
775
- it('success responses have data field; error responses have error field', async () => {
776
- vi.mocked(taskShow).mockResolvedValue({
777
- success: true,
778
- data: { task: { id: 'T001' } },
779
- });
780
- const successResult = await dispatchRaw('query', 'tasks', 'show', {
781
- taskId: 'T001',
782
- });
783
- expect(successResult.success).toBe(true);
784
- expect(successResult.data).toBeDefined();
785
- expect(successResult.error).toBeUndefined();
786
- const errorResult = await dispatchRaw('query', 'tasks', 'show', {});
787
- expect(errorResult.success).toBe(false);
788
- expect(errorResult.error).toBeDefined();
789
- expect(typeof errorResult.error?.code).toBe('string');
790
- expect(typeof errorResult.error?.message).toBe('string');
791
- });
792
- it('error codes are E_ prefixed strings', async () => {
793
- // Missing taskId → E_INVALID_INPUT
794
- const result1 = await dispatchRaw('query', 'tasks', 'show', {});
795
- expect(result1.error?.code).toMatch(/^E_/);
796
- // Unknown operation → E_INVALID_OPERATION
797
- const result2 = await dispatchRaw('query', 'tasks', 'nonexistent', {});
798
- expect(result2.error?.code).toBe('E_INVALID_OPERATION');
799
- });
800
- it('domain handler and dispatchRaw produce identical error shape for same failure', async () => {
801
- const handlerResult = await tasksHandler.query('show', {});
802
- const cliResult = await dispatchRaw('query', 'tasks', 'show', {});
803
- // Both return error with same code and message
804
- expect(handlerResult.error?.code).toBe('E_INVALID_INPUT');
805
- expect(cliResult.error?.code).toBe('E_INVALID_INPUT');
806
- expect(handlerResult.error?.message).toBe(cliResult.error?.message);
807
- });
808
- });
809
- // ===========================================================================
810
- // Section 5: Documented parity gaps (T4796)
811
- //
812
- // These tests document known architectural gaps between CLI and MCP paths.
813
- // They verify the current behavior and are intended to fail once the gap
814
- // is fixed (at which point the test assertions should be updated).
815
- // ===========================================================================
816
- describe('Section 5: Documented parity gaps (T4796)', () => {
817
- /**
818
- * GAP 1: MCP gateway normalization
819
- *
820
- * handleMcpToolCall() passes 'cleo_query' as the gateway field to the
821
- * Dispatcher, but the registry only indexes operations by 'query'/'mutate'.
822
- * This causes ALL handleMcpToolCall() calls to fail with E_INVALID_OPERATION
823
- * because the registry lookup in dispatcher.ts line 38:
824
- * resolve(request.gateway, domain, operation)
825
- * receives 'cleo_query' instead of 'query'.
826
- *
827
- * Fix: handleMcpToolCall() should normalize gateway before dispatching:
828
- * const normalizedGateway = gateway === 'cleo_query' ? 'query' : 'mutate';
829
- */
830
- it('GAP RESOLVED: handleMcpToolCall now normalizes cleo_query to query', async () => {
831
- vi.mocked(taskShow).mockResolvedValue({
832
- success: true,
833
- data: { task: { id: 'T001' } },
834
- });
835
- const mcpResponse = await handleMcpToolCall('cleo_query', 'tasks', 'show', { taskId: 'T001' });
836
- // GAP has been resolved: cleo_query is now normalized to query.
837
- // The request succeeds because the registry lookup now works.
838
- expect(mcpResponse.success).toBe(true);
839
- });
840
- /**
841
- * GAP 2: Dispatcher routes cleo_query to handler.mutate() instead of handler.query()
842
- *
843
- * In dispatcher.ts line 88:
844
- * if (request.gateway === 'query') { handler.query(...) } else { handler.mutate(...) }
845
- *
846
- * Since MCP requests arrive with gateway='cleo_query', they fall through to
847
- * handler.mutate() even for read operations. This compounds the registry gap.
848
- *
849
- * This gap is blocked by GAP 1 (registry failure happens first), but once
850
- * GAP 1 is fixed, this must also be fixed.
851
- *
852
- * Fix: Normalize 'cleo_query' → 'query' before the terminal handler check.
853
- */
854
- it('GAP: Dispatcher routes cleo_query to mutate handler (wrong path for read ops)', async () => {
855
- // This gap is masked by GAP 1, but we verify the expected correct behavior
856
- // via dispatchRaw (which uses 'query' gateway correctly):
857
- vi.mocked(taskShow).mockResolvedValue({
858
- success: true,
859
- data: { task: { id: 'T001' } },
860
- });
861
- const cliResult = await dispatchRaw('query', 'tasks', 'show', {
862
- taskId: 'T001',
863
- });
864
- // CLI correctly routes to handler.query()
865
- expect(cliResult.success).toBe(true);
866
- expect(cliResult.data).toEqual({ task: { id: 'T001' } });
867
- // taskShow (a query engine fn) was called once (via CLI query path)
868
- expect(taskShow).toHaveBeenCalledTimes(1);
869
- });
870
- /**
871
- * CORRECT PATH: CLI dispatchRaw produces valid results for all tested operations.
872
- * The full CLI → Dispatcher → Handler → Engine → Core path works correctly.
873
- */
874
- it('CLI path (dispatchRaw) works correctly end-to-end for task operations', async () => {
875
- vi.mocked(taskShow).mockResolvedValue({
876
- success: true,
877
- data: { task: { id: 'T001', title: 'Test task' } },
878
- });
879
- vi.mocked(taskList).mockResolvedValue({
880
- success: true,
881
- data: { tasks: [], total: 0 },
882
- });
883
- vi.mocked(taskCreate).mockResolvedValue({
884
- success: true,
885
- data: { task: { id: 'T100', title: 'New task' } },
886
- });
887
- const showResult = await dispatchRaw('query', 'tasks', 'show', { taskId: 'T001' });
888
- const listResult = await dispatchRaw('query', 'tasks', 'list', {});
889
- const addResult = await dispatchRaw('mutate', 'tasks', 'add', { title: 'New task' });
890
- expect(showResult.success).toBe(true);
891
- expect(listResult.success).toBe(true);
892
- expect(addResult.success).toBe(true);
893
- expect(taskShow).toHaveBeenCalledTimes(1);
894
- expect(taskList).toHaveBeenCalledTimes(1);
895
- expect(taskCreate).toHaveBeenCalledTimes(1);
896
- });
897
- });
898
- //# sourceMappingURL=cli-mcp-parity.integration.test.js.map