@cleocode/core 2026.4.5 → 2026.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (782) hide show
  1. package/dist/discovery.d.ts +69 -0
  2. package/dist/discovery.d.ts.map +1 -0
  3. package/dist/index.d.ts +3 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1643 -2349
  6. package/dist/index.js.map +4 -4
  7. package/dist/init.d.ts +51 -0
  8. package/dist/init.d.ts.map +1 -1
  9. package/dist/internal.d.ts +9 -1
  10. package/dist/internal.d.ts.map +1 -1
  11. package/dist/lifecycle/default-chain.d.ts +8 -2
  12. package/dist/lifecycle/default-chain.d.ts.map +1 -1
  13. package/dist/lifecycle/index.d.ts +1 -0
  14. package/dist/lifecycle/index.d.ts.map +1 -1
  15. package/dist/lifecycle/stage-guidance.d.ts +140 -0
  16. package/dist/lifecycle/stage-guidance.d.ts.map +1 -0
  17. package/dist/orchestration/protocol-validators.d.ts +122 -3
  18. package/dist/orchestration/protocol-validators.d.ts.map +1 -1
  19. package/dist/paths.d.ts +91 -0
  20. package/dist/paths.d.ts.map +1 -1
  21. package/dist/scaffold.d.ts +31 -1
  22. package/dist/scaffold.d.ts.map +1 -1
  23. package/dist/skills/dispatch.d.ts +1 -1
  24. package/dist/skills/skill-paths.d.ts +9 -6
  25. package/dist/skills/skill-paths.d.ts.map +1 -1
  26. package/dist/validation/protocols/_shared.d.ts +40 -0
  27. package/dist/validation/protocols/_shared.d.ts.map +1 -0
  28. package/dist/validation/protocols/architecture-decision.d.ts +23 -0
  29. package/dist/validation/protocols/architecture-decision.d.ts.map +1 -0
  30. package/dist/validation/protocols/artifact-publish.d.ts +22 -0
  31. package/dist/validation/protocols/artifact-publish.d.ts.map +1 -0
  32. package/dist/validation/protocols/consensus.d.ts +11 -17
  33. package/dist/validation/protocols/consensus.d.ts.map +1 -1
  34. package/dist/validation/protocols/contribution.d.ts +12 -17
  35. package/dist/validation/protocols/contribution.d.ts.map +1 -1
  36. package/dist/validation/protocols/decomposition.d.ts +18 -21
  37. package/dist/validation/protocols/decomposition.d.ts.map +1 -1
  38. package/dist/validation/protocols/implementation.d.ts +9 -17
  39. package/dist/validation/protocols/implementation.d.ts.map +1 -1
  40. package/dist/validation/protocols/provenance.d.ts +23 -0
  41. package/dist/validation/protocols/provenance.d.ts.map +1 -0
  42. package/dist/validation/protocols/release.d.ts +25 -0
  43. package/dist/validation/protocols/release.d.ts.map +1 -0
  44. package/dist/validation/protocols/research.d.ts +9 -17
  45. package/dist/validation/protocols/research.d.ts.map +1 -1
  46. package/dist/validation/protocols/specification.d.ts +7 -17
  47. package/dist/validation/protocols/specification.d.ts.map +1 -1
  48. package/dist/validation/protocols/testing.d.ts +22 -0
  49. package/dist/validation/protocols/testing.d.ts.map +1 -0
  50. package/dist/validation/protocols/validation.d.ts +22 -0
  51. package/dist/validation/protocols/validation.d.ts.map +1 -0
  52. package/package.json +7 -7
  53. package/src/discovery.ts +235 -0
  54. package/src/index.ts +16 -0
  55. package/src/init.ts +196 -0
  56. package/src/internal.ts +31 -1
  57. package/src/lifecycle/default-chain.ts +11 -2
  58. package/src/lifecycle/index.ts +10 -0
  59. package/src/lifecycle/stage-guidance.ts +282 -0
  60. package/src/orchestration/__tests__/protocol-validators.test.ts +259 -7
  61. package/src/orchestration/protocol-validators.ts +419 -4
  62. package/src/paths.ts +110 -0
  63. package/src/scaffold.ts +240 -4
  64. package/src/skills/dispatch.ts +6 -6
  65. package/src/skills/skill-paths.ts +27 -23
  66. package/src/validation/protocols/_shared.ts +88 -0
  67. package/src/validation/protocols/architecture-decision.ts +52 -0
  68. package/src/validation/protocols/artifact-publish.ts +49 -0
  69. package/src/validation/protocols/consensus.ts +44 -74
  70. package/src/validation/protocols/contribution.ts +28 -65
  71. package/src/validation/protocols/decomposition.ts +37 -64
  72. package/src/validation/protocols/implementation.ts +25 -65
  73. package/src/validation/protocols/protocols-markdown/architecture-decision.md +303 -0
  74. package/src/validation/protocols/protocols-markdown/artifact-publish.md +600 -0
  75. package/src/validation/protocols/protocols-markdown/consensus.md +322 -0
  76. package/src/validation/protocols/protocols-markdown/contribution.md +388 -0
  77. package/src/validation/protocols/protocols-markdown/decomposition.md +421 -0
  78. package/src/validation/protocols/protocols-markdown/implementation.md +357 -0
  79. package/src/validation/protocols/protocols-markdown/provenance.md +613 -0
  80. package/src/validation/protocols/protocols-markdown/release.md +783 -0
  81. package/src/validation/protocols/protocols-markdown/research.md +261 -0
  82. package/src/validation/protocols/protocols-markdown/specification.md +300 -0
  83. package/src/validation/protocols/protocols-markdown/testing.md +287 -0
  84. package/src/validation/protocols/protocols-markdown/validation.md +242 -0
  85. package/src/validation/protocols/provenance.ts +50 -0
  86. package/src/validation/protocols/release.ts +44 -0
  87. package/src/validation/protocols/research.ts +25 -87
  88. package/src/validation/protocols/specification.ts +27 -89
  89. package/src/validation/protocols/testing.ts +46 -0
  90. package/src/validation/protocols/validation.ts +46 -0
  91. package/dist/cant/approval.d.ts +0 -110
  92. package/dist/cant/approval.d.ts.map +0 -1
  93. package/dist/cant/context-builder.d.ts +0 -79
  94. package/dist/cant/context-builder.d.ts.map +0 -1
  95. package/dist/cant/discretion.d.ts +0 -95
  96. package/dist/cant/discretion.d.ts.map +0 -1
  97. package/dist/cant/index.d.ts +0 -25
  98. package/dist/cant/index.d.ts.map +0 -1
  99. package/dist/cant/parallel-runner.d.ts +0 -38
  100. package/dist/cant/parallel-runner.d.ts.map +0 -1
  101. package/dist/cant/types.d.ts +0 -127
  102. package/dist/cant/types.d.ts.map +0 -1
  103. package/dist/cant/workflow-executor.d.ts +0 -105
  104. package/dist/cant/workflow-executor.d.ts.map +0 -1
  105. package/dist/validation/protocols/release-protocol.d.ts +0 -27
  106. package/dist/validation/protocols/release-protocol.d.ts.map +0 -1
  107. package/dist/validation/protocols/testing-protocol.d.ts +0 -27
  108. package/dist/validation/protocols/testing-protocol.d.ts.map +0 -1
  109. package/dist/validation/protocols/validation-protocol.d.ts +0 -27
  110. package/dist/validation/protocols/validation-protocol.d.ts.map +0 -1
  111. package/schemas/agent-configs.schema.json +0 -120
  112. package/schemas/agent-registry.schema.json +0 -132
  113. package/schemas/archive.schema.json +0 -450
  114. package/schemas/brain-decision.schema.json +0 -69
  115. package/schemas/brain-learning.schema.json +0 -57
  116. package/schemas/brain-pattern.schema.json +0 -72
  117. package/schemas/critical-path.schema.json +0 -246
  118. package/schemas/deps-cache.schema.json +0 -97
  119. package/schemas/doctor-output.schema.json +0 -283
  120. package/schemas/error.schema.json +0 -161
  121. package/schemas/global-config.schema.json +0 -219
  122. package/schemas/grade.schema.json +0 -49
  123. package/schemas/log.schema.json +0 -250
  124. package/schemas/metrics.schema.json +0 -328
  125. package/schemas/migrations.schema.json +0 -150
  126. package/schemas/nexus-registry.schema.json +0 -90
  127. package/schemas/operation-constitution.schema.json +0 -438
  128. package/schemas/output.schema.json +0 -164
  129. package/schemas/projects-registry.schema.json +0 -107
  130. package/schemas/protocol-frontmatter.schema.json +0 -72
  131. package/schemas/rcasd-consensus-report.schema.json +0 -10
  132. package/schemas/rcasd-evidence.schema.json +0 -42
  133. package/schemas/rcasd-gate-result.schema.json +0 -46
  134. package/schemas/rcasd-hitl-resolution.schema.json +0 -10
  135. package/schemas/rcasd-index.schema.json +0 -10
  136. package/schemas/rcasd-manifest.schema.json +0 -10
  137. package/schemas/rcasd-research-output.schema.json +0 -10
  138. package/schemas/rcasd-spec-frontmatter.schema.json +0 -10
  139. package/schemas/rcasd-stage-transition.schema.json +0 -38
  140. package/schemas/releases.schema.json +0 -267
  141. package/schemas/skills-manifest.schema.json +0 -91
  142. package/schemas/spec-index.schema.json +0 -196
  143. package/schemas/system-flow-atlas.schema.json +0 -125
  144. package/src/__tests__/audit-prune.test.d.ts.map +0 -1
  145. package/src/__tests__/audit-prune.test.js +0 -162
  146. package/src/__tests__/audit-prune.test.js.map +0 -1
  147. package/src/__tests__/caamp-skill-install.test.d.ts.map +0 -1
  148. package/src/__tests__/caamp-skill-install.test.js +0 -147
  149. package/src/__tests__/caamp-skill-install.test.js.map +0 -1
  150. package/src/__tests__/cli-parity.test.d.ts.map +0 -1
  151. package/src/__tests__/cli-parity.test.js +0 -209
  152. package/src/__tests__/cli-parity.test.js.map +0 -1
  153. package/src/__tests__/config.test.d.ts.map +0 -1
  154. package/src/__tests__/config.test.js +0 -144
  155. package/src/__tests__/config.test.js.map +0 -1
  156. package/src/__tests__/core-parity.test.d.ts.map +0 -1
  157. package/src/__tests__/core-parity.test.js +0 -645
  158. package/src/__tests__/core-parity.test.js.map +0 -1
  159. package/src/__tests__/error-catalog.test.d.ts.map +0 -1
  160. package/src/__tests__/error-catalog.test.js +0 -127
  161. package/src/__tests__/error-catalog.test.js.map +0 -1
  162. package/src/__tests__/golden-parity.test.d.ts.map +0 -1
  163. package/src/__tests__/golden-parity.test.js +0 -212
  164. package/src/__tests__/golden-parity.test.js.map +0 -1
  165. package/src/__tests__/hooks.test.d.ts.map +0 -1
  166. package/src/__tests__/hooks.test.js +0 -201
  167. package/src/__tests__/hooks.test.js.map +0 -1
  168. package/src/__tests__/human-output.test.d.ts.map +0 -1
  169. package/src/__tests__/human-output.test.js +0 -158
  170. package/src/__tests__/human-output.test.js.map +0 -1
  171. package/src/__tests__/index-api-compat.test.d.ts.map +0 -1
  172. package/src/__tests__/index-api-compat.test.js +0 -16
  173. package/src/__tests__/index-api-compat.test.js.map +0 -1
  174. package/src/__tests__/init-e2e.test.d.ts.map +0 -1
  175. package/src/__tests__/init-e2e.test.js +0 -221
  176. package/src/__tests__/init-e2e.test.js.map +0 -1
  177. package/src/__tests__/injection-chain.test.d.ts.map +0 -1
  178. package/src/__tests__/injection-chain.test.js +0 -234
  179. package/src/__tests__/injection-chain.test.js.map +0 -1
  180. package/src/__tests__/injection-mvi-tiers.test.d.ts.map +0 -1
  181. package/src/__tests__/injection-mvi-tiers.test.js +0 -152
  182. package/src/__tests__/injection-mvi-tiers.test.js.map +0 -1
  183. package/src/__tests__/injection-shared.test.d.ts.map +0 -1
  184. package/src/__tests__/injection-shared.test.js +0 -194
  185. package/src/__tests__/injection-shared.test.js.map +0 -1
  186. package/src/__tests__/lafs-conformance.test.d.ts.map +0 -1
  187. package/src/__tests__/lafs-conformance.test.js +0 -786
  188. package/src/__tests__/lafs-conformance.test.js.map +0 -1
  189. package/src/__tests__/logger.test.d.ts.map +0 -1
  190. package/src/__tests__/logger.test.js +0 -75
  191. package/src/__tests__/logger.test.js.map +0 -1
  192. package/src/__tests__/paths.test.d.ts.map +0 -1
  193. package/src/__tests__/paths.test.js +0 -327
  194. package/src/__tests__/paths.test.js.map +0 -1
  195. package/src/__tests__/project-info.test.d.ts.map +0 -1
  196. package/src/__tests__/project-info.test.js +0 -156
  197. package/src/__tests__/project-info.test.js.map +0 -1
  198. package/src/__tests__/rcsd-pipeline-e2e.test.d.ts.map +0 -1
  199. package/src/__tests__/rcsd-pipeline-e2e.test.js +0 -263
  200. package/src/__tests__/rcsd-pipeline-e2e.test.js.map +0 -1
  201. package/src/__tests__/remote.test.d.ts.map +0 -1
  202. package/src/__tests__/remote.test.js +0 -149
  203. package/src/__tests__/remote.test.js.map +0 -1
  204. package/src/__tests__/scaffold.test.d.ts.map +0 -1
  205. package/src/__tests__/scaffold.test.js +0 -474
  206. package/src/__tests__/scaffold.test.js.map +0 -1
  207. package/src/__tests__/schema-management.test.d.ts.map +0 -1
  208. package/src/__tests__/schema-management.test.js +0 -287
  209. package/src/__tests__/schema-management.test.js.map +0 -1
  210. package/src/__tests__/schema.test.d.ts.map +0 -1
  211. package/src/__tests__/schema.test.js +0 -51
  212. package/src/__tests__/schema.test.js.map +0 -1
  213. package/src/__tests__/sharing.test.d.ts.map +0 -1
  214. package/src/__tests__/sharing.test.js +0 -160
  215. package/src/__tests__/sharing.test.js.map +0 -1
  216. package/src/__tests__/snapshot.test.d.ts.map +0 -1
  217. package/src/__tests__/snapshot.test.js +0 -72
  218. package/src/__tests__/snapshot.test.js.map +0 -1
  219. package/src/__tests__/upgrade.test.d.ts.map +0 -1
  220. package/src/__tests__/upgrade.test.js +0 -321
  221. package/src/__tests__/upgrade.test.js.map +0 -1
  222. package/src/adapters/__tests__/discovery.test.d.ts.map +0 -1
  223. package/src/adapters/__tests__/discovery.test.js +0 -56
  224. package/src/adapters/__tests__/discovery.test.js.map +0 -1
  225. package/src/adapters/__tests__/manager.test.d.ts.map +0 -1
  226. package/src/adapters/__tests__/manager.test.js +0 -260
  227. package/src/adapters/__tests__/manager.test.js.map +0 -1
  228. package/src/agents/__tests__/agent-registry.test.d.ts.map +0 -1
  229. package/src/agents/__tests__/agent-registry.test.js +0 -262
  230. package/src/agents/__tests__/agent-registry.test.js.map +0 -1
  231. package/src/agents/__tests__/capacity.test.d.ts.map +0 -1
  232. package/src/agents/__tests__/capacity.test.js +0 -173
  233. package/src/agents/__tests__/capacity.test.js.map +0 -1
  234. package/src/agents/__tests__/execution-learning.test.d.ts.map +0 -1
  235. package/src/agents/__tests__/execution-learning.test.js +0 -533
  236. package/src/agents/__tests__/execution-learning.test.js.map +0 -1
  237. package/src/agents/__tests__/health-monitor.test.d.ts.map +0 -1
  238. package/src/agents/__tests__/health-monitor.test.js +0 -259
  239. package/src/agents/__tests__/health-monitor.test.js.map +0 -1
  240. package/src/agents/__tests__/registry.test.d.ts.map +0 -1
  241. package/src/agents/__tests__/registry.test.js +0 -373
  242. package/src/agents/__tests__/registry.test.js.map +0 -1
  243. package/src/agents/__tests__/retry.test.d.ts.map +0 -1
  244. package/src/agents/__tests__/retry.test.js +0 -225
  245. package/src/agents/__tests__/retry.test.js.map +0 -1
  246. package/src/cant/__tests__/cant-agent-parse.test.d.ts.map +0 -1
  247. package/src/cant/__tests__/cant-agent-parse.test.js +0 -77
  248. package/src/cant/__tests__/cant-agent-parse.test.js.map +0 -1
  249. package/src/cant/__tests__/cant-agent-parse.test.ts +0 -94
  250. package/src/cant/approval.ts +0 -218
  251. package/src/cant/context-builder.ts +0 -135
  252. package/src/cant/discretion.ts +0 -149
  253. package/src/cant/index.ts +0 -58
  254. package/src/cant/parallel-runner.ts +0 -205
  255. package/src/cant/types.ts +0 -158
  256. package/src/cant/workflow-executor.ts +0 -618
  257. package/src/compliance/__tests__/sync.test.d.ts.map +0 -1
  258. package/src/compliance/__tests__/sync.test.js +0 -119
  259. package/src/compliance/__tests__/sync.test.js.map +0 -1
  260. package/src/conduit/__tests__/dual-api-e2e.test.d.ts.map +0 -1
  261. package/src/conduit/__tests__/dual-api-e2e.test.js +0 -178
  262. package/src/conduit/__tests__/dual-api-e2e.test.js.map +0 -1
  263. package/src/conduit/__tests__/dual-api-e2e.test.ts +0 -212
  264. package/src/conduit/__tests__/local-credential-flow.test.d.ts.map +0 -1
  265. package/src/conduit/__tests__/local-credential-flow.test.js +0 -185
  266. package/src/conduit/__tests__/local-credential-flow.test.js.map +0 -1
  267. package/src/conduit/__tests__/local-transport.test.d.ts.map +0 -1
  268. package/src/conduit/__tests__/local-transport.test.js +0 -404
  269. package/src/conduit/__tests__/local-transport.test.js.map +0 -1
  270. package/src/conduit/__tests__/sse-transport.test.d.ts.map +0 -1
  271. package/src/conduit/__tests__/sse-transport.test.js +0 -291
  272. package/src/conduit/__tests__/sse-transport.test.js.map +0 -1
  273. package/src/hooks/__tests__/provider-hooks.test.d.ts.map +0 -1
  274. package/src/hooks/__tests__/provider-hooks.test.js +0 -33
  275. package/src/hooks/__tests__/provider-hooks.test.js.map +0 -1
  276. package/src/hooks/__tests__/registry.test.d.ts.map +0 -1
  277. package/src/hooks/__tests__/registry.test.js +0 -37
  278. package/src/hooks/__tests__/registry.test.js.map +0 -1
  279. package/src/hooks/handlers/__tests__/error-hooks.test.d.ts.map +0 -1
  280. package/src/hooks/handlers/__tests__/error-hooks.test.js +0 -90
  281. package/src/hooks/handlers/__tests__/error-hooks.test.js.map +0 -1
  282. package/src/hooks/handlers/__tests__/file-hooks.test.d.ts.map +0 -1
  283. package/src/hooks/handlers/__tests__/file-hooks.test.js +0 -128
  284. package/src/hooks/handlers/__tests__/file-hooks.test.js.map +0 -1
  285. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.d.ts.map +0 -1
  286. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js +0 -501
  287. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js.map +0 -1
  288. package/src/hooks/handlers/__tests__/session-hooks.test.d.ts.map +0 -1
  289. package/src/hooks/handlers/__tests__/session-hooks.test.js +0 -54
  290. package/src/hooks/handlers/__tests__/session-hooks.test.js.map +0 -1
  291. package/src/hooks/handlers/__tests__/task-hooks.test.d.ts.map +0 -1
  292. package/src/hooks/handlers/__tests__/task-hooks.test.js +0 -77
  293. package/src/hooks/handlers/__tests__/task-hooks.test.js.map +0 -1
  294. package/src/intelligence/__tests__/adaptive-validation.test.d.ts.map +0 -1
  295. package/src/intelligence/__tests__/adaptive-validation.test.js +0 -517
  296. package/src/intelligence/__tests__/adaptive-validation.test.js.map +0 -1
  297. package/src/intelligence/__tests__/impact.test.d.ts.map +0 -1
  298. package/src/intelligence/__tests__/impact.test.js +0 -515
  299. package/src/intelligence/__tests__/impact.test.js.map +0 -1
  300. package/src/intelligence/__tests__/patterns.test.d.ts.map +0 -1
  301. package/src/intelligence/__tests__/patterns.test.js +0 -370
  302. package/src/intelligence/__tests__/patterns.test.js.map +0 -1
  303. package/src/intelligence/__tests__/prediction.test.d.ts.map +0 -1
  304. package/src/intelligence/__tests__/prediction.test.js +0 -314
  305. package/src/intelligence/__tests__/prediction.test.js.map +0 -1
  306. package/src/lib/__tests__/retry.test.d.ts.map +0 -1
  307. package/src/lib/__tests__/retry.test.js +0 -225
  308. package/src/lib/__tests__/retry.test.js.map +0 -1
  309. package/src/lifecycle/__tests__/chain-store.test.d.ts.map +0 -1
  310. package/src/lifecycle/__tests__/chain-store.test.js +0 -243
  311. package/src/lifecycle/__tests__/chain-store.test.js.map +0 -1
  312. package/src/lifecycle/__tests__/consolidate-rcasd.test.d.ts.map +0 -1
  313. package/src/lifecycle/__tests__/consolidate-rcasd.test.js +0 -210
  314. package/src/lifecycle/__tests__/consolidate-rcasd.test.js.map +0 -1
  315. package/src/lifecycle/__tests__/default-chain.test.d.ts.map +0 -1
  316. package/src/lifecycle/__tests__/default-chain.test.js +0 -74
  317. package/src/lifecycle/__tests__/default-chain.test.js.map +0 -1
  318. package/src/lifecycle/__tests__/frontmatter.test.d.ts.map +0 -1
  319. package/src/lifecycle/__tests__/frontmatter.test.js +0 -229
  320. package/src/lifecycle/__tests__/frontmatter.test.js.map +0 -1
  321. package/src/lifecycle/__tests__/lifecycle.test.d.ts.map +0 -1
  322. package/src/lifecycle/__tests__/lifecycle.test.js +0 -126
  323. package/src/lifecycle/__tests__/lifecycle.test.js.map +0 -1
  324. package/src/lifecycle/__tests__/pipeline.integration.test.d.ts.map +0 -1
  325. package/src/lifecycle/__tests__/pipeline.integration.test.js +0 -977
  326. package/src/lifecycle/__tests__/pipeline.integration.test.js.map +0 -1
  327. package/src/lifecycle/__tests__/rcasd-paths.test.d.ts.map +0 -1
  328. package/src/lifecycle/__tests__/rcasd-paths.test.js +0 -206
  329. package/src/lifecycle/__tests__/rcasd-paths.test.js.map +0 -1
  330. package/src/lifecycle/__tests__/resume-schema-contract.test.d.ts.map +0 -1
  331. package/src/lifecycle/__tests__/resume-schema-contract.test.js +0 -246
  332. package/src/lifecycle/__tests__/resume-schema-contract.test.js.map +0 -1
  333. package/src/lifecycle/__tests__/stage-record-provenance.integration.test.d.ts.map +0 -1
  334. package/src/lifecycle/__tests__/stage-record-provenance.integration.test.js +0 -95
  335. package/src/lifecycle/__tests__/stage-record-provenance.integration.test.js.map +0 -1
  336. package/src/lifecycle/__tests__/tessera-engine.test.d.ts.map +0 -1
  337. package/src/lifecycle/__tests__/tessera-engine.test.js +0 -392
  338. package/src/lifecycle/__tests__/tessera-engine.test.js.map +0 -1
  339. package/src/memory/__tests__/auto-extract.test.d.ts.map +0 -1
  340. package/src/memory/__tests__/auto-extract.test.js +0 -197
  341. package/src/memory/__tests__/auto-extract.test.js.map +0 -1
  342. package/src/memory/__tests__/brain-automation.test.d.ts.map +0 -1
  343. package/src/memory/__tests__/brain-automation.test.js +0 -730
  344. package/src/memory/__tests__/brain-automation.test.js.map +0 -1
  345. package/src/memory/__tests__/brain-embedding.test.d.ts.map +0 -1
  346. package/src/memory/__tests__/brain-embedding.test.js +0 -92
  347. package/src/memory/__tests__/brain-embedding.test.js.map +0 -1
  348. package/src/memory/__tests__/brain-links.test.d.ts.map +0 -1
  349. package/src/memory/__tests__/brain-links.test.js +0 -221
  350. package/src/memory/__tests__/brain-links.test.js.map +0 -1
  351. package/src/memory/__tests__/brain-migration.test.d.ts.map +0 -1
  352. package/src/memory/__tests__/brain-migration.test.js +0 -180
  353. package/src/memory/__tests__/brain-migration.test.js.map +0 -1
  354. package/src/memory/__tests__/brain-retrieval.test.d.ts.map +0 -1
  355. package/src/memory/__tests__/brain-retrieval.test.js +0 -701
  356. package/src/memory/__tests__/brain-retrieval.test.js.map +0 -1
  357. package/src/memory/__tests__/brain-search.test.d.ts.map +0 -1
  358. package/src/memory/__tests__/brain-search.test.js +0 -180
  359. package/src/memory/__tests__/brain-search.test.js.map +0 -1
  360. package/src/memory/__tests__/claude-mem-migration.test.d.ts.map +0 -1
  361. package/src/memory/__tests__/claude-mem-migration.test.js +0 -424
  362. package/src/memory/__tests__/claude-mem-migration.test.js.map +0 -1
  363. package/src/memory/__tests__/decisions.test.d.ts.map +0 -1
  364. package/src/memory/__tests__/decisions.test.js +0 -253
  365. package/src/memory/__tests__/decisions.test.js.map +0 -1
  366. package/src/memory/__tests__/engine-compat.test.d.ts.map +0 -1
  367. package/src/memory/__tests__/engine-compat.test.js +0 -331
  368. package/src/memory/__tests__/engine-compat.test.js.map +0 -1
  369. package/src/memory/__tests__/memory-bridge.test.d.ts.map +0 -1
  370. package/src/memory/__tests__/memory-bridge.test.js +0 -231
  371. package/src/memory/__tests__/memory-bridge.test.js.map +0 -1
  372. package/src/memory/__tests__/pipeline-manifest-sqlite.test.d.ts.map +0 -1
  373. package/src/memory/__tests__/pipeline-manifest-sqlite.test.js +0 -516
  374. package/src/memory/__tests__/pipeline-manifest-sqlite.test.js.map +0 -1
  375. package/src/memory/__tests__/session-memory.test.d.ts.map +0 -1
  376. package/src/memory/__tests__/session-memory.test.js +0 -387
  377. package/src/memory/__tests__/session-memory.test.js.map +0 -1
  378. package/src/metrics/__tests__/model-provider-registry.test.d.ts.map +0 -1
  379. package/src/metrics/__tests__/model-provider-registry.test.js +0 -45
  380. package/src/metrics/__tests__/model-provider-registry.test.js.map +0 -1
  381. package/src/metrics/__tests__/provider-detection.test.d.ts.map +0 -1
  382. package/src/metrics/__tests__/provider-detection.test.js +0 -111
  383. package/src/metrics/__tests__/provider-detection.test.js.map +0 -1
  384. package/src/migration/__tests__/checksum.test.d.ts.map +0 -1
  385. package/src/migration/__tests__/checksum.test.js +0 -216
  386. package/src/migration/__tests__/checksum.test.js.map +0 -1
  387. package/src/migration/__tests__/logger.test.d.ts.map +0 -1
  388. package/src/migration/__tests__/logger.test.js +0 -256
  389. package/src/migration/__tests__/logger.test.js.map +0 -1
  390. package/src/migration/__tests__/migration-failure.integration.test.d.ts.map +0 -1
  391. package/src/migration/__tests__/migration-failure.integration.test.js +0 -515
  392. package/src/migration/__tests__/migration-failure.integration.test.js.map +0 -1
  393. package/src/migration/__tests__/migration.test.d.ts.map +0 -1
  394. package/src/migration/__tests__/migration.test.js +0 -82
  395. package/src/migration/__tests__/migration.test.js.map +0 -1
  396. package/src/migration/__tests__/state.test.d.ts.map +0 -1
  397. package/src/migration/__tests__/state.test.js +0 -330
  398. package/src/migration/__tests__/state.test.js.map +0 -1
  399. package/src/migration/__tests__/validate.test.d.ts.map +0 -1
  400. package/src/migration/__tests__/validate.test.js +0 -258
  401. package/src/migration/__tests__/validate.test.js.map +0 -1
  402. package/src/nexus/__tests__/deps.test.d.ts.map +0 -1
  403. package/src/nexus/__tests__/deps.test.js +0 -283
  404. package/src/nexus/__tests__/deps.test.js.map +0 -1
  405. package/src/nexus/__tests__/nexus-e2e.test.d.ts.map +0 -1
  406. package/src/nexus/__tests__/nexus-e2e.test.js +0 -1220
  407. package/src/nexus/__tests__/nexus-e2e.test.js.map +0 -1
  408. package/src/nexus/__tests__/permissions.test.d.ts.map +0 -1
  409. package/src/nexus/__tests__/permissions.test.js +0 -119
  410. package/src/nexus/__tests__/permissions.test.js.map +0 -1
  411. package/src/nexus/__tests__/query.test.d.ts.map +0 -1
  412. package/src/nexus/__tests__/query.test.js +0 -168
  413. package/src/nexus/__tests__/query.test.js.map +0 -1
  414. package/src/nexus/__tests__/reconcile.test.d.ts.map +0 -1
  415. package/src/nexus/__tests__/reconcile.test.js +0 -135
  416. package/src/nexus/__tests__/reconcile.test.js.map +0 -1
  417. package/src/nexus/__tests__/registry.test.d.ts.map +0 -1
  418. package/src/nexus/__tests__/registry.test.js +0 -229
  419. package/src/nexus/__tests__/registry.test.js.map +0 -1
  420. package/src/nexus/__tests__/transfer.test.d.ts.map +0 -1
  421. package/src/nexus/__tests__/transfer.test.js +0 -372
  422. package/src/nexus/__tests__/transfer.test.js.map +0 -1
  423. package/src/observability/__tests__/index.test.d.ts.map +0 -1
  424. package/src/observability/__tests__/index.test.js +0 -288
  425. package/src/observability/__tests__/index.test.js.map +0 -1
  426. package/src/observability/__tests__/log-filter.test.d.ts.map +0 -1
  427. package/src/observability/__tests__/log-filter.test.js +0 -151
  428. package/src/observability/__tests__/log-filter.test.js.map +0 -1
  429. package/src/observability/__tests__/log-parser.test.d.ts.map +0 -1
  430. package/src/observability/__tests__/log-parser.test.js +0 -170
  431. package/src/observability/__tests__/log-parser.test.js.map +0 -1
  432. package/src/observability/__tests__/log-reader.test.d.ts.map +0 -1
  433. package/src/observability/__tests__/log-reader.test.js +0 -150
  434. package/src/observability/__tests__/log-reader.test.js.map +0 -1
  435. package/src/orchestration/__tests__/autonomous-spec.test.d.ts.map +0 -1
  436. package/src/orchestration/__tests__/autonomous-spec.test.js +0 -419
  437. package/src/orchestration/__tests__/autonomous-spec.test.js.map +0 -1
  438. package/src/orchestration/__tests__/orchestration.test.d.ts.map +0 -1
  439. package/src/orchestration/__tests__/orchestration.test.js +0 -205
  440. package/src/orchestration/__tests__/orchestration.test.js.map +0 -1
  441. package/src/orchestration/__tests__/protocol-validators.test.d.ts.map +0 -1
  442. package/src/orchestration/__tests__/protocol-validators.test.js +0 -382
  443. package/src/orchestration/__tests__/protocol-validators.test.js.map +0 -1
  444. package/src/phases/__tests__/deps.test.d.ts.map +0 -1
  445. package/src/phases/__tests__/deps.test.js +0 -210
  446. package/src/phases/__tests__/deps.test.js.map +0 -1
  447. package/src/phases/__tests__/phases.test.d.ts.map +0 -1
  448. package/src/phases/__tests__/phases.test.js +0 -215
  449. package/src/phases/__tests__/phases.test.js.map +0 -1
  450. package/src/release/__tests__/artifacts.test.d.ts.map +0 -1
  451. package/src/release/__tests__/artifacts.test.js +0 -65
  452. package/src/release/__tests__/artifacts.test.js.map +0 -1
  453. package/src/release/__tests__/cancel-release.test.d.ts.map +0 -1
  454. package/src/release/__tests__/cancel-release.test.js +0 -154
  455. package/src/release/__tests__/cancel-release.test.js.map +0 -1
  456. package/src/release/__tests__/changelog-writer.test.d.ts.map +0 -1
  457. package/src/release/__tests__/changelog-writer.test.js +0 -132
  458. package/src/release/__tests__/changelog-writer.test.js.map +0 -1
  459. package/src/release/__tests__/push-policy.test.d.ts.map +0 -1
  460. package/src/release/__tests__/push-policy.test.js +0 -142
  461. package/src/release/__tests__/push-policy.test.js.map +0 -1
  462. package/src/release/__tests__/release.test.d.ts.map +0 -1
  463. package/src/release/__tests__/release.test.js +0 -25
  464. package/src/release/__tests__/release.test.js.map +0 -1
  465. package/src/sequence/__tests__/allocate.test.d.ts.map +0 -1
  466. package/src/sequence/__tests__/allocate.test.js +0 -113
  467. package/src/sequence/__tests__/allocate.test.js.map +0 -1
  468. package/src/sessions/__tests__/briefing-blocked.test.d.ts.map +0 -1
  469. package/src/sessions/__tests__/briefing-blocked.test.js +0 -117
  470. package/src/sessions/__tests__/briefing-blocked.test.js.map +0 -1
  471. package/src/sessions/__tests__/briefing.test.d.ts.map +0 -1
  472. package/src/sessions/__tests__/briefing.test.js +0 -336
  473. package/src/sessions/__tests__/briefing.test.js.map +0 -1
  474. package/src/sessions/__tests__/handoff-integration.test.d.ts.map +0 -1
  475. package/src/sessions/__tests__/handoff-integration.test.js +0 -264
  476. package/src/sessions/__tests__/handoff-integration.test.js.map +0 -1
  477. package/src/sessions/__tests__/handoff.test.d.ts.map +0 -1
  478. package/src/sessions/__tests__/handoff.test.js +0 -435
  479. package/src/sessions/__tests__/handoff.test.js.map +0 -1
  480. package/src/sessions/__tests__/index.test.d.ts.map +0 -1
  481. package/src/sessions/__tests__/index.test.js +0 -82
  482. package/src/sessions/__tests__/index.test.js.map +0 -1
  483. package/src/sessions/__tests__/session-cleanup.test.d.ts.map +0 -1
  484. package/src/sessions/__tests__/session-cleanup.test.js +0 -201
  485. package/src/sessions/__tests__/session-cleanup.test.js.map +0 -1
  486. package/src/sessions/__tests__/session-edge-cases.test.d.ts.map +0 -1
  487. package/src/sessions/__tests__/session-edge-cases.test.js +0 -251
  488. package/src/sessions/__tests__/session-edge-cases.test.js.map +0 -1
  489. package/src/sessions/__tests__/session-find.test.d.ts.map +0 -1
  490. package/src/sessions/__tests__/session-find.test.js +0 -210
  491. package/src/sessions/__tests__/session-find.test.js.map +0 -1
  492. package/src/sessions/__tests__/session-grade.integration.test.d.ts.map +0 -1
  493. package/src/sessions/__tests__/session-grade.integration.test.js +0 -287
  494. package/src/sessions/__tests__/session-grade.integration.test.js.map +0 -1
  495. package/src/sessions/__tests__/session-grade.test.d.ts.map +0 -1
  496. package/src/sessions/__tests__/session-grade.test.js +0 -630
  497. package/src/sessions/__tests__/session-grade.test.js.map +0 -1
  498. package/src/sessions/__tests__/session-memory-bridge.test.d.ts.map +0 -1
  499. package/src/sessions/__tests__/session-memory-bridge.test.js +0 -52
  500. package/src/sessions/__tests__/session-memory-bridge.test.js.map +0 -1
  501. package/src/sessions/__tests__/sessions.test.d.ts.map +0 -1
  502. package/src/sessions/__tests__/sessions.test.js +0 -113
  503. package/src/sessions/__tests__/sessions.test.js.map +0 -1
  504. package/src/skills/__tests__/discovery.test.d.ts.map +0 -1
  505. package/src/skills/__tests__/discovery.test.js +0 -171
  506. package/src/skills/__tests__/discovery.test.js.map +0 -1
  507. package/src/skills/__tests__/dispatch.test.d.ts.map +0 -1
  508. package/src/skills/__tests__/dispatch.test.js +0 -99
  509. package/src/skills/__tests__/dispatch.test.js.map +0 -1
  510. package/src/skills/__tests__/dynamic-skill-generator.test.d.ts.map +0 -1
  511. package/src/skills/__tests__/dynamic-skill-generator.test.js +0 -77
  512. package/src/skills/__tests__/dynamic-skill-generator.test.js.map +0 -1
  513. package/src/skills/__tests__/manifests.test.d.ts.map +0 -1
  514. package/src/skills/__tests__/manifests.test.js +0 -121
  515. package/src/skills/__tests__/manifests.test.js.map +0 -1
  516. package/src/skills/__tests__/precedence.test.d.ts.map +0 -1
  517. package/src/skills/__tests__/precedence.test.js +0 -325
  518. package/src/skills/__tests__/precedence.test.js.map +0 -1
  519. package/src/skills/__tests__/routing-table.test.d.ts.map +0 -1
  520. package/src/skills/__tests__/routing-table.test.js +0 -91
  521. package/src/skills/__tests__/routing-table.test.js.map +0 -1
  522. package/src/skills/__tests__/skill-paths.test.d.ts.map +0 -1
  523. package/src/skills/__tests__/skill-paths.test.js +0 -71
  524. package/src/skills/__tests__/skill-paths.test.js.map +0 -1
  525. package/src/skills/__tests__/test-utility.test.d.ts.map +0 -1
  526. package/src/skills/__tests__/test-utility.test.js +0 -59
  527. package/src/skills/__tests__/test-utility.test.js.map +0 -1
  528. package/src/skills/__tests__/token.test.d.ts.map +0 -1
  529. package/src/skills/__tests__/token.test.js +0 -135
  530. package/src/skills/__tests__/token.test.js.map +0 -1
  531. package/src/skills/__tests__/validation.test.d.ts.map +0 -1
  532. package/src/skills/__tests__/validation.test.js +0 -108
  533. package/src/skills/__tests__/validation.test.js.map +0 -1
  534. package/src/skills/__tests__/version.test.d.ts.map +0 -1
  535. package/src/skills/__tests__/version.test.js +0 -71
  536. package/src/skills/__tests__/version.test.js.map +0 -1
  537. package/src/skills/injection/__tests__/subagent.test.d.ts.map +0 -1
  538. package/src/skills/injection/__tests__/subagent.test.js +0 -122
  539. package/src/skills/injection/__tests__/subagent.test.js.map +0 -1
  540. package/src/skills/orchestrator/__tests__/spawn-tier.test.d.ts.map +0 -1
  541. package/src/skills/orchestrator/__tests__/spawn-tier.test.js +0 -228
  542. package/src/skills/orchestrator/__tests__/spawn-tier.test.js.map +0 -1
  543. package/src/spawn/__tests__/adapter-registry.test.d.ts.map +0 -1
  544. package/src/spawn/__tests__/adapter-registry.test.js +0 -76
  545. package/src/spawn/__tests__/adapter-registry.test.js.map +0 -1
  546. package/src/stats/__tests__/stats.test.d.ts.map +0 -1
  547. package/src/stats/__tests__/stats.test.js +0 -374
  548. package/src/stats/__tests__/stats.test.js.map +0 -1
  549. package/src/sticky/__tests__/purge.test.d.ts.map +0 -1
  550. package/src/sticky/__tests__/purge.test.js +0 -64
  551. package/src/sticky/__tests__/purge.test.js.map +0 -1
  552. package/src/store/__tests__/atomic.test.d.ts.map +0 -1
  553. package/src/store/__tests__/atomic.test.js +0 -81
  554. package/src/store/__tests__/atomic.test.js.map +0 -1
  555. package/src/store/__tests__/backup.test.d.ts.map +0 -1
  556. package/src/store/__tests__/backup.test.js +0 -131
  557. package/src/store/__tests__/backup.test.js.map +0 -1
  558. package/src/store/__tests__/brain-accessor-pageindex.test.d.ts.map +0 -1
  559. package/src/store/__tests__/brain-accessor-pageindex.test.js +0 -179
  560. package/src/store/__tests__/brain-accessor-pageindex.test.js.map +0 -1
  561. package/src/store/__tests__/brain-accessor.test.d.ts.map +0 -1
  562. package/src/store/__tests__/brain-accessor.test.js +0 -398
  563. package/src/store/__tests__/brain-accessor.test.js.map +0 -1
  564. package/src/store/__tests__/brain-pageindex.test.d.ts.map +0 -1
  565. package/src/store/__tests__/brain-pageindex.test.js +0 -137
  566. package/src/store/__tests__/brain-pageindex.test.js.map +0 -1
  567. package/src/store/__tests__/brain-schema.test.d.ts.map +0 -1
  568. package/src/store/__tests__/brain-schema.test.js +0 -137
  569. package/src/store/__tests__/brain-schema.test.js.map +0 -1
  570. package/src/store/__tests__/brain-vec.test.d.ts.map +0 -1
  571. package/src/store/__tests__/brain-vec.test.js +0 -100
  572. package/src/store/__tests__/brain-vec.test.js.map +0 -1
  573. package/src/store/__tests__/collision-detection.test.d.ts.map +0 -1
  574. package/src/store/__tests__/collision-detection.test.js +0 -165
  575. package/src/store/__tests__/collision-detection.test.js.map +0 -1
  576. package/src/store/__tests__/data-safety-central.test.d.ts.map +0 -1
  577. package/src/store/__tests__/data-safety-central.test.js +0 -408
  578. package/src/store/__tests__/data-safety-central.test.js.map +0 -1
  579. package/src/store/__tests__/db-helpers.test.d.ts.map +0 -1
  580. package/src/store/__tests__/db-helpers.test.js +0 -101
  581. package/src/store/__tests__/db-helpers.test.js.map +0 -1
  582. package/src/store/__tests__/e2e-safety-integration.test.d.ts.map +0 -1
  583. package/src/store/__tests__/e2e-safety-integration.test.js +0 -402
  584. package/src/store/__tests__/e2e-safety-integration.test.js.map +0 -1
  585. package/src/store/__tests__/git-checkpoint.test.d.ts.map +0 -1
  586. package/src/store/__tests__/git-checkpoint.test.js +0 -133
  587. package/src/store/__tests__/git-checkpoint.test.js.map +0 -1
  588. package/src/store/__tests__/idempotent-migration.test.d.ts.map +0 -1
  589. package/src/store/__tests__/idempotent-migration.test.js +0 -172
  590. package/src/store/__tests__/idempotent-migration.test.js.map +0 -1
  591. package/src/store/__tests__/import-logging.test.d.ts.map +0 -1
  592. package/src/store/__tests__/import-logging.test.js +0 -92
  593. package/src/store/__tests__/import-logging.test.js.map +0 -1
  594. package/src/store/__tests__/import-sort.test.d.ts.map +0 -1
  595. package/src/store/__tests__/import-sort.test.js +0 -109
  596. package/src/store/__tests__/import-sort.test.js.map +0 -1
  597. package/src/store/__tests__/json.test.d.ts.map +0 -1
  598. package/src/store/__tests__/json.test.js +0 -98
  599. package/src/store/__tests__/json.test.js.map +0 -1
  600. package/src/store/__tests__/lifecycle-schema-parity.test.d.ts.map +0 -1
  601. package/src/store/__tests__/lifecycle-schema-parity.test.js +0 -90
  602. package/src/store/__tests__/lifecycle-schema-parity.test.js.map +0 -1
  603. package/src/store/__tests__/migration-integration.test.d.ts.map +0 -1
  604. package/src/store/__tests__/migration-integration.test.js +0 -238
  605. package/src/store/__tests__/migration-integration.test.js.map +0 -1
  606. package/src/store/__tests__/migration-retry.test.d.ts.map +0 -1
  607. package/src/store/__tests__/migration-retry.test.js +0 -178
  608. package/src/store/__tests__/migration-retry.test.js.map +0 -1
  609. package/src/store/__tests__/migration-safety.test.d.ts.map +0 -1
  610. package/src/store/__tests__/migration-safety.test.js +0 -756
  611. package/src/store/__tests__/migration-safety.test.js.map +0 -1
  612. package/src/store/__tests__/migration-sqlite.test.d.ts.map +0 -1
  613. package/src/store/__tests__/migration-sqlite.test.js +0 -544
  614. package/src/store/__tests__/migration-sqlite.test.js.map +0 -1
  615. package/src/store/__tests__/performance-safety.test.d.ts.map +0 -1
  616. package/src/store/__tests__/performance-safety.test.js +0 -157
  617. package/src/store/__tests__/performance-safety.test.js.map +0 -1
  618. package/src/store/__tests__/project-detect.test.d.ts.map +0 -1
  619. package/src/store/__tests__/project-detect.test.js +0 -609
  620. package/src/store/__tests__/project-detect.test.js.map +0 -1
  621. package/src/store/__tests__/project-registry.test.d.ts.map +0 -1
  622. package/src/store/__tests__/project-registry.test.js +0 -28
  623. package/src/store/__tests__/project-registry.test.js.map +0 -1
  624. package/src/store/__tests__/provider.test.d.ts.map +0 -1
  625. package/src/store/__tests__/provider.test.js +0 -15
  626. package/src/store/__tests__/provider.test.js.map +0 -1
  627. package/src/store/__tests__/relations.test.d.ts.map +0 -1
  628. package/src/store/__tests__/relations.test.js +0 -318
  629. package/src/store/__tests__/relations.test.js.map +0 -1
  630. package/src/store/__tests__/safety-accessor.test.d.ts.map +0 -1
  631. package/src/store/__tests__/safety-accessor.test.js +0 -219
  632. package/src/store/__tests__/safety-accessor.test.js.map +0 -1
  633. package/src/store/__tests__/sequence-validation.test.d.ts.map +0 -1
  634. package/src/store/__tests__/sequence-validation.test.js +0 -94
  635. package/src/store/__tests__/sequence-validation.test.js.map +0 -1
  636. package/src/store/__tests__/session-store.test.d.ts.map +0 -1
  637. package/src/store/__tests__/session-store.test.js +0 -463
  638. package/src/store/__tests__/session-store.test.js.map +0 -1
  639. package/src/store/__tests__/sqlite-backup.test.d.ts.map +0 -1
  640. package/src/store/__tests__/sqlite-backup.test.js +0 -72
  641. package/src/store/__tests__/sqlite-backup.test.js.map +0 -1
  642. package/src/store/__tests__/sqlite.test.d.ts.map +0 -1
  643. package/src/store/__tests__/sqlite.test.js +0 -256
  644. package/src/store/__tests__/sqlite.test.js.map +0 -1
  645. package/src/store/__tests__/task-store.test.d.ts.map +0 -1
  646. package/src/store/__tests__/task-store.test.js +0 -514
  647. package/src/store/__tests__/task-store.test.js.map +0 -1
  648. package/src/store/__tests__/test-db-helper.d.ts.map +0 -1
  649. package/src/store/__tests__/test-db-helper.js +0 -110
  650. package/src/store/__tests__/test-db-helper.js.map +0 -1
  651. package/src/store/__tests__/write-verification.test.d.ts.map +0 -1
  652. package/src/store/__tests__/write-verification.test.js +0 -185
  653. package/src/store/__tests__/write-verification.test.js.map +0 -1
  654. package/src/system/__tests__/cleanup.test.d.ts.map +0 -1
  655. package/src/system/__tests__/cleanup.test.js +0 -87
  656. package/src/system/__tests__/cleanup.test.js.map +0 -1
  657. package/src/system/__tests__/health.test.d.ts.map +0 -1
  658. package/src/system/__tests__/health.test.js +0 -55
  659. package/src/system/__tests__/health.test.js.map +0 -1
  660. package/src/task-work/__tests__/start-deps.test.d.ts.map +0 -1
  661. package/src/task-work/__tests__/start-deps.test.js +0 -152
  662. package/src/task-work/__tests__/start-deps.test.js.map +0 -1
  663. package/src/tasks/__tests__/add.test.d.ts.map +0 -1
  664. package/src/tasks/__tests__/add.test.js +0 -226
  665. package/src/tasks/__tests__/add.test.js.map +0 -1
  666. package/src/tasks/__tests__/archive.test.d.ts.map +0 -1
  667. package/src/tasks/__tests__/archive.test.js +0 -196
  668. package/src/tasks/__tests__/archive.test.js.map +0 -1
  669. package/src/tasks/__tests__/assignee.test.d.ts.map +0 -1
  670. package/src/tasks/__tests__/assignee.test.js +0 -125
  671. package/src/tasks/__tests__/assignee.test.js.map +0 -1
  672. package/src/tasks/__tests__/atomicity.test.d.ts.map +0 -1
  673. package/src/tasks/__tests__/atomicity.test.js +0 -192
  674. package/src/tasks/__tests__/atomicity.test.js.map +0 -1
  675. package/src/tasks/__tests__/cancel-ops.test.d.ts.map +0 -1
  676. package/src/tasks/__tests__/cancel-ops.test.js +0 -115
  677. package/src/tasks/__tests__/cancel-ops.test.js.map +0 -1
  678. package/src/tasks/__tests__/complete-unblocks.test.d.ts.map +0 -1
  679. package/src/tasks/__tests__/complete-unblocks.test.js +0 -151
  680. package/src/tasks/__tests__/complete-unblocks.test.js.map +0 -1
  681. package/src/tasks/__tests__/complete.test.d.ts.map +0 -1
  682. package/src/tasks/__tests__/complete.test.js +0 -230
  683. package/src/tasks/__tests__/complete.test.js.map +0 -1
  684. package/src/tasks/__tests__/delete.test.d.ts.map +0 -1
  685. package/src/tasks/__tests__/delete.test.js +0 -183
  686. package/src/tasks/__tests__/delete.test.js.map +0 -1
  687. package/src/tasks/__tests__/dependency-check.test.d.ts.map +0 -1
  688. package/src/tasks/__tests__/dependency-check.test.js +0 -293
  689. package/src/tasks/__tests__/dependency-check.test.js.map +0 -1
  690. package/src/tasks/__tests__/deps-ready.test.d.ts.map +0 -1
  691. package/src/tasks/__tests__/deps-ready.test.js +0 -68
  692. package/src/tasks/__tests__/deps-ready.test.js.map +0 -1
  693. package/src/tasks/__tests__/epic-enforcement.test.d.ts.map +0 -1
  694. package/src/tasks/__tests__/epic-enforcement.test.js +0 -669
  695. package/src/tasks/__tests__/epic-enforcement.test.js.map +0 -1
  696. package/src/tasks/__tests__/find.test.d.ts.map +0 -1
  697. package/src/tasks/__tests__/find.test.js +0 -163
  698. package/src/tasks/__tests__/find.test.js.map +0 -1
  699. package/src/tasks/__tests__/graph-ops.test.d.ts.map +0 -1
  700. package/src/tasks/__tests__/graph-ops.test.js +0 -174
  701. package/src/tasks/__tests__/graph-ops.test.js.map +0 -1
  702. package/src/tasks/__tests__/hierarchy-policy.test.d.ts.map +0 -1
  703. package/src/tasks/__tests__/hierarchy-policy.test.js +0 -399
  704. package/src/tasks/__tests__/hierarchy-policy.test.js.map +0 -1
  705. package/src/tasks/__tests__/hierarchy.test.d.ts.map +0 -1
  706. package/src/tasks/__tests__/hierarchy.test.js +0 -302
  707. package/src/tasks/__tests__/hierarchy.test.js.map +0 -1
  708. package/src/tasks/__tests__/id-generator.test.d.ts.map +0 -1
  709. package/src/tasks/__tests__/id-generator.test.js +0 -59
  710. package/src/tasks/__tests__/id-generator.test.js.map +0 -1
  711. package/src/tasks/__tests__/labels.test.d.ts.map +0 -1
  712. package/src/tasks/__tests__/labels.test.js +0 -173
  713. package/src/tasks/__tests__/labels.test.js.map +0 -1
  714. package/src/tasks/__tests__/list.test.d.ts.map +0 -1
  715. package/src/tasks/__tests__/list.test.js +0 -272
  716. package/src/tasks/__tests__/list.test.js.map +0 -1
  717. package/src/tasks/__tests__/minimal-test.test.d.ts.map +0 -1
  718. package/src/tasks/__tests__/minimal-test.test.js +0 -25
  719. package/src/tasks/__tests__/minimal-test.test.js.map +0 -1
  720. package/src/tasks/__tests__/phase-tracking.test.d.ts.map +0 -1
  721. package/src/tasks/__tests__/phase-tracking.test.js +0 -209
  722. package/src/tasks/__tests__/phase-tracking.test.js.map +0 -1
  723. package/src/tasks/__tests__/pipeline-stage.test.d.ts.map +0 -1
  724. package/src/tasks/__tests__/pipeline-stage.test.js +0 -277
  725. package/src/tasks/__tests__/pipeline-stage.test.js.map +0 -1
  726. package/src/tasks/__tests__/plan-priority.test.d.ts.map +0 -1
  727. package/src/tasks/__tests__/plan-priority.test.js +0 -133
  728. package/src/tasks/__tests__/plan-priority.test.js.map +0 -1
  729. package/src/tasks/__tests__/priority-normalization.test.d.ts.map +0 -1
  730. package/src/tasks/__tests__/priority-normalization.test.js +0 -117
  731. package/src/tasks/__tests__/priority-normalization.test.js.map +0 -1
  732. package/src/tasks/__tests__/relates.test.d.ts.map +0 -1
  733. package/src/tasks/__tests__/relates.test.js +0 -84
  734. package/src/tasks/__tests__/relates.test.js.map +0 -1
  735. package/src/tasks/__tests__/show-deps.test.d.ts.map +0 -1
  736. package/src/tasks/__tests__/show-deps.test.js +0 -182
  737. package/src/tasks/__tests__/show-deps.test.js.map +0 -1
  738. package/src/tasks/__tests__/show.test.d.ts.map +0 -1
  739. package/src/tasks/__tests__/show.test.js +0 -126
  740. package/src/tasks/__tests__/show.test.js.map +0 -1
  741. package/src/tasks/__tests__/staleness.test.d.ts.map +0 -1
  742. package/src/tasks/__tests__/staleness.test.js +0 -154
  743. package/src/tasks/__tests__/staleness.test.js.map +0 -1
  744. package/src/tasks/__tests__/task-ops-depends.test.d.ts.map +0 -1
  745. package/src/tasks/__tests__/task-ops-depends.test.js +0 -118
  746. package/src/tasks/__tests__/task-ops-depends.test.js.map +0 -1
  747. package/src/tasks/__tests__/update.test.d.ts.map +0 -1
  748. package/src/tasks/__tests__/update.test.js +0 -320
  749. package/src/tasks/__tests__/update.test.js.map +0 -1
  750. package/src/validation/__tests__/chain-validation.test.d.ts.map +0 -1
  751. package/src/validation/__tests__/chain-validation.test.js +0 -204
  752. package/src/validation/__tests__/chain-validation.test.js.map +0 -1
  753. package/src/validation/__tests__/compliance.test.d.ts.map +0 -1
  754. package/src/validation/__tests__/compliance.test.js +0 -83
  755. package/src/validation/__tests__/compliance.test.js.map +0 -1
  756. package/src/validation/__tests__/docs-sync.test.d.ts.map +0 -1
  757. package/src/validation/__tests__/docs-sync.test.js +0 -243
  758. package/src/validation/__tests__/docs-sync.test.js.map +0 -1
  759. package/src/validation/__tests__/doctor-gitignore.test.d.ts.map +0 -1
  760. package/src/validation/__tests__/doctor-gitignore.test.js +0 -154
  761. package/src/validation/__tests__/doctor-gitignore.test.js.map +0 -1
  762. package/src/validation/__tests__/doctor-injection.test.d.ts.map +0 -1
  763. package/src/validation/__tests__/doctor-injection.test.js +0 -230
  764. package/src/validation/__tests__/doctor-injection.test.js.map +0 -1
  765. package/src/validation/__tests__/doctor.test.d.ts.map +0 -1
  766. package/src/validation/__tests__/doctor.test.js +0 -202
  767. package/src/validation/__tests__/doctor.test.js.map +0 -1
  768. package/src/validation/__tests__/engine.test.d.ts.map +0 -1
  769. package/src/validation/__tests__/engine.test.js +0 -346
  770. package/src/validation/__tests__/engine.test.js.map +0 -1
  771. package/src/validation/__tests__/manifest.test.d.ts.map +0 -1
  772. package/src/validation/__tests__/manifest.test.js +0 -244
  773. package/src/validation/__tests__/manifest.test.js.map +0 -1
  774. package/src/validation/__tests__/protocol-common.test.d.ts.map +0 -1
  775. package/src/validation/__tests__/protocol-common.test.js +0 -112
  776. package/src/validation/__tests__/protocol-common.test.js.map +0 -1
  777. package/src/validation/__tests__/verification.test.d.ts.map +0 -1
  778. package/src/validation/__tests__/verification.test.js +0 -277
  779. package/src/validation/__tests__/verification.test.js.map +0 -1
  780. package/src/validation/protocols/release-protocol.ts +0 -80
  781. package/src/validation/protocols/testing-protocol.ts +0 -93
  782. package/src/validation/protocols/validation-protocol.ts +0 -93
@@ -1,1220 +0,0 @@
1
- /**
2
- * Comprehensive E2E tests for NEXUS cross-project registry system.
3
- *
4
- * Covers: audit log verification, health status, permission updates,
5
- * schema integrity, cross-project reference resolution, orphan detection
6
- * with real project deletion, multi-project scenarios, discovery module,
7
- * and edge cases.
8
- *
9
- * @task WAVE-1D
10
- */
11
- import { randomUUID } from 'node:crypto';
12
- import { existsSync } from 'node:fs';
13
- import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
14
- import { tmpdir } from 'node:os';
15
- import { join } from 'node:path';
16
- import { eq } from 'drizzle-orm';
17
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
18
- import { seedTasks } from '../../store/__tests__/test-db-helper.js';
19
- import { nexusAuditLog, nexusSchemaMeta, projectRegistry } from '../../store/nexus-schema.js';
20
- import { getNexusDb, NEXUS_SCHEMA_VERSION, resetNexusDbState } from '../../store/nexus-sqlite.js';
21
- import { resetDbState } from '../../store/sqlite.js';
22
- import { createSqliteDataAccessor } from '../../store/sqlite-data-accessor.js';
23
- import { blockingAnalysis, buildGlobalGraph, criticalPath, invalidateGraphCache, nexusDeps, orphanDetection, resolveCrossDeps, } from '../deps.js';
24
- import { discoverRelated, extractKeywords, searchAcrossProjects } from '../discover.js';
25
- import { generateProjectHash } from '../hash.js';
26
- import { canExecute, canRead, canWrite, checkPermission, checkPermissionDetail, getPermission, permissionLevel, requirePermission, setPermission, } from '../permissions.js';
27
- import { getProjectFromQuery, parseQuery, resolveTask, validateSyntax } from '../query.js';
28
- import { nexusGetProject, nexusInit, nexusList, nexusProjectExists, nexusReconcile, nexusRegister, nexusSetPermission, nexusSync, nexusSyncAll, nexusUnregister, readRegistry, readRegistryRequired, } from '../registry.js';
29
- // ── Test helpers ─────────────────────────────────────────────────────
30
- /** Create a test project with tasks in SQLite (tasks.db). */
31
- async function createTestProjectDb(dir, tasks) {
32
- await mkdir(join(dir, '.cleo'), { recursive: true });
33
- resetDbState();
34
- const accessor = await createSqliteDataAccessor(dir);
35
- await seedTasks(accessor, tasks);
36
- await accessor.close();
37
- resetDbState();
38
- }
39
- /** Create a test project with tasks.db and project-info.json. */
40
- async function createTestProjectWithId(dir, tasks, projectId) {
41
- const pid = projectId ?? randomUUID();
42
- await createTestProjectDb(dir, tasks);
43
- await writeFile(join(dir, '.cleo', 'project-info.json'), JSON.stringify({ projectId: pid, createdAt: new Date().toISOString() }));
44
- return pid;
45
- }
46
- // ── Shared state ─────────────────────────────────────────────────────
47
- let testDir;
48
- let registryDir;
49
- beforeEach(async () => {
50
- testDir = await mkdtemp(join(tmpdir(), 'nexus-e2e-test-'));
51
- registryDir = join(testDir, 'cleo-home');
52
- await mkdir(registryDir, { recursive: true });
53
- process.env['CLEO_HOME'] = registryDir;
54
- process.env['NEXUS_HOME'] = join(registryDir, 'nexus');
55
- process.env['NEXUS_CACHE_DIR'] = join(registryDir, 'nexus', 'cache');
56
- process.env['NEXUS_CURRENT_PROJECT'] = 'e2e-project';
57
- delete process.env['NEXUS_SKIP_PERMISSION_CHECK'];
58
- resetNexusDbState();
59
- resetDbState();
60
- invalidateGraphCache();
61
- });
62
- afterEach(async () => {
63
- delete process.env['CLEO_HOME'];
64
- delete process.env['NEXUS_HOME'];
65
- delete process.env['NEXUS_CACHE_DIR'];
66
- delete process.env['NEXUS_CURRENT_PROJECT'];
67
- delete process.env['NEXUS_SKIP_PERMISSION_CHECK'];
68
- resetNexusDbState();
69
- resetDbState();
70
- invalidateGraphCache();
71
- await rm(testDir, { recursive: true, force: true });
72
- });
73
- // =====================================================================
74
- // 1. AUDIT LOG VERIFICATION
75
- // =====================================================================
76
- describe('audit log', () => {
77
- it('register creates an audit entry with action=register', async () => {
78
- const projDir = join(testDir, 'audit-proj');
79
- await createTestProjectDb(projDir, [
80
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
81
- ]);
82
- const hash = await nexusRegister(projDir, 'audit-proj', 'read');
83
- const db = await getNexusDb();
84
- const entries = await db
85
- .select()
86
- .from(nexusAuditLog)
87
- .where(eq(nexusAuditLog.action, 'register'));
88
- expect(entries.length).toBeGreaterThanOrEqual(1);
89
- const entry = entries.find((e) => e.projectHash === hash);
90
- expect(entry).toBeDefined();
91
- expect(entry.action).toBe('register');
92
- expect(entry.success).toBe(1);
93
- expect(entry.domain).toBe('nexus');
94
- expect(entry.timestamp).toBeTruthy();
95
- expect(entry.id).toBeTruthy();
96
- });
97
- it('unregister creates an audit entry with action=unregister', async () => {
98
- const projDir = join(testDir, 'unreg-proj');
99
- await createTestProjectDb(projDir, [
100
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
101
- ]);
102
- const hash = await nexusRegister(projDir, 'unreg-proj', 'read');
103
- await nexusUnregister('unreg-proj');
104
- const db = await getNexusDb();
105
- const entries = await db
106
- .select()
107
- .from(nexusAuditLog)
108
- .where(eq(nexusAuditLog.action, 'unregister'));
109
- expect(entries.length).toBeGreaterThanOrEqual(1);
110
- const entry = entries.find((e) => e.projectHash === hash);
111
- expect(entry).toBeDefined();
112
- expect(entry.success).toBe(1);
113
- });
114
- it('sync creates an audit entry with action=sync', async () => {
115
- const projDir = join(testDir, 'sync-audit-proj');
116
- await createTestProjectDb(projDir, [
117
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
118
- ]);
119
- await nexusRegister(projDir, 'sync-audit-proj', 'read');
120
- await nexusSync('sync-audit-proj');
121
- const db = await getNexusDb();
122
- const entries = await db.select().from(nexusAuditLog).where(eq(nexusAuditLog.action, 'sync'));
123
- expect(entries.length).toBeGreaterThanOrEqual(1);
124
- expect(entries[0].success).toBe(1);
125
- });
126
- it('sync-all creates an audit entry with action=sync-all', async () => {
127
- const projDir = join(testDir, 'syncall-proj');
128
- await createTestProjectDb(projDir, [
129
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
130
- ]);
131
- await nexusRegister(projDir, 'syncall-proj', 'read');
132
- await nexusSyncAll();
133
- const db = await getNexusDb();
134
- const entries = await db
135
- .select()
136
- .from(nexusAuditLog)
137
- .where(eq(nexusAuditLog.action, 'sync-all'));
138
- expect(entries.length).toBeGreaterThanOrEqual(1);
139
- expect(entries[0].success).toBe(1);
140
- const details = JSON.parse(entries[0].detailsJson ?? '{}');
141
- expect(details.synced).toBe(1);
142
- expect(details.failed).toBe(0);
143
- });
144
- it('set-permission creates an audit entry', async () => {
145
- const projDir = join(testDir, 'perm-audit-proj');
146
- await createTestProjectDb(projDir, [
147
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
148
- ]);
149
- await nexusRegister(projDir, 'perm-audit-proj', 'read');
150
- await nexusSetPermission('perm-audit-proj', 'execute');
151
- const db = await getNexusDb();
152
- const entries = await db
153
- .select()
154
- .from(nexusAuditLog)
155
- .where(eq(nexusAuditLog.action, 'set-permission'));
156
- expect(entries.length).toBeGreaterThanOrEqual(1);
157
- expect(entries[0].success).toBe(1);
158
- const details = JSON.parse(entries[0].detailsJson ?? '{}');
159
- expect(details.permission).toBe('execute');
160
- });
161
- it('reconcile creates audit entries', async () => {
162
- const projDir = join(testDir, 'recon-audit-proj');
163
- await createTestProjectWithId(projDir, [
164
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
165
- ]);
166
- await nexusReconcile(projDir);
167
- const db = await getNexusDb();
168
- const entries = await db
169
- .select()
170
- .from(nexusAuditLog)
171
- .where(eq(nexusAuditLog.action, 'reconcile'));
172
- expect(entries.length).toBeGreaterThanOrEqual(1);
173
- expect(entries[0].success).toBe(1);
174
- });
175
- it('audit entries survive project deletion', async () => {
176
- const projDir = join(testDir, 'surviving-audit-proj');
177
- await createTestProjectDb(projDir, [
178
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
179
- ]);
180
- const hash = await nexusRegister(projDir, 'surviving-audit-proj', 'read');
181
- await nexusUnregister('surviving-audit-proj');
182
- // Verify audit entries remain even after project is removed
183
- const db = await getNexusDb();
184
- const entries = await db
185
- .select()
186
- .from(nexusAuditLog)
187
- .where(eq(nexusAuditLog.projectHash, hash));
188
- // At least register + unregister = 2 entries
189
- expect(entries.length).toBeGreaterThanOrEqual(2);
190
- const actions = entries.map((e) => e.action);
191
- expect(actions).toContain('register');
192
- expect(actions).toContain('unregister');
193
- });
194
- it('audit entries have valid timestamps', async () => {
195
- const projDir = join(testDir, 'ts-audit-proj');
196
- await createTestProjectDb(projDir, [
197
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
198
- ]);
199
- await nexusRegister(projDir, 'ts-audit-proj', 'read');
200
- const db = await getNexusDb();
201
- const entries = await db.select().from(nexusAuditLog);
202
- for (const entry of entries) {
203
- expect(entry.timestamp).toBeTruthy();
204
- // Should be parseable as a date
205
- const date = new Date(entry.timestamp);
206
- expect(date.getTime()).not.toBeNaN();
207
- }
208
- });
209
- it('audit entries have unique UUIDs', async () => {
210
- const projDir = join(testDir, 'uuid-audit-proj');
211
- await createTestProjectDb(projDir, [
212
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
213
- ]);
214
- await nexusRegister(projDir, 'uuid-audit-proj', 'read');
215
- await nexusSync('uuid-audit-proj');
216
- await nexusUnregister('uuid-audit-proj');
217
- const db = await getNexusDb();
218
- const entries = await db.select().from(nexusAuditLog);
219
- const ids = entries.map((e) => e.id);
220
- const uniqueIds = new Set(ids);
221
- expect(uniqueIds.size).toBe(ids.length);
222
- });
223
- });
224
- // =====================================================================
225
- // 2. HEALTH STATUS
226
- // =====================================================================
227
- describe('health status', () => {
228
- it('newly registered project has unknown health status', async () => {
229
- const projDir = join(testDir, 'health-proj');
230
- await createTestProjectDb(projDir, [
231
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
232
- ]);
233
- await nexusRegister(projDir, 'health-proj', 'read');
234
- const project = await nexusGetProject('health-proj');
235
- expect(project).not.toBeNull();
236
- expect(project.healthStatus).toBe('unknown');
237
- expect(project.healthLastCheck).toBeNull();
238
- });
239
- it('health status can be updated directly via DB', async () => {
240
- const projDir = join(testDir, 'health-update-proj');
241
- await createTestProjectDb(projDir, [
242
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
243
- ]);
244
- await nexusRegister(projDir, 'health-update-proj', 'read');
245
- // Simulate health check update directly
246
- const db = await getNexusDb();
247
- const hash = generateProjectHash(projDir);
248
- const now = new Date().toISOString();
249
- await db
250
- .update(projectRegistry)
251
- .set({ healthStatus: 'healthy', healthLastCheck: now })
252
- .where(eq(projectRegistry.projectHash, hash));
253
- const project = await nexusGetProject('health-update-proj');
254
- expect(project).not.toBeNull();
255
- expect(project.healthStatus).toBe('healthy');
256
- expect(project.healthLastCheck).toBe(now);
257
- });
258
- it('health status values are preserved through readRegistry', async () => {
259
- const projDir = join(testDir, 'health-registry-proj');
260
- await createTestProjectDb(projDir, [
261
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
262
- ]);
263
- await nexusRegister(projDir, 'health-registry-proj', 'read');
264
- const db = await getNexusDb();
265
- const hash = generateProjectHash(projDir);
266
- await db
267
- .update(projectRegistry)
268
- .set({ healthStatus: 'degraded' })
269
- .where(eq(projectRegistry.projectHash, hash));
270
- const registry = await readRegistry();
271
- expect(registry).not.toBeNull();
272
- const project = Object.values(registry.projects).find((p) => p.name === 'health-registry-proj');
273
- expect(project).toBeDefined();
274
- expect(project.healthStatus).toBe('degraded');
275
- });
276
- it('all valid health status values can be stored and retrieved', async () => {
277
- const statuses = ['unknown', 'healthy', 'degraded', 'unreachable'];
278
- for (const status of statuses) {
279
- const projDir = join(testDir, `health-${status}-proj`);
280
- await createTestProjectDb(projDir, [
281
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
282
- ]);
283
- await nexusRegister(projDir, `health-${status}`, 'read');
284
- const db = await getNexusDb();
285
- const hash = generateProjectHash(projDir);
286
- await db
287
- .update(projectRegistry)
288
- .set({ healthStatus: status })
289
- .where(eq(projectRegistry.projectHash, hash));
290
- const project = await nexusGetProject(`health-${status}`);
291
- expect(project.healthStatus).toBe(status);
292
- }
293
- });
294
- });
295
- // =====================================================================
296
- // 3. PERMISSION UPDATES
297
- // =====================================================================
298
- describe('permission updates', () => {
299
- it('nexusSetPermission changes permission from read to write', async () => {
300
- const projDir = join(testDir, 'perm-rw-proj');
301
- await createTestProjectDb(projDir, [
302
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
303
- ]);
304
- await nexusRegister(projDir, 'perm-rw-proj', 'read');
305
- expect((await nexusGetProject('perm-rw-proj')).permissions).toBe('read');
306
- await nexusSetPermission('perm-rw-proj', 'write');
307
- expect((await nexusGetProject('perm-rw-proj')).permissions).toBe('write');
308
- });
309
- it('nexusSetPermission changes permission from read to execute', async () => {
310
- const projDir = join(testDir, 'perm-rx-proj');
311
- await createTestProjectDb(projDir, [
312
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
313
- ]);
314
- await nexusRegister(projDir, 'perm-rx-proj', 'read');
315
- await nexusSetPermission('perm-rx-proj', 'execute');
316
- const project = await nexusGetProject('perm-rx-proj');
317
- expect(project.permissions).toBe('execute');
318
- expect(await checkPermission('perm-rx-proj', 'read')).toBe(true);
319
- expect(await checkPermission('perm-rx-proj', 'write')).toBe(true);
320
- expect(await checkPermission('perm-rx-proj', 'execute')).toBe(true);
321
- });
322
- it('nexusSetPermission can downgrade from execute to read', async () => {
323
- const projDir = join(testDir, 'perm-down-proj');
324
- await createTestProjectDb(projDir, [
325
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
326
- ]);
327
- await nexusRegister(projDir, 'perm-down-proj', 'execute');
328
- await nexusSetPermission('perm-down-proj', 'read');
329
- expect(await checkPermission('perm-down-proj', 'write')).toBe(false);
330
- expect(await checkPermission('perm-down-proj', 'execute')).toBe(false);
331
- expect(await checkPermission('perm-down-proj', 'read')).toBe(true);
332
- });
333
- it('nexusSetPermission throws for non-existent project', async () => {
334
- await nexusInit();
335
- await expect(nexusSetPermission('no-such-project', 'write')).rejects.toThrow(/not found/i);
336
- });
337
- it('setPermission (from permissions module) updates correctly', async () => {
338
- const projDir = join(testDir, 'setperm-proj');
339
- await createTestProjectDb(projDir, [
340
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
341
- ]);
342
- await nexusRegister(projDir, 'setperm-proj', 'read');
343
- await setPermission('setperm-proj', 'execute');
344
- const perm = await getPermission('setperm-proj');
345
- expect(perm).toBe('execute');
346
- });
347
- it('setPermission throws on empty name', async () => {
348
- await expect(setPermission('', 'read')).rejects.toThrow(/required/i);
349
- });
350
- });
351
- // =====================================================================
352
- // 4. SCHEMA INTEGRITY
353
- // =====================================================================
354
- describe('schema integrity', () => {
355
- it('nexus.db is created with correct schema version in nexus_schema_meta', async () => {
356
- await nexusInit();
357
- const db = await getNexusDb();
358
- const meta = await db
359
- .select()
360
- .from(nexusSchemaMeta)
361
- .where(eq(nexusSchemaMeta.key, 'schemaVersion'));
362
- expect(meta.length).toBe(1);
363
- expect(meta[0].value).toBe(NEXUS_SCHEMA_VERSION);
364
- });
365
- it('all required tables exist after init', async () => {
366
- await nexusInit();
367
- const db = await getNexusDb();
368
- // Verify each table can be queried
369
- const projects = await db.select().from(projectRegistry);
370
- expect(Array.isArray(projects)).toBe(true);
371
- const auditLogs = await db.select().from(nexusAuditLog);
372
- expect(Array.isArray(auditLogs)).toBe(true);
373
- const schemaMeta = await db.select().from(nexusSchemaMeta);
374
- expect(Array.isArray(schemaMeta)).toBe(true);
375
- });
376
- it('project_registry indexes exist and are usable', async () => {
377
- await nexusInit();
378
- // Register a project to populate the table
379
- const projDir = join(testDir, 'idx-proj');
380
- await createTestProjectDb(projDir, [
381
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
382
- ]);
383
- await nexusRegister(projDir, 'idx-proj', 'read');
384
- // Query by hash (uses idx_project_registry_hash)
385
- const byHash = await nexusGetProject(generateProjectHash(projDir));
386
- expect(byHash).not.toBeNull();
387
- // Query by name (uses idx_project_registry_name)
388
- const byName = await nexusGetProject('idx-proj');
389
- expect(byName).not.toBeNull();
390
- });
391
- it('nexus.db file is created on disk', async () => {
392
- await nexusInit();
393
- const dbPath = join(registryDir, 'nexus.db');
394
- expect(existsSync(dbPath)).toBe(true);
395
- });
396
- it('readRegistry returns null before initialization when DB does not exist', async () => {
397
- // Point to a non-existent CLEO_HOME
398
- const noDir = join(testDir, 'nonexistent-cleo-home');
399
- process.env['CLEO_HOME'] = noDir;
400
- resetNexusDbState();
401
- // readRegistry should return null (not throw)
402
- const registry = await readRegistry();
403
- // It may or may not be null depending on whether getNexusDb auto-creates;
404
- // the important thing is it doesn't throw
405
- expect(registry === null || typeof registry === 'object').toBe(true);
406
- });
407
- it('readRegistryRequired throws when no projects exist and DB is empty', async () => {
408
- // readRegistryRequired only throws if readRegistry returns null.
409
- // With SQLite auto-initialization, it returns an empty registry.
410
- await nexusInit();
411
- const registry = await readRegistryRequired();
412
- expect(registry).not.toBeNull();
413
- expect(Object.keys(registry.projects)).toHaveLength(0);
414
- });
415
- });
416
- // =====================================================================
417
- // 5. MULTI-PROJECT REGISTRATION & LISTING
418
- // =====================================================================
419
- describe('multi-project operations', () => {
420
- it('registers and lists multiple projects', async () => {
421
- const projects = [];
422
- for (let i = 0; i < 5; i++) {
423
- const dir = join(testDir, `multi-proj-${i}`);
424
- await createTestProjectDb(dir, [
425
- { id: `T00${i}`, title: `Task ${i}`, status: 'pending', description: `Desc ${i}` },
426
- ]);
427
- await nexusRegister(dir, `multi-${i}`, 'read');
428
- projects.push(`multi-${i}`);
429
- }
430
- const listed = await nexusList();
431
- expect(listed).toHaveLength(5);
432
- const names = listed.map((p) => p.name).sort();
433
- expect(names).toEqual(projects.sort());
434
- });
435
- it('nexusSyncAll syncs multiple projects correctly', async () => {
436
- for (let i = 0; i < 3; i++) {
437
- const dir = join(testDir, `sync-multi-${i}`);
438
- await createTestProjectDb(dir, [
439
- { id: `T00${i}`, title: `Task ${i}`, status: 'pending', description: `Desc ${i}` },
440
- ]);
441
- await nexusRegister(dir, `sync-multi-${i}`, 'read');
442
- }
443
- const result = await nexusSyncAll();
444
- expect(result.synced).toBe(3);
445
- expect(result.failed).toBe(0);
446
- });
447
- it('readRegistry returns all projects with correct structure', async () => {
448
- const dirA = join(testDir, 'reg-a');
449
- const dirB = join(testDir, 'reg-b');
450
- await createTestProjectDb(dirA, [
451
- { id: 'T001', title: 'Task A', status: 'pending', description: 'A' },
452
- ]);
453
- await createTestProjectDb(dirB, [
454
- { id: 'T002', title: 'Task B', status: 'done', description: 'B' },
455
- ]);
456
- await nexusRegister(dirA, 'proj-a', 'read');
457
- await nexusRegister(dirB, 'proj-b', 'write');
458
- const registry = await readRegistry();
459
- expect(registry).not.toBeNull();
460
- expect(registry.schemaVersion).toBe('1.0.0');
461
- expect(Object.keys(registry.projects)).toHaveLength(2);
462
- // Verify project structure
463
- const projectA = Object.values(registry.projects).find((p) => p.name === 'proj-a');
464
- expect(projectA).toBeDefined();
465
- expect(projectA.path).toBe(dirA);
466
- expect(projectA.permissions).toBe('read');
467
- expect(projectA.taskCount).toBe(1);
468
- const projectB = Object.values(registry.projects).find((p) => p.name === 'proj-b');
469
- expect(projectB).toBeDefined();
470
- expect(projectB.permissions).toBe('write');
471
- });
472
- it('unregistering one project does not affect others', async () => {
473
- const dirA = join(testDir, 'keep-a');
474
- const dirB = join(testDir, 'remove-b');
475
- await createTestProjectDb(dirA, [
476
- { id: 'T001', title: 'Task A', status: 'pending', description: 'A' },
477
- ]);
478
- await createTestProjectDb(dirB, [
479
- { id: 'T002', title: 'Task B', status: 'pending', description: 'B' },
480
- ]);
481
- await nexusRegister(dirA, 'keep-a', 'read');
482
- await nexusRegister(dirB, 'remove-b', 'read');
483
- await nexusUnregister('remove-b');
484
- expect(await nexusProjectExists('keep-a')).toBe(true);
485
- expect(await nexusProjectExists('remove-b')).toBe(false);
486
- const listed = await nexusList();
487
- expect(listed).toHaveLength(1);
488
- expect(listed[0].name).toBe('keep-a');
489
- });
490
- });
491
- // =====================================================================
492
- // 6. CROSS-PROJECT TASK RESOLUTION
493
- // =====================================================================
494
- describe('cross-project task resolution', () => {
495
- let projADir;
496
- let projBDir;
497
- beforeEach(async () => {
498
- projADir = join(testDir, 'xproj-a');
499
- projBDir = join(testDir, 'xproj-b');
500
- await createTestProjectDb(projADir, [
501
- { id: 'T001', title: 'Auth API', status: 'active', description: 'Auth', labels: ['auth'] },
502
- {
503
- id: 'T002',
504
- title: 'Users API',
505
- status: 'pending',
506
- description: 'Users',
507
- depends: ['T001'],
508
- },
509
- ]);
510
- await createTestProjectDb(projBDir, [
511
- {
512
- id: 'T100',
513
- title: 'Login UI',
514
- status: 'blocked',
515
- description: 'Login page',
516
- labels: ['auth'],
517
- },
518
- {
519
- id: 'T101',
520
- title: 'Dashboard',
521
- status: 'pending',
522
- description: 'Dashboard',
523
- depends: ['T100'],
524
- },
525
- ]);
526
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
527
- await nexusRegister(projADir, 'backend', 'read');
528
- await nexusRegister(projBDir, 'frontend', 'read');
529
- });
530
- it('resolves task from named project', async () => {
531
- const task = await resolveTask('backend:T001');
532
- expect(Array.isArray(task)).toBe(false);
533
- if (!Array.isArray(task)) {
534
- expect(task.id).toBe('T001');
535
- expect(task.title).toBe('Auth API');
536
- expect(task._project).toBe('backend');
537
- }
538
- });
539
- it('resolves task from a different project', async () => {
540
- const task = await resolveTask('frontend:T100');
541
- expect(Array.isArray(task)).toBe(false);
542
- if (!Array.isArray(task)) {
543
- expect(task.id).toBe('T100');
544
- expect(task.title).toBe('Login UI');
545
- expect(task._project).toBe('frontend');
546
- }
547
- });
548
- it('wildcard resolves matching tasks across projects', async () => {
549
- const tasks = await resolveTask('*:T001');
550
- expect(Array.isArray(tasks)).toBe(true);
551
- if (Array.isArray(tasks)) {
552
- expect(tasks.length).toBeGreaterThanOrEqual(1);
553
- expect(tasks[0]._project).toBe('backend');
554
- }
555
- });
556
- it('throws for task not found in specific project', async () => {
557
- await expect(resolveTask('frontend:T001')).rejects.toThrow(/not found/i);
558
- });
559
- it('throws for non-existent project', async () => {
560
- await expect(resolveTask('nonexistent:T001')).rejects.toThrow(/not found/i);
561
- });
562
- });
563
- // =====================================================================
564
- // 7. DEPENDENCY GRAPH WITH CROSS-PROJECT EDGES
565
- // =====================================================================
566
- describe('dependency graph', () => {
567
- it('builds graph from multiple projects', async () => {
568
- const dirA = join(testDir, 'graph-a');
569
- const dirB = join(testDir, 'graph-b');
570
- await createTestProjectDb(dirA, [
571
- { id: 'T001', title: 'API Base', status: 'done', description: 'API' },
572
- {
573
- id: 'T002',
574
- title: 'API Routes',
575
- status: 'active',
576
- description: 'Routes',
577
- depends: ['T001'],
578
- },
579
- ]);
580
- await createTestProjectDb(dirB, [
581
- { id: 'T010', title: 'UI Shell', status: 'active', description: 'Shell' },
582
- ]);
583
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
584
- await nexusRegister(dirA, 'api', 'read');
585
- await nexusRegister(dirB, 'ui', 'read');
586
- const graph = await buildGlobalGraph();
587
- expect(graph.nodes).toHaveLength(3);
588
- expect(graph.edges.length).toBeGreaterThanOrEqual(1);
589
- // T002 -> T001 edge within api project
590
- const edge = graph.edges.find((e) => e.from === 'T002' && e.to === 'T001');
591
- expect(edge).toBeDefined();
592
- expect(edge.fromProject).toBe('api');
593
- expect(edge.toProject).toBe('api');
594
- });
595
- it('forward deps for a task with dependencies', async () => {
596
- const dirA = join(testDir, 'fwd-a');
597
- await createTestProjectDb(dirA, [
598
- { id: 'T001', title: 'Base', status: 'done', description: 'Base' },
599
- { id: 'T002', title: 'Mid', status: 'active', description: 'Mid', depends: ['T001'] },
600
- { id: 'T003', title: 'Top', status: 'pending', description: 'Top', depends: ['T002'] },
601
- ]);
602
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
603
- await nexusRegister(dirA, 'chain', 'read');
604
- const result = await nexusDeps('chain:T003', 'forward');
605
- expect(result.depends).toHaveLength(1);
606
- expect(result.depends[0].query).toBe('chain:T002');
607
- });
608
- it('reverse deps shows what depends on a task', async () => {
609
- const dirA = join(testDir, 'rev-a');
610
- await createTestProjectDb(dirA, [
611
- { id: 'T001', title: 'Base', status: 'done', description: 'Base' },
612
- { id: 'T002', title: 'Dep', status: 'pending', description: 'Dep', depends: ['T001'] },
613
- ]);
614
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
615
- await nexusRegister(dirA, 'rev-proj', 'read');
616
- const result = await nexusDeps('rev-proj:T001', 'reverse');
617
- expect(result.blocking.length).toBeGreaterThanOrEqual(1);
618
- expect(result.blocking.some((b) => b.query.includes('T002'))).toBe(true);
619
- });
620
- it('resolveCrossDeps resolves local dependencies', async () => {
621
- const dirA = join(testDir, 'resolve-deps-a');
622
- await createTestProjectDb(dirA, [
623
- { id: 'T001', title: 'Base', status: 'done', description: 'Base' },
624
- { id: 'T002', title: 'Dep', status: 'pending', description: 'Dep', depends: ['T001'] },
625
- ]);
626
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
627
- await nexusRegister(dirA, 'resolve-proj', 'read');
628
- const resolved = await resolveCrossDeps(['T001'], 'resolve-proj');
629
- expect(resolved).toHaveLength(1);
630
- expect(resolved[0].query).toBe('resolve-proj:T001');
631
- expect(resolved[0].status).toBe('done');
632
- });
633
- });
634
- // =====================================================================
635
- // 8. ORPHAN DETECTION
636
- // =====================================================================
637
- describe('orphan detection', () => {
638
- it('detects no orphans when all deps are local', async () => {
639
- const dirA = join(testDir, 'orphan-local');
640
- await createTestProjectDb(dirA, [
641
- { id: 'T001', title: 'Base', status: 'done', description: 'Base' },
642
- { id: 'T002', title: 'Dep', status: 'pending', description: 'Dep', depends: ['T001'] },
643
- ]);
644
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
645
- await nexusRegister(dirA, 'orphan-local', 'read');
646
- const orphans = await orphanDetection();
647
- expect(orphans).toHaveLength(0);
648
- });
649
- it('returns empty array for projects with no dependencies', async () => {
650
- const dirA = join(testDir, 'no-deps-orphan');
651
- await createTestProjectDb(dirA, [
652
- { id: 'T001', title: 'Solo', status: 'done', description: 'Solo' },
653
- ]);
654
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
655
- await nexusRegister(dirA, 'no-deps', 'read');
656
- const orphans = await orphanDetection();
657
- expect(orphans).toHaveLength(0);
658
- });
659
- });
660
- // =====================================================================
661
- // 9. BLOCKING ANALYSIS
662
- // =====================================================================
663
- describe('blocking analysis extended', () => {
664
- it('handles diamond dependency pattern', async () => {
665
- // T001 -> T002 -> T004
666
- // T001 -> T003 -> T004
667
- const dirA = join(testDir, 'diamond');
668
- await createTestProjectDb(dirA, [
669
- { id: 'T001', title: 'Root', status: 'active', description: 'Root' },
670
- { id: 'T002', title: 'Left', status: 'pending', description: 'Left', depends: ['T001'] },
671
- { id: 'T003', title: 'Right', status: 'pending', description: 'Right', depends: ['T001'] },
672
- {
673
- id: 'T004',
674
- title: 'Join',
675
- status: 'pending',
676
- description: 'Join',
677
- depends: ['T002', 'T003'],
678
- },
679
- ]);
680
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
681
- await nexusRegister(dirA, 'diamond', 'read');
682
- const result = await blockingAnalysis('diamond:T001');
683
- // T001 blocks T002, T003, and transitively T004
684
- expect(result.impactScore).toBeGreaterThanOrEqual(3);
685
- const blocked = result.blocking.map((b) => b.query);
686
- expect(blocked.some((q) => q.includes('T002'))).toBe(true);
687
- expect(blocked.some((q) => q.includes('T003'))).toBe(true);
688
- expect(blocked.some((q) => q.includes('T004'))).toBe(true);
689
- });
690
- });
691
- // =====================================================================
692
- // 10. CRITICAL PATH
693
- // =====================================================================
694
- describe('critical path extended', () => {
695
- it('returns CriticalPathResult with valid structure', async () => {
696
- const dirA = join(testDir, 'crit-chain');
697
- await createTestProjectDb(dirA, [
698
- { id: 'T001', title: 'Step 1', status: 'done', description: 'S1' },
699
- { id: 'T002', title: 'Step 2', status: 'active', description: 'S2', depends: ['T001'] },
700
- { id: 'T003', title: 'Step 3', status: 'pending', description: 'S3', depends: ['T002'] },
701
- { id: 'T004', title: 'Step 4', status: 'pending', description: 'S4', depends: ['T003'] },
702
- ]);
703
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
704
- await nexusRegister(dirA, 'crit-proj', 'read');
705
- const result = await criticalPath();
706
- // criticalPath starts from root nodes (no outgoing dep edges) and traces
707
- // their dependency edges. T001 is the only root (depends on nothing).
708
- // The algorithm traces outgoing edges from roots; since T001 has no deps,
709
- // path = [T001]. length matches criticalPath array length.
710
- expect(result).toHaveProperty('criticalPath');
711
- expect(result).toHaveProperty('length');
712
- expect(result).toHaveProperty('blockedBy');
713
- expect(result.length).toBe(result.criticalPath.length);
714
- expect(result.length).toBeGreaterThanOrEqual(1);
715
- for (const entry of result.criticalPath) {
716
- expect(entry).toHaveProperty('query');
717
- expect(entry).toHaveProperty('title');
718
- }
719
- });
720
- it('returns blockedBy string (may be empty if all tasks done)', async () => {
721
- const dirA = join(testDir, 'crit-blocker');
722
- await createTestProjectDb(dirA, [
723
- { id: 'T001', title: 'Done task', status: 'done', description: 'Done' },
724
- {
725
- id: 'T002',
726
- title: 'Pending task',
727
- status: 'pending',
728
- description: 'Pending',
729
- depends: ['T001'],
730
- },
731
- ]);
732
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
733
- await nexusRegister(dirA, 'blocker-proj', 'read');
734
- const result = await criticalPath();
735
- expect(typeof result.blockedBy).toBe('string');
736
- // The algorithm finds roots (T001, status done) and traces back.
737
- // Since T001 is done, it's not a blocker. blockedBy remains ''.
738
- // This is correct behavior for the current algorithm.
739
- expect(result.length).toBeGreaterThanOrEqual(1);
740
- });
741
- });
742
- // =====================================================================
743
- // 11. DISCOVERY MODULE (discoverRelated, searchAcrossProjects)
744
- // =====================================================================
745
- describe('discovery - extractKeywords', () => {
746
- it('extracts meaningful keywords from text', () => {
747
- const keywords = extractKeywords('the auth module for user login');
748
- expect(keywords).toContain('auth');
749
- expect(keywords).toContain('module');
750
- expect(keywords).toContain('user');
751
- expect(keywords).toContain('login');
752
- expect(keywords).not.toContain('the');
753
- expect(keywords).not.toContain('for');
754
- });
755
- it('filters short words (2 chars or less)', () => {
756
- const keywords = extractKeywords('an is to be or no');
757
- expect(keywords).toHaveLength(0);
758
- });
759
- it('handles empty string', () => {
760
- const keywords = extractKeywords('');
761
- expect(keywords).toHaveLength(0);
762
- });
763
- it('lowercases and removes special characters', () => {
764
- const keywords = extractKeywords('Authentication! Module: V2.0');
765
- expect(keywords).toContain('authentication');
766
- expect(keywords).toContain('module');
767
- });
768
- });
769
- describe('discovery - searchAcrossProjects', () => {
770
- let projADir;
771
- let projBDir;
772
- beforeEach(async () => {
773
- projADir = join(testDir, 'search-a');
774
- projBDir = join(testDir, 'search-b');
775
- await createTestProjectDb(projADir, [
776
- {
777
- id: 'T001',
778
- title: 'Auth API',
779
- status: 'active',
780
- description: 'Authentication API',
781
- labels: ['auth'],
782
- },
783
- {
784
- id: 'T002',
785
- title: 'User API',
786
- status: 'pending',
787
- description: 'User management',
788
- labels: ['user'],
789
- },
790
- ]);
791
- await createTestProjectDb(projBDir, [
792
- {
793
- id: 'T100',
794
- title: 'Auth UI',
795
- status: 'blocked',
796
- description: 'Auth login page',
797
- labels: ['auth'],
798
- },
799
- {
800
- id: 'T101',
801
- title: 'Dashboard',
802
- status: 'pending',
803
- description: 'Main dashboard',
804
- labels: ['ui'],
805
- },
806
- ]);
807
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
808
- await nexusRegister(projADir, 'search-backend', 'read');
809
- await nexusRegister(projBDir, 'search-frontend', 'read');
810
- });
811
- it('searches by keyword across all projects', async () => {
812
- const result = await searchAcrossProjects('Auth');
813
- expect('error' in result).toBe(false);
814
- if (!('error' in result)) {
815
- expect(result.results.length).toBeGreaterThanOrEqual(2);
816
- const titles = result.results.map((r) => r.title);
817
- expect(titles.some((t) => t.includes('Auth'))).toBe(true);
818
- }
819
- });
820
- it('searches by task ID pattern', async () => {
821
- const result = await searchAcrossProjects('T001');
822
- expect('error' in result).toBe(false);
823
- if (!('error' in result)) {
824
- expect(result.results.length).toBeGreaterThanOrEqual(1);
825
- expect(result.results[0].id).toBe('T001');
826
- }
827
- });
828
- it('returns empty results for no match', async () => {
829
- const result = await searchAcrossProjects('zzz-no-match-xyz');
830
- expect('error' in result).toBe(false);
831
- if (!('error' in result)) {
832
- expect(result.results).toHaveLength(0);
833
- }
834
- });
835
- it('respects limit parameter', async () => {
836
- const result = await searchAcrossProjects('Auth', undefined, 1);
837
- expect('error' in result).toBe(false);
838
- if (!('error' in result)) {
839
- expect(result.results.length).toBeLessThanOrEqual(1);
840
- }
841
- });
842
- it('filters by project when projectFilter is specified', async () => {
843
- const result = await searchAcrossProjects('Auth', 'search-backend');
844
- expect('error' in result).toBe(false);
845
- if (!('error' in result)) {
846
- for (const r of result.results) {
847
- expect(r._project).toBe('search-backend');
848
- }
849
- }
850
- });
851
- it('returns error for non-existent project filter', async () => {
852
- const result = await searchAcrossProjects('Auth', 'nonexistent-project');
853
- expect('error' in result).toBe(true);
854
- if ('error' in result) {
855
- expect(result.error.code).toBe('E_NOT_FOUND');
856
- }
857
- });
858
- it('handles wildcard query syntax (*:T001)', async () => {
859
- const result = await searchAcrossProjects('*:T001');
860
- expect('error' in result).toBe(false);
861
- if (!('error' in result)) {
862
- expect(result.results.length).toBeGreaterThanOrEqual(1);
863
- }
864
- });
865
- });
866
- describe('discovery - discoverRelated', () => {
867
- let projADir;
868
- let projBDir;
869
- beforeEach(async () => {
870
- projADir = join(testDir, 'disc-a');
871
- projBDir = join(testDir, 'disc-b');
872
- await createTestProjectDb(projADir, [
873
- {
874
- id: 'T001',
875
- title: 'Auth module implementation',
876
- status: 'active',
877
- description: 'Build the authentication module',
878
- labels: ['auth', 'security'],
879
- },
880
- {
881
- id: 'T002',
882
- title: 'Database setup',
883
- status: 'done',
884
- description: 'Set up database',
885
- labels: ['db'],
886
- },
887
- ]);
888
- await createTestProjectDb(projBDir, [
889
- {
890
- id: 'T100',
891
- title: 'Auth UI component',
892
- status: 'blocked',
893
- description: 'UI for authentication flow',
894
- labels: ['auth', 'ui'],
895
- },
896
- {
897
- id: 'T101',
898
- title: 'Dashboard analytics',
899
- status: 'pending',
900
- description: 'Analytics dashboard',
901
- labels: ['ui'],
902
- },
903
- ]);
904
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
905
- await nexusRegister(projADir, 'disc-backend', 'read');
906
- await nexusRegister(projBDir, 'disc-frontend', 'read');
907
- });
908
- it('discovers related tasks by labels', async () => {
909
- const result = await discoverRelated('disc-backend:T001', 'labels');
910
- expect('error' in result).toBe(false);
911
- if (!('error' in result)) {
912
- // T100 shares the 'auth' label with T001
913
- const authMatch = result.results.find((r) => r.taskId === 'T100');
914
- expect(authMatch).toBeDefined();
915
- expect(authMatch.type).toBe('labels');
916
- expect(authMatch.reason).toContain('auth');
917
- }
918
- });
919
- it('discovers related tasks by description keywords', async () => {
920
- const result = await discoverRelated('disc-backend:T001', 'description');
921
- expect('error' in result).toBe(false);
922
- if (!('error' in result)) {
923
- // T100 shares keywords like "auth", "authentication"
924
- const descMatch = result.results.find((r) => r.taskId === 'T100');
925
- expect(descMatch).toBeDefined();
926
- expect(descMatch.type).toBe('description');
927
- }
928
- });
929
- it('auto method finds results by best match type', async () => {
930
- const result = await discoverRelated('disc-backend:T001', 'auto');
931
- expect('error' in result).toBe(false);
932
- if (!('error' in result)) {
933
- expect(result.results.length).toBeGreaterThan(0);
934
- expect(result.method).toBe('auto');
935
- }
936
- });
937
- it('returns error for invalid query syntax', async () => {
938
- const result = await discoverRelated('invalid-syntax');
939
- expect('error' in result).toBe(true);
940
- if ('error' in result) {
941
- expect(result.error.code).toBe('E_INVALID_INPUT');
942
- }
943
- });
944
- it('returns error for wildcard queries', async () => {
945
- const result = await discoverRelated('*:T001');
946
- expect('error' in result).toBe(true);
947
- if ('error' in result) {
948
- expect(result.error.code).toBe('E_INVALID_INPUT');
949
- expect(result.error.message).toContain('Wildcard');
950
- }
951
- });
952
- it('respects limit parameter', async () => {
953
- const result = await discoverRelated('disc-backend:T001', 'auto', 1);
954
- expect('error' in result).toBe(false);
955
- if (!('error' in result)) {
956
- expect(result.results.length).toBeLessThanOrEqual(1);
957
- }
958
- });
959
- it('results are sorted by score descending', async () => {
960
- const result = await discoverRelated('disc-backend:T001', 'auto', 10);
961
- expect('error' in result).toBe(false);
962
- if (!('error' in result)) {
963
- for (let i = 1; i < result.results.length; i++) {
964
- expect(result.results[i].score).toBeLessThanOrEqual(result.results[i - 1].score);
965
- }
966
- }
967
- });
968
- it('each result has correct shape', async () => {
969
- const result = await discoverRelated('disc-backend:T001', 'auto');
970
- expect('error' in result).toBe(false);
971
- if (!('error' in result)) {
972
- for (const r of result.results) {
973
- expect(r).toHaveProperty('project');
974
- expect(r).toHaveProperty('taskId');
975
- expect(r).toHaveProperty('title');
976
- expect(r).toHaveProperty('score');
977
- expect(r).toHaveProperty('type');
978
- expect(r).toHaveProperty('reason');
979
- expect(typeof r.score).toBe('number');
980
- expect(r.score).toBeGreaterThan(0);
981
- }
982
- }
983
- });
984
- });
985
- // =====================================================================
986
- // 12. RECONCILIATION EXTENDED
987
- // =====================================================================
988
- describe('reconciliation extended', () => {
989
- it('reconcile without projectId falls back to hash-based lookup', async () => {
990
- // Create a project without project-info.json
991
- const projDir = join(testDir, 'hashonly-proj');
992
- await createTestProjectDb(projDir, [
993
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
994
- ]);
995
- const hash = await nexusRegister(projDir, 'hashonly-proj', 'read');
996
- // Reconcile should find by hash (no project-info.json)
997
- const result = await nexusReconcile(projDir);
998
- expect(result.status).toBe('ok');
999
- });
1000
- it('auto-registers unknown project without projectId', async () => {
1001
- const projDir = join(testDir, 'auto-reg-no-id');
1002
- await createTestProjectDb(projDir, [
1003
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
1004
- ]);
1005
- const result = await nexusReconcile(projDir);
1006
- expect(result.status).toBe('auto_registered');
1007
- // Verify it's now in the registry
1008
- const hash = generateProjectHash(projDir);
1009
- const project = await nexusGetProject(hash);
1010
- expect(project).not.toBeNull();
1011
- });
1012
- });
1013
- // =====================================================================
1014
- // 13. EDGE CASES
1015
- // =====================================================================
1016
- describe('edge cases', () => {
1017
- it('handles project with very long path', async () => {
1018
- // Create a deeply nested directory
1019
- const deepPath = join(testDir, 'a'.repeat(50), 'b'.repeat(50), 'c'.repeat(50), 'project');
1020
- await createTestProjectDb(deepPath, [
1021
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
1022
- ]);
1023
- const hash = await nexusRegister(deepPath, 'long-path-proj', 'read');
1024
- expect(hash).toMatch(/^[a-f0-9]{12}$/);
1025
- const project = await nexusGetProject('long-path-proj');
1026
- expect(project).not.toBeNull();
1027
- expect(project.path).toBe(deepPath);
1028
- });
1029
- it('empty project path throws', async () => {
1030
- await expect(nexusRegister('', 'empty-path')).rejects.toThrow(/required/i);
1031
- });
1032
- it('empty name or hash for unregister throws', async () => {
1033
- await expect(nexusUnregister('')).rejects.toThrow(/required/i);
1034
- });
1035
- it('empty name or hash for sync throws', async () => {
1036
- await expect(nexusSync('')).rejects.toThrow(/required/i);
1037
- });
1038
- it('nexusInit is idempotent (multiple calls)', async () => {
1039
- await nexusInit();
1040
- await nexusInit();
1041
- await nexusInit();
1042
- const registry = await readRegistry();
1043
- expect(registry).not.toBeNull();
1044
- });
1045
- it('project with no tasks registers with taskCount=0', async () => {
1046
- const emptyDir = join(testDir, 'empty-tasks');
1047
- await createTestProjectDb(emptyDir, []);
1048
- await nexusRegister(emptyDir, 'empty-proj', 'read');
1049
- const project = await nexusGetProject('empty-proj');
1050
- expect(project).not.toBeNull();
1051
- expect(project.taskCount).toBe(0);
1052
- expect(project.labels).toEqual([]);
1053
- });
1054
- it('project labels are sorted and deduplicated', async () => {
1055
- const projDir = join(testDir, 'labels-proj');
1056
- await createTestProjectDb(projDir, [
1057
- {
1058
- id: 'T001',
1059
- title: 'Task 1',
1060
- status: 'pending',
1061
- description: 'a',
1062
- labels: ['z-label', 'a-label'],
1063
- },
1064
- {
1065
- id: 'T002',
1066
- title: 'Task 2',
1067
- status: 'pending',
1068
- description: 'b',
1069
- labels: ['a-label', 'm-label'],
1070
- },
1071
- ]);
1072
- await nexusRegister(projDir, 'labels-proj', 'read');
1073
- const project = await nexusGetProject('labels-proj');
1074
- expect(project.labels).toEqual(['a-label', 'm-label', 'z-label']);
1075
- });
1076
- it('nexusGetProject returns null for empty string', async () => {
1077
- await nexusInit();
1078
- const project = await nexusGetProject('');
1079
- expect(project).toBeNull();
1080
- });
1081
- it('nexusList returns empty array when nexus.db is fresh', async () => {
1082
- await nexusInit();
1083
- const projects = await nexusList();
1084
- expect(projects).toEqual([]);
1085
- });
1086
- it('readRegistry lastUpdated reflects most recent lastSeen', async () => {
1087
- const projDir = join(testDir, 'last-updated');
1088
- await createTestProjectDb(projDir, [
1089
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
1090
- ]);
1091
- await nexusRegister(projDir, 'lu-proj', 'read');
1092
- const registry = await readRegistry();
1093
- expect(registry).not.toBeNull();
1094
- expect(registry.lastUpdated).toBeTruthy();
1095
- const luDate = new Date(registry.lastUpdated);
1096
- expect(luDate.getTime()).not.toBeNaN();
1097
- });
1098
- it('project hash is deterministic and 12 hex chars', () => {
1099
- const path = '/some/unique/path/to/project';
1100
- const h1 = generateProjectHash(path);
1101
- const h2 = generateProjectHash(path);
1102
- expect(h1).toBe(h2);
1103
- expect(h1).toMatch(/^[a-f0-9]{12}$/);
1104
- expect(h1.length).toBe(12);
1105
- });
1106
- it('different paths produce different hashes', () => {
1107
- const h1 = generateProjectHash('/path/a');
1108
- const h2 = generateProjectHash('/path/b');
1109
- expect(h1).not.toBe(h2);
1110
- });
1111
- });
1112
- // =====================================================================
1113
- // 14. QUERY MODULE EXTENDED
1114
- // =====================================================================
1115
- describe('query module extended', () => {
1116
- it('validateSyntax accepts 3+ digit task IDs', () => {
1117
- expect(validateSyntax('T001')).toBe(true);
1118
- expect(validateSyntax('T99999')).toBe(true);
1119
- expect(validateSyntax('T1234567890')).toBe(true);
1120
- });
1121
- it('validateSyntax rejects empty string', () => {
1122
- expect(validateSyntax('')).toBe(false);
1123
- });
1124
- it('validateSyntax rejects task IDs with fewer than 3 digits', () => {
1125
- expect(validateSyntax('T1')).toBe(false);
1126
- expect(validateSyntax('T12')).toBe(false);
1127
- });
1128
- it('parseQuery with currentProject override', () => {
1129
- const result = parseQuery('T001', 'override-proj');
1130
- expect(result.project).toBe('override-proj');
1131
- expect(result.taskId).toBe('T001');
1132
- });
1133
- it('parseQuery dot syntax uses currentProject', () => {
1134
- const result = parseQuery('.:T001', 'my-proj');
1135
- expect(result.project).toBe('my-proj');
1136
- });
1137
- it('getProjectFromQuery extracts project correctly for all syntaxes', () => {
1138
- expect(getProjectFromQuery('my-app:T001')).toBe('my-app');
1139
- expect(getProjectFromQuery('*:T001')).toBe('*');
1140
- expect(getProjectFromQuery('T001', 'current')).toBe('current');
1141
- expect(getProjectFromQuery('.:T001', 'current')).toBe('current');
1142
- });
1143
- });
1144
- // =====================================================================
1145
- // 15. PERMISSION MODULE EXTENDED
1146
- // =====================================================================
1147
- describe('permission module extended', () => {
1148
- it('permissionLevel returns correct values for all levels', () => {
1149
- expect(permissionLevel('read')).toBe(1);
1150
- expect(permissionLevel('write')).toBe(2);
1151
- expect(permissionLevel('execute')).toBe(3);
1152
- expect(permissionLevel('invalid')).toBe(0);
1153
- expect(permissionLevel('')).toBe(0);
1154
- });
1155
- it('getPermission returns read for unregistered project', async () => {
1156
- await nexusInit();
1157
- const perm = await getPermission('no-such-proj');
1158
- expect(perm).toBe('read');
1159
- });
1160
- it('checkPermissionDetail returns full detail', async () => {
1161
- const projDir = join(testDir, 'detail-proj');
1162
- await createTestProjectDb(projDir, [
1163
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
1164
- ]);
1165
- await nexusRegister(projDir, 'detail-proj', 'write');
1166
- const result = await checkPermissionDetail('detail-proj', 'execute');
1167
- expect(result.project).toBe('detail-proj');
1168
- expect(result.required).toBe('execute');
1169
- expect(result.granted).toBe('write');
1170
- expect(result.allowed).toBe(false);
1171
- });
1172
- it('requirePermission throws with descriptive message', async () => {
1173
- const projDir = join(testDir, 'require-proj');
1174
- await createTestProjectDb(projDir, [
1175
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
1176
- ]);
1177
- await nexusRegister(projDir, 'require-proj', 'read');
1178
- await expect(requirePermission('require-proj', 'execute', 'delete task')).rejects.toThrow(/Permission denied.*execute.*require-proj/);
1179
- });
1180
- it('permission hierarchy: write includes read', async () => {
1181
- const projDir = join(testDir, 'hier-proj');
1182
- await createTestProjectDb(projDir, [
1183
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
1184
- ]);
1185
- await nexusRegister(projDir, 'hier-proj', 'write');
1186
- expect(await canRead('hier-proj')).toBe(true);
1187
- expect(await canWrite('hier-proj')).toBe(true);
1188
- expect(await canExecute('hier-proj')).toBe(false);
1189
- });
1190
- it('NEXUS_SKIP_PERMISSION_CHECK bypasses all checks', async () => {
1191
- const projDir = join(testDir, 'bypass-proj');
1192
- await createTestProjectDb(projDir, [
1193
- { id: 'T001', title: 'Task', status: 'pending', description: 'desc' },
1194
- ]);
1195
- await nexusRegister(projDir, 'bypass-proj', 'read');
1196
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
1197
- expect(await checkPermission('bypass-proj', 'execute')).toBe(true);
1198
- await expect(requirePermission('bypass-proj', 'execute')).resolves.toBeUndefined();
1199
- });
1200
- });
1201
- // =====================================================================
1202
- // 16. GRAPH CACHING
1203
- // =====================================================================
1204
- describe('graph caching', () => {
1205
- it('invalidateGraphCache forces rebuild', async () => {
1206
- const dirA = join(testDir, 'cache-proj');
1207
- await createTestProjectDb(dirA, [
1208
- { id: 'T001', title: 'Task', status: 'done', description: 'desc' },
1209
- ]);
1210
- process.env['NEXUS_SKIP_PERMISSION_CHECK'] = 'true';
1211
- await nexusRegister(dirA, 'cache-proj', 'read');
1212
- const graph1 = await buildGlobalGraph();
1213
- invalidateGraphCache();
1214
- const graph2 = await buildGlobalGraph();
1215
- // After invalidation, graph2 should be a new object
1216
- // (may or may not be strictly === depending on checksum)
1217
- expect(graph2.nodes).toHaveLength(graph1.nodes.length);
1218
- });
1219
- });
1220
- //# sourceMappingURL=nexus-e2e.test.js.map