@planu/cli 0.88.1 → 0.90.1

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 (486) hide show
  1. package/dist/cli/commands/activate.d.ts +14 -0
  2. package/dist/cli/commands/activate.d.ts.map +1 -0
  3. package/dist/cli/commands/activate.js +174 -0
  4. package/dist/cli/commands/activate.js.map +1 -0
  5. package/dist/cli/commands/doctor.d.ts +16 -0
  6. package/dist/cli/commands/doctor.d.ts.map +1 -0
  7. package/dist/cli/commands/doctor.js +162 -0
  8. package/dist/cli/commands/doctor.js.map +1 -0
  9. package/dist/cli/commands/install.d.ts +48 -0
  10. package/dist/cli/commands/install.d.ts.map +1 -0
  11. package/dist/cli/commands/install.js +348 -0
  12. package/dist/cli/commands/install.js.map +1 -0
  13. package/dist/cli/commands/uninstall.d.ts +10 -0
  14. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  15. package/dist/cli/commands/uninstall.js +133 -0
  16. package/dist/cli/commands/uninstall.js.map +1 -0
  17. package/dist/cli/router.d.ts.map +1 -1
  18. package/dist/cli/router.js +9 -1
  19. package/dist/cli/router.js.map +1 -1
  20. package/dist/config/license-plans.json +5 -2
  21. package/dist/engine/agent-generator.test.d.ts +2 -0
  22. package/dist/engine/agent-generator.test.d.ts.map +1 -0
  23. package/dist/engine/agent-generator.test.js +556 -0
  24. package/dist/engine/agent-generator.test.js.map +1 -0
  25. package/dist/engine/analyzer.test.d.ts +2 -0
  26. package/dist/engine/analyzer.test.d.ts.map +1 -0
  27. package/dist/engine/analyzer.test.js +1461 -0
  28. package/dist/engine/analyzer.test.js.map +1 -0
  29. package/dist/engine/auditor.test.d.ts +2 -0
  30. package/dist/engine/auditor.test.d.ts.map +1 -0
  31. package/dist/engine/auditor.test.js +2075 -0
  32. package/dist/engine/auditor.test.js.map +1 -0
  33. package/dist/engine/convention-scanner/codebase-scanner.js +2 -2
  34. package/dist/engine/convention-scanner/codebase-scanner.js.map +1 -1
  35. package/dist/engine/conventions-cache.d.ts +6 -0
  36. package/dist/engine/conventions-cache.d.ts.map +1 -0
  37. package/dist/engine/conventions-cache.js +20 -0
  38. package/dist/engine/conventions-cache.js.map +1 -0
  39. package/dist/engine/doc-generator.test.d.ts +2 -0
  40. package/dist/engine/doc-generator.test.d.ts.map +1 -0
  41. package/dist/engine/doc-generator.test.js +961 -0
  42. package/dist/engine/doc-generator.test.js.map +1 -0
  43. package/dist/engine/estimator.test.d.ts +2 -0
  44. package/dist/engine/estimator.test.d.ts.map +1 -0
  45. package/dist/engine/estimator.test.js +334 -0
  46. package/dist/engine/estimator.test.js.map +1 -0
  47. package/dist/engine/skill-generator.test.d.ts +2 -0
  48. package/dist/engine/skill-generator.test.d.ts.map +1 -0
  49. package/dist/engine/skill-generator.test.js +742 -0
  50. package/dist/engine/skill-generator.test.js.map +1 -0
  51. package/dist/engine/spec-migrator/filesystem-import.d.ts +14 -0
  52. package/dist/engine/spec-migrator/filesystem-import.d.ts.map +1 -0
  53. package/dist/engine/spec-migrator/filesystem-import.js +96 -0
  54. package/dist/engine/spec-migrator/filesystem-import.js.map +1 -0
  55. package/dist/engine/spec-migrator/flatten-specs.d.ts +12 -0
  56. package/dist/engine/spec-migrator/flatten-specs.d.ts.map +1 -0
  57. package/dist/engine/spec-migrator/flatten-specs.js +111 -0
  58. package/dist/engine/spec-migrator/flatten-specs.js.map +1 -0
  59. package/dist/engine/spec-migrator/folder-operations.d.ts +9 -0
  60. package/dist/engine/spec-migrator/folder-operations.d.ts.map +1 -0
  61. package/dist/engine/spec-migrator/folder-operations.js +109 -0
  62. package/dist/engine/spec-migrator/folder-operations.js.map +1 -0
  63. package/dist/engine/spec-migrator/frontmatter-parser.d.ts +11 -0
  64. package/dist/engine/spec-migrator/frontmatter-parser.d.ts.map +1 -0
  65. package/dist/engine/spec-migrator/frontmatter-parser.js +92 -0
  66. package/dist/engine/spec-migrator/frontmatter-parser.js.map +1 -0
  67. package/dist/engine/spec-migrator/index.d.ts +9 -0
  68. package/dist/engine/spec-migrator/index.d.ts.map +1 -0
  69. package/dist/engine/spec-migrator/index.js +18 -0
  70. package/dist/engine/spec-migrator/index.js.map +1 -0
  71. package/dist/engine/spec-migrator/legacy-migration.d.ts +13 -0
  72. package/dist/engine/spec-migrator/legacy-migration.d.ts.map +1 -0
  73. package/dist/engine/spec-migrator/legacy-migration.js +75 -0
  74. package/dist/engine/spec-migrator/legacy-migration.js.map +1 -0
  75. package/dist/engine/spec-migrator/migration-validator.d.ts +20 -0
  76. package/dist/engine/spec-migrator/migration-validator.d.ts.map +1 -0
  77. package/dist/engine/spec-migrator/migration-validator.js +35 -0
  78. package/dist/engine/spec-migrator/migration-validator.js.map +1 -0
  79. package/dist/engine/spec-migrator/path-utils.d.ts +13 -0
  80. package/dist/engine/spec-migrator/path-utils.d.ts.map +1 -0
  81. package/dist/engine/spec-migrator/path-utils.js +40 -0
  82. package/dist/engine/spec-migrator/path-utils.js.map +1 -0
  83. package/dist/engine/spec-migrator/prefix-migration.d.ts +11 -0
  84. package/dist/engine/spec-migrator/prefix-migration.d.ts.map +1 -0
  85. package/dist/engine/spec-migrator/prefix-migration.js +73 -0
  86. package/dist/engine/spec-migrator/prefix-migration.js.map +1 -0
  87. package/dist/engine/spec-migrator/reconcile-paths.d.ts +12 -0
  88. package/dist/engine/spec-migrator/reconcile-paths.d.ts.map +1 -0
  89. package/dist/engine/spec-migrator/reconcile-paths.js +77 -0
  90. package/dist/engine/spec-migrator/reconcile-paths.js.map +1 -0
  91. package/dist/engine/spec-migrator/version-detection.d.ts +5 -0
  92. package/dist/engine/spec-migrator/version-detection.d.ts.map +1 -0
  93. package/dist/engine/spec-migrator/version-detection.js +19 -0
  94. package/dist/engine/spec-migrator/version-detection.js.map +1 -0
  95. package/dist/engine/spec-migrator.d.ts +1 -58
  96. package/dist/engine/spec-migrator.d.ts.map +1 -1
  97. package/dist/engine/spec-migrator.js +2 -658
  98. package/dist/engine/spec-migrator.js.map +1 -1
  99. package/dist/engine/spec-summary-html/dashboard-renderer.d.ts +6 -0
  100. package/dist/engine/spec-summary-html/dashboard-renderer.d.ts.map +1 -0
  101. package/dist/engine/spec-summary-html/dashboard-renderer.js +333 -0
  102. package/dist/engine/spec-summary-html/dashboard-renderer.js.map +1 -0
  103. package/dist/engine/spec-summary-html/hash-utils.d.ts +11 -0
  104. package/dist/engine/spec-summary-html/hash-utils.d.ts.map +1 -0
  105. package/dist/engine/spec-summary-html/hash-utils.js +39 -0
  106. package/dist/engine/spec-summary-html/hash-utils.js.map +1 -0
  107. package/dist/engine/spec-summary-html/index.d.ts +4 -0
  108. package/dist/engine/spec-summary-html/index.d.ts.map +1 -0
  109. package/dist/engine/spec-summary-html/index.js +6 -0
  110. package/dist/engine/spec-summary-html/index.js.map +1 -0
  111. package/dist/engine/spec-summary-html/report-renderer.d.ts +9 -0
  112. package/dist/engine/spec-summary-html/report-renderer.d.ts.map +1 -0
  113. package/dist/engine/spec-summary-html/report-renderer.js +139 -0
  114. package/dist/engine/spec-summary-html/report-renderer.js.map +1 -0
  115. package/dist/engine/spec-summary-html.d.ts +1 -0
  116. package/dist/engine/spec-summary-html.d.ts.map +1 -1
  117. package/dist/engine/spec-summary-html.js +19 -473
  118. package/dist/engine/spec-summary-html.js.map +1 -1
  119. package/dist/engine/update-notifier.d.ts +8 -0
  120. package/dist/engine/update-notifier.d.ts.map +1 -0
  121. package/dist/engine/update-notifier.js +130 -0
  122. package/dist/engine/update-notifier.js.map +1 -0
  123. package/dist/engine/validator/dor-dod.d.ts.map +1 -1
  124. package/dist/engine/validator/dor-dod.js +8 -5
  125. package/dist/engine/validator/dor-dod.js.map +1 -1
  126. package/dist/engine/validator.d.ts.map +1 -1
  127. package/dist/engine/validator.js +4 -3
  128. package/dist/engine/validator.js.map +1 -1
  129. package/dist/engine/validator.test.d.ts +2 -0
  130. package/dist/engine/validator.test.d.ts.map +1 -0
  131. package/dist/engine/validator.test.js +2371 -0
  132. package/dist/engine/validator.test.js.map +1 -0
  133. package/dist/engine/web-fetcher.test.d.ts +2 -0
  134. package/dist/engine/web-fetcher.test.d.ts.map +1 -0
  135. package/dist/engine/web-fetcher.test.js +360 -0
  136. package/dist/engine/web-fetcher.test.js.map +1 -0
  137. package/dist/i18n/index.test.d.ts +2 -0
  138. package/dist/i18n/index.test.d.ts.map +1 -0
  139. package/dist/i18n/index.test.js +375 -0
  140. package/dist/i18n/index.test.js.map +1 -0
  141. package/dist/index.js +10 -0
  142. package/dist/index.js.map +1 -1
  143. package/dist/index.test.d.ts +2 -0
  144. package/dist/index.test.d.ts.map +1 -0
  145. package/dist/index.test.js +124 -0
  146. package/dist/index.test.js.map +1 -0
  147. package/dist/resources/patterns.test.d.ts +2 -0
  148. package/dist/resources/patterns.test.d.ts.map +1 -0
  149. package/dist/resources/patterns.test.js +142 -0
  150. package/dist/resources/patterns.test.js.map +1 -0
  151. package/dist/resources/process.test.d.ts +2 -0
  152. package/dist/resources/process.test.d.ts.map +1 -0
  153. package/dist/resources/process.test.js +48 -0
  154. package/dist/resources/process.test.js.map +1 -0
  155. package/dist/resources/registry.test.d.ts +2 -0
  156. package/dist/resources/registry.test.d.ts.map +1 -0
  157. package/dist/resources/registry.test.js +138 -0
  158. package/dist/resources/registry.test.js.map +1 -0
  159. package/dist/resources/specs.test.d.ts +2 -0
  160. package/dist/resources/specs.test.d.ts.map +1 -0
  161. package/dist/resources/specs.test.js +130 -0
  162. package/dist/resources/specs.test.js.map +1 -0
  163. package/dist/resources/templates.test.d.ts +2 -0
  164. package/dist/resources/templates.test.d.ts.map +1 -0
  165. package/dist/resources/templates.test.js +119 -0
  166. package/dist/resources/templates.test.js.map +1 -0
  167. package/dist/smoke.test.d.ts +2 -0
  168. package/dist/smoke.test.d.ts.map +1 -0
  169. package/dist/smoke.test.js +229 -0
  170. package/dist/smoke.test.js.map +1 -0
  171. package/dist/storage/base-store.test.d.ts +2 -0
  172. package/dist/storage/base-store.test.d.ts.map +1 -0
  173. package/dist/storage/base-store.test.js +180 -0
  174. package/dist/storage/base-store.test.js.map +1 -0
  175. package/dist/storage/global-store.test.d.ts +2 -0
  176. package/dist/storage/global-store.test.d.ts.map +1 -0
  177. package/dist/storage/global-store.test.js +327 -0
  178. package/dist/storage/global-store.test.js.map +1 -0
  179. package/dist/storage/index.d.ts +1 -0
  180. package/dist/storage/index.d.ts.map +1 -1
  181. package/dist/storage/index.js +1 -0
  182. package/dist/storage/index.js.map +1 -1
  183. package/dist/storage/index.test.d.ts +2 -0
  184. package/dist/storage/index.test.d.ts.map +1 -0
  185. package/dist/storage/index.test.js +56 -0
  186. package/dist/storage/index.test.js.map +1 -0
  187. package/dist/storage/knowledge-store.test.d.ts +2 -0
  188. package/dist/storage/knowledge-store.test.d.ts.map +1 -0
  189. package/dist/storage/knowledge-store.test.js +368 -0
  190. package/dist/storage/knowledge-store.test.js.map +1 -0
  191. package/dist/storage/lessons-store.d.ts +10 -0
  192. package/dist/storage/lessons-store.d.ts.map +1 -0
  193. package/dist/storage/lessons-store.js +67 -0
  194. package/dist/storage/lessons-store.js.map +1 -0
  195. package/dist/storage/metrics-store.test.d.ts +2 -0
  196. package/dist/storage/metrics-store.test.d.ts.map +1 -0
  197. package/dist/storage/metrics-store.test.js +212 -0
  198. package/dist/storage/metrics-store.test.js.map +1 -0
  199. package/dist/storage/pattern-store.test.d.ts +2 -0
  200. package/dist/storage/pattern-store.test.d.ts.map +1 -0
  201. package/dist/storage/pattern-store.test.js +224 -0
  202. package/dist/storage/pattern-store.test.js.map +1 -0
  203. package/dist/storage/spec-store.test.d.ts +2 -0
  204. package/dist/storage/spec-store.test.d.ts.map +1 -0
  205. package/dist/storage/spec-store.test.js +227 -0
  206. package/dist/storage/spec-store.test.js.map +1 -0
  207. package/dist/tools/audit.test.d.ts +2 -0
  208. package/dist/tools/audit.test.d.ts.map +1 -0
  209. package/dist/tools/audit.test.js +169 -0
  210. package/dist/tools/audit.test.js.map +1 -0
  211. package/dist/tools/challenge-spec.test.d.ts +2 -0
  212. package/dist/tools/challenge-spec.test.d.ts.map +1 -0
  213. package/dist/tools/challenge-spec.test.js +782 -0
  214. package/dist/tools/challenge-spec.test.js.map +1 -0
  215. package/dist/tools/check-versions.test.d.ts +2 -0
  216. package/dist/tools/check-versions.test.d.ts.map +1 -0
  217. package/dist/tools/check-versions.test.js +214 -0
  218. package/dist/tools/check-versions.test.js.map +1 -0
  219. package/dist/tools/clarify-requirements.test.d.ts +2 -0
  220. package/dist/tools/clarify-requirements.test.d.ts.map +1 -0
  221. package/dist/tools/clarify-requirements.test.js +161 -0
  222. package/dist/tools/clarify-requirements.test.js.map +1 -0
  223. package/dist/tools/consult-docs.test.d.ts +2 -0
  224. package/dist/tools/consult-docs.test.d.ts.map +1 -0
  225. package/dist/tools/consult-docs.test.js +140 -0
  226. package/dist/tools/consult-docs.test.js.map +1 -0
  227. package/dist/tools/create-spec/lessons-injector.d.ts +6 -0
  228. package/dist/tools/create-spec/lessons-injector.d.ts.map +1 -0
  229. package/dist/tools/create-spec/lessons-injector.js +53 -0
  230. package/dist/tools/create-spec/lessons-injector.js.map +1 -0
  231. package/dist/tools/create-spec.d.ts.map +1 -1
  232. package/dist/tools/create-spec.js +6 -1
  233. package/dist/tools/create-spec.js.map +1 -1
  234. package/dist/tools/create-spec.test.d.ts +2 -0
  235. package/dist/tools/create-spec.test.d.ts.map +1 -0
  236. package/dist/tools/create-spec.test.js +233 -0
  237. package/dist/tools/create-spec.test.js.map +1 -0
  238. package/dist/tools/define-ui-contract.test.d.ts +2 -0
  239. package/dist/tools/define-ui-contract.test.d.ts.map +1 -0
  240. package/dist/tools/define-ui-contract.test.js +479 -0
  241. package/dist/tools/define-ui-contract.test.js.map +1 -0
  242. package/dist/tools/design-schema.test.d.ts +2 -0
  243. package/dist/tools/design-schema.test.d.ts.map +1 -0
  244. package/dist/tools/design-schema.test.js +301 -0
  245. package/dist/tools/design-schema.test.js.map +1 -0
  246. package/dist/tools/detect-agent.test.d.ts +2 -0
  247. package/dist/tools/detect-agent.test.d.ts.map +1 -0
  248. package/dist/tools/detect-agent.test.js +133 -0
  249. package/dist/tools/detect-agent.test.js.map +1 -0
  250. package/dist/tools/detect-drift.test.d.ts +2 -0
  251. package/dist/tools/detect-drift.test.d.ts.map +1 -0
  252. package/dist/tools/detect-drift.test.js +312 -0
  253. package/dist/tools/detect-drift.test.js.map +1 -0
  254. package/dist/tools/discover-mcps.test.d.ts +2 -0
  255. package/dist/tools/discover-mcps.test.d.ts.map +1 -0
  256. package/dist/tools/discover-mcps.test.js +345 -0
  257. package/dist/tools/discover-mcps.test.js.map +1 -0
  258. package/dist/tools/estimate.test.d.ts +2 -0
  259. package/dist/tools/estimate.test.d.ts.map +1 -0
  260. package/dist/tools/estimate.test.js +137 -0
  261. package/dist/tools/estimate.test.js.map +1 -0
  262. package/dist/tools/generate-adr.test.d.ts +2 -0
  263. package/dist/tools/generate-adr.test.d.ts.map +1 -0
  264. package/dist/tools/generate-adr.test.js +206 -0
  265. package/dist/tools/generate-adr.test.js.map +1 -0
  266. package/dist/tools/generate-checklist.test.d.ts +2 -0
  267. package/dist/tools/generate-checklist.test.d.ts.map +1 -0
  268. package/dist/tools/generate-checklist.test.js +201 -0
  269. package/dist/tools/generate-checklist.test.js.map +1 -0
  270. package/dist/tools/generate-docs.test.d.ts +2 -0
  271. package/dist/tools/generate-docs.test.d.ts.map +1 -0
  272. package/dist/tools/generate-docs.test.js +183 -0
  273. package/dist/tools/generate-docs.test.js.map +1 -0
  274. package/dist/tools/generate-execution-plan.test.d.ts +2 -0
  275. package/dist/tools/generate-execution-plan.test.d.ts.map +1 -0
  276. package/dist/tools/generate-execution-plan.test.js +643 -0
  277. package/dist/tools/generate-execution-plan.test.js.map +1 -0
  278. package/dist/tools/generate-rules.test.d.ts +2 -0
  279. package/dist/tools/generate-rules.test.d.ts.map +1 -0
  280. package/dist/tools/generate-rules.test.js +148 -0
  281. package/dist/tools/generate-rules.test.js.map +1 -0
  282. package/dist/tools/generate-skill.test.d.ts +2 -0
  283. package/dist/tools/generate-skill.test.d.ts.map +1 -0
  284. package/dist/tools/generate-skill.test.js +138 -0
  285. package/dist/tools/generate-skill.test.js.map +1 -0
  286. package/dist/tools/generate-sub-agent.test.d.ts +2 -0
  287. package/dist/tools/generate-sub-agent.test.d.ts.map +1 -0
  288. package/dist/tools/generate-sub-agent.test.js +162 -0
  289. package/dist/tools/generate-sub-agent.test.js.map +1 -0
  290. package/dist/tools/generate-tests.test.d.ts +2 -0
  291. package/dist/tools/generate-tests.test.d.ts.map +1 -0
  292. package/dist/tools/generate-tests.test.js +222 -0
  293. package/dist/tools/generate-tests.test.js.map +1 -0
  294. package/dist/tools/init-constitution.test.d.ts +2 -0
  295. package/dist/tools/init-constitution.test.d.ts.map +1 -0
  296. package/dist/tools/init-constitution.test.js +398 -0
  297. package/dist/tools/init-constitution.test.js.map +1 -0
  298. package/dist/tools/init-project/config-builder.d.ts +12 -0
  299. package/dist/tools/init-project/config-builder.d.ts.map +1 -0
  300. package/dist/tools/init-project/config-builder.js +31 -0
  301. package/dist/tools/init-project/config-builder.js.map +1 -0
  302. package/dist/tools/init-project/git-setup.d.ts +8 -0
  303. package/dist/tools/init-project/git-setup.d.ts.map +1 -0
  304. package/dist/tools/init-project/git-setup.js +70 -0
  305. package/dist/tools/init-project/git-setup.js.map +1 -0
  306. package/dist/tools/init-project/handler.d.ts.map +1 -1
  307. package/dist/tools/init-project/handler.js +27 -364
  308. package/dist/tools/init-project/handler.js.map +1 -1
  309. package/dist/tools/init-project/lifecycle-helpers.d.ts +32 -0
  310. package/dist/tools/init-project/lifecycle-helpers.d.ts.map +1 -0
  311. package/dist/tools/init-project/lifecycle-helpers.js +153 -0
  312. package/dist/tools/init-project/lifecycle-helpers.js.map +1 -0
  313. package/dist/tools/init-project/migration-runner.d.ts +28 -0
  314. package/dist/tools/init-project/migration-runner.d.ts.map +1 -0
  315. package/dist/tools/init-project/migration-runner.js +57 -0
  316. package/dist/tools/init-project/migration-runner.js.map +1 -0
  317. package/dist/tools/init-project/result-builder.d.ts.map +1 -1
  318. package/dist/tools/init-project/result-builder.js +1 -0
  319. package/dist/tools/init-project/result-builder.js.map +1 -1
  320. package/dist/tools/init-project/rules-writer.d.ts +14 -0
  321. package/dist/tools/init-project/rules-writer.d.ts.map +1 -0
  322. package/dist/tools/init-project/rules-writer.js +43 -0
  323. package/dist/tools/init-project/rules-writer.js.map +1 -0
  324. package/dist/tools/init-project/scaffold-writer.d.ts +29 -0
  325. package/dist/tools/init-project/scaffold-writer.d.ts.map +1 -0
  326. package/dist/tools/init-project/scaffold-writer.js +76 -0
  327. package/dist/tools/init-project/scaffold-writer.js.map +1 -0
  328. package/dist/tools/init-project/stack-detector.d.ts +16 -0
  329. package/dist/tools/init-project/stack-detector.d.ts.map +1 -0
  330. package/dist/tools/init-project/stack-detector.js +19 -0
  331. package/dist/tools/init-project/stack-detector.js.map +1 -0
  332. package/dist/tools/init-project.test.d.ts +2 -0
  333. package/dist/tools/init-project.test.d.ts.map +1 -0
  334. package/dist/tools/init-project.test.js +158 -0
  335. package/dist/tools/init-project.test.js.map +1 -0
  336. package/dist/tools/integrate-pm.test.d.ts +2 -0
  337. package/dist/tools/integrate-pm.test.d.ts.map +1 -0
  338. package/dist/tools/integrate-pm.test.js +558 -0
  339. package/dist/tools/integrate-pm.test.js.map +1 -0
  340. package/dist/tools/learn.test.d.ts +2 -0
  341. package/dist/tools/learn.test.d.ts.map +1 -0
  342. package/dist/tools/learn.test.js +123 -0
  343. package/dist/tools/learn.test.js.map +1 -0
  344. package/dist/tools/lessons-handler.d.ts +6 -0
  345. package/dist/tools/lessons-handler.d.ts.map +1 -0
  346. package/dist/tools/lessons-handler.js +64 -0
  347. package/dist/tools/lessons-handler.js.map +1 -0
  348. package/dist/tools/list-specs.js +1 -1
  349. package/dist/tools/list-specs.js.map +1 -1
  350. package/dist/tools/list-specs.test.d.ts +2 -0
  351. package/dist/tools/list-specs.test.d.ts.map +1 -0
  352. package/dist/tools/list-specs.test.js +110 -0
  353. package/dist/tools/list-specs.test.js.map +1 -0
  354. package/dist/tools/manage-context.test.d.ts +2 -0
  355. package/dist/tools/manage-context.test.d.ts.map +1 -0
  356. package/dist/tools/manage-context.test.js +359 -0
  357. package/dist/tools/manage-context.test.js.map +1 -0
  358. package/dist/tools/manage-git.test.d.ts +2 -0
  359. package/dist/tools/manage-git.test.d.ts.map +1 -0
  360. package/dist/tools/manage-git.test.js +882 -0
  361. package/dist/tools/manage-git.test.js.map +1 -0
  362. package/dist/tools/orchestrate.test.d.ts +2 -0
  363. package/dist/tools/orchestrate.test.d.ts.map +1 -0
  364. package/dist/tools/orchestrate.test.js +1117 -0
  365. package/dist/tools/orchestrate.test.js.map +1 -0
  366. package/dist/tools/reconcile-spec.test.d.ts +2 -0
  367. package/dist/tools/reconcile-spec.test.d.ts.map +1 -0
  368. package/dist/tools/reconcile-spec.test.js +259 -0
  369. package/dist/tools/reconcile-spec.test.js.map +1 -0
  370. package/dist/tools/red-team.d.ts +3 -0
  371. package/dist/tools/red-team.d.ts.map +1 -0
  372. package/dist/tools/red-team.js +302 -0
  373. package/dist/tools/red-team.js.map +1 -0
  374. package/dist/tools/register-lessons-tools.d.ts +3 -0
  375. package/dist/tools/register-lessons-tools.d.ts.map +1 -0
  376. package/dist/tools/register-lessons-tools.js +62 -0
  377. package/dist/tools/register-lessons-tools.js.map +1 -0
  378. package/dist/tools/register-platform-tools/design-stack-tools.d.ts.map +1 -1
  379. package/dist/tools/register-platform-tools/design-stack-tools.js +14 -0
  380. package/dist/tools/register-platform-tools/design-stack-tools.js.map +1 -1
  381. package/dist/tools/register-platform-tools.test.d.ts +2 -0
  382. package/dist/tools/register-platform-tools.test.d.ts.map +1 -0
  383. package/dist/tools/register-platform-tools.test.js +404 -0
  384. package/dist/tools/register-platform-tools.test.js.map +1 -0
  385. package/dist/tools/register-spec-tools.test.d.ts +2 -0
  386. package/dist/tools/register-spec-tools.test.d.ts.map +1 -0
  387. package/dist/tools/register-spec-tools.test.js +407 -0
  388. package/dist/tools/register-spec-tools.test.js.map +1 -0
  389. package/dist/tools/reverse-engineer.test.d.ts +2 -0
  390. package/dist/tools/reverse-engineer.test.d.ts.map +1 -0
  391. package/dist/tools/reverse-engineer.test.js +206 -0
  392. package/dist/tools/reverse-engineer.test.js.map +1 -0
  393. package/dist/tools/schemas.d.ts +20 -0
  394. package/dist/tools/schemas.d.ts.map +1 -0
  395. package/dist/tools/schemas.js +133 -0
  396. package/dist/tools/schemas.js.map +1 -0
  397. package/dist/tools/schemas.test.d.ts +2 -0
  398. package/dist/tools/schemas.test.d.ts.map +1 -0
  399. package/dist/tools/schemas.test.js +245 -0
  400. package/dist/tools/schemas.test.js.map +1 -0
  401. package/dist/tools/set-locale.test.d.ts +2 -0
  402. package/dist/tools/set-locale.test.d.ts.map +1 -0
  403. package/dist/tools/set-locale.test.js +74 -0
  404. package/dist/tools/set-locale.test.js.map +1 -0
  405. package/dist/tools/suggest-mcps.test.d.ts +2 -0
  406. package/dist/tools/suggest-mcps.test.d.ts.map +1 -0
  407. package/dist/tools/suggest-mcps.test.js +198 -0
  408. package/dist/tools/suggest-mcps.test.js.map +1 -0
  409. package/dist/tools/suggest-stack.test.d.ts +2 -0
  410. package/dist/tools/suggest-stack.test.d.ts.map +1 -0
  411. package/dist/tools/suggest-stack.test.js +181 -0
  412. package/dist/tools/suggest-stack.test.js.map +1 -0
  413. package/dist/tools/suggest-tooling.test.d.ts +2 -0
  414. package/dist/tools/suggest-tooling.test.d.ts.map +1 -0
  415. package/dist/tools/suggest-tooling.test.js +213 -0
  416. package/dist/tools/suggest-tooling.test.js.map +1 -0
  417. package/dist/tools/summarize-spec.test.d.ts +2 -0
  418. package/dist/tools/summarize-spec.test.d.ts.map +1 -0
  419. package/dist/tools/summarize-spec.test.js +180 -0
  420. package/dist/tools/summarize-spec.test.js.map +1 -0
  421. package/dist/tools/update-status/dod-gates.d.ts +16 -0
  422. package/dist/tools/update-status/dod-gates.d.ts.map +1 -0
  423. package/dist/tools/update-status/dod-gates.js +117 -0
  424. package/dist/tools/update-status/dod-gates.js.map +1 -0
  425. package/dist/tools/update-status/file-sync.d.ts +6 -0
  426. package/dist/tools/update-status/file-sync.d.ts.map +1 -0
  427. package/dist/tools/update-status/file-sync.js +112 -0
  428. package/dist/tools/update-status/file-sync.js.map +1 -0
  429. package/dist/tools/update-status/index.d.ts +3 -0
  430. package/dist/tools/update-status/index.d.ts.map +1 -0
  431. package/dist/tools/update-status/index.js +181 -0
  432. package/dist/tools/update-status/index.js.map +1 -0
  433. package/dist/tools/update-status/response-builder.d.ts +4 -0
  434. package/dist/tools/update-status/response-builder.d.ts.map +1 -0
  435. package/dist/tools/update-status/response-builder.js +69 -0
  436. package/dist/tools/update-status/response-builder.js.map +1 -0
  437. package/dist/tools/update-status/side-effects.d.ts +15 -0
  438. package/dist/tools/update-status/side-effects.d.ts.map +1 -0
  439. package/dist/tools/update-status/side-effects.js +64 -0
  440. package/dist/tools/update-status/side-effects.js.map +1 -0
  441. package/dist/tools/update-status/transition-guard.d.ts +20 -0
  442. package/dist/tools/update-status/transition-guard.d.ts.map +1 -0
  443. package/dist/tools/update-status/transition-guard.js +75 -0
  444. package/dist/tools/update-status/transition-guard.js.map +1 -0
  445. package/dist/tools/update-status.d.ts +1 -2
  446. package/dist/tools/update-status.d.ts.map +1 -1
  447. package/dist/tools/update-status.js +2 -461
  448. package/dist/tools/update-status.js.map +1 -1
  449. package/dist/tools/update-status.test.d.ts +2 -0
  450. package/dist/tools/update-status.test.d.ts.map +1 -0
  451. package/dist/tools/update-status.test.js +142 -0
  452. package/dist/tools/update-status.test.js.map +1 -0
  453. package/dist/tools/validate.d.ts.map +1 -1
  454. package/dist/tools/validate.js +18 -4
  455. package/dist/tools/validate.js.map +1 -1
  456. package/dist/tools/validate.test.d.ts +2 -0
  457. package/dist/tools/validate.test.d.ts.map +1 -0
  458. package/dist/tools/validate.test.js +137 -0
  459. package/dist/tools/validate.test.js.map +1 -0
  460. package/dist/types/analysis.d.ts +2 -1
  461. package/dist/types/analysis.d.ts.map +1 -1
  462. package/dist/types/conventions.d.ts +5 -0
  463. package/dist/types/conventions.d.ts.map +1 -1
  464. package/dist/types/index.d.ts +3 -0
  465. package/dist/types/index.d.ts.map +1 -1
  466. package/dist/types/index.js +3 -0
  467. package/dist/types/index.js.map +1 -1
  468. package/dist/types/lessons.d.ts +50 -0
  469. package/dist/types/lessons.d.ts.map +1 -0
  470. package/dist/types/lessons.js +3 -0
  471. package/dist/types/lessons.js.map +1 -0
  472. package/dist/types/project/planu-config.d.ts +2 -0
  473. package/dist/types/project/planu-config.d.ts.map +1 -1
  474. package/dist/types/red-team.d.ts +29 -0
  475. package/dist/types/red-team.d.ts.map +1 -0
  476. package/dist/types/red-team.js +3 -0
  477. package/dist/types/red-team.js.map +1 -0
  478. package/dist/types/update-notifier.d.ts +5 -0
  479. package/dist/types/update-notifier.d.ts.map +1 -0
  480. package/dist/types/update-notifier.js +3 -0
  481. package/dist/types/update-notifier.js.map +1 -0
  482. package/package.json +9 -2
  483. package/src/config/license-plans.json +5 -2
  484. package/src/i18n/messages/en.json +5 -0
  485. package/src/i18n/messages/es.json +5 -0
  486. package/src/i18n/messages/pt.json +5 -0
@@ -0,0 +1,222 @@
1
+ // Tests for handleGenerateTests
2
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
+ vi.mock('../i18n/index.js', () => ({
4
+ t: (key) => key,
5
+ ti: (key, _vars) => key,
6
+ }));
7
+ vi.mock('../storage/index.js', () => ({
8
+ knowledgeStore: { getKnowledge: vi.fn() },
9
+ specStore: { getSpec: vi.fn() },
10
+ }));
11
+ import { handleGenerateTests } from './generate-tests.js';
12
+ import { knowledgeStore, specStore } from '../storage/index.js';
13
+ const mockGetKnowledge = vi.mocked(knowledgeStore.getKnowledge);
14
+ const mockGetSpec = vi.mocked(specStore.getSpec);
15
+ const baseKnowledge = {
16
+ language: 'typescript',
17
+ framework: 'express',
18
+ projectPath: '/test',
19
+ stack: ['vitest'],
20
+ conventions: {},
21
+ architecture: { primary: 'monolith', secondary: [], layers: [] },
22
+ database: 'postgresql',
23
+ testCommand: 'npm test',
24
+ buildCommand: 'npm run build',
25
+ linting: { detectedLinters: [] },
26
+ apiContracts: [],
27
+ layers: [],
28
+ };
29
+ const baseSpec = {
30
+ id: 'SPEC-001',
31
+ slug: 'user-auth',
32
+ title: 'User Authentication',
33
+ type: 'feature',
34
+ scope: 'feature',
35
+ target: 'backend',
36
+ tags: ['auth'],
37
+ status: 'approved',
38
+ risk: 'medium',
39
+ difficulty: 3,
40
+ estimation: { devHours: 8, reviewHours: 2, totalCostUsd: 100 },
41
+ dependencies: [],
42
+ createdAt: '2025-01-01',
43
+ updatedAt: '2025-01-01',
44
+ };
45
+ beforeEach(() => {
46
+ vi.clearAllMocks();
47
+ });
48
+ describe('handleGenerateTests', () => {
49
+ it('should return error when project not found', async () => {
50
+ mockGetKnowledge.mockResolvedValue(null);
51
+ const result = await handleGenerateTests({
52
+ specId: 'SPEC-001',
53
+ projectId: 'missing',
54
+ });
55
+ expect(result.isError).toBe(true);
56
+ expect(result.content[0].text).toContain('errors.projectNotFound');
57
+ });
58
+ it('should return error when spec not found', async () => {
59
+ mockGetKnowledge.mockResolvedValue(baseKnowledge);
60
+ mockGetSpec.mockResolvedValue(null);
61
+ const result = await handleGenerateTests({
62
+ specId: 'SPEC-999',
63
+ projectId: 'proj-1',
64
+ });
65
+ expect(result.isError).toBe(true);
66
+ expect(result.content[0].text).toContain('errors.specNotFound');
67
+ });
68
+ it('should generate unit test for backend spec', async () => {
69
+ mockGetKnowledge.mockResolvedValue(baseKnowledge);
70
+ mockGetSpec.mockResolvedValue(baseSpec);
71
+ const result = await handleGenerateTests({
72
+ specId: 'SPEC-001',
73
+ projectId: 'proj-1',
74
+ });
75
+ expect(result.isError).toBeUndefined();
76
+ const text = result.content[0].text;
77
+ expect(text).toContain('Unit Tests');
78
+ expect(text).toContain('User Authentication');
79
+ expect(text).toContain('vitest');
80
+ expect(text).toContain('Coverage target');
81
+ expect(text).toContain('80%');
82
+ expect(text).toContain('Integration Tests'); // backend => integration
83
+ expect(text).not.toContain('E2E Tests'); // backend only => no e2e
84
+ expect(text).toContain('Manual Tests');
85
+ expect(text).toContain('Generated Test Files');
86
+ expect(text).toContain('Commands');
87
+ });
88
+ it('should generate e2e test for fullstack spec', async () => {
89
+ mockGetKnowledge.mockResolvedValue(baseKnowledge);
90
+ mockGetSpec.mockResolvedValue({ ...baseSpec, target: 'fullstack' });
91
+ const result = await handleGenerateTests({
92
+ specId: 'SPEC-001',
93
+ projectId: 'proj-1',
94
+ });
95
+ const text = result.content[0].text;
96
+ expect(text).toContain('E2E Tests');
97
+ expect(text).toContain('Integration Tests');
98
+ });
99
+ it('should generate e2e test for frontend spec without integration', async () => {
100
+ mockGetKnowledge.mockResolvedValue(baseKnowledge);
101
+ mockGetSpec.mockResolvedValue({ ...baseSpec, target: 'frontend' });
102
+ const result = await handleGenerateTests({
103
+ specId: 'SPEC-001',
104
+ projectId: 'proj-1',
105
+ });
106
+ const text = result.content[0].text;
107
+ expect(text).toContain('E2E Tests');
108
+ // frontend-only: no integration tests generated
109
+ });
110
+ it('should use pytest for python language', async () => {
111
+ mockGetKnowledge.mockResolvedValue({
112
+ ...baseKnowledge,
113
+ language: 'python',
114
+ stack: ['pytest'],
115
+ });
116
+ mockGetSpec.mockResolvedValue(baseSpec);
117
+ const result = await handleGenerateTests({
118
+ specId: 'SPEC-001',
119
+ projectId: 'proj-1',
120
+ });
121
+ const text = result.content[0].text;
122
+ expect(text).toContain('pytest');
123
+ expect(text).toContain('.py');
124
+ });
125
+ it('should use cypress when in stack', async () => {
126
+ mockGetKnowledge.mockResolvedValue({
127
+ ...baseKnowledge,
128
+ stack: ['vitest', 'cypress'],
129
+ });
130
+ mockGetSpec.mockResolvedValue({ ...baseSpec, target: 'fullstack' });
131
+ const result = await handleGenerateTests({
132
+ specId: 'SPEC-001',
133
+ projectId: 'proj-1',
134
+ });
135
+ const text = result.content[0].text;
136
+ expect(text).toContain('cy.');
137
+ });
138
+ it('should include existing test command in commands', async () => {
139
+ mockGetKnowledge.mockResolvedValue(baseKnowledge);
140
+ mockGetSpec.mockResolvedValue(baseSpec);
141
+ const result = await handleGenerateTests({
142
+ specId: 'SPEC-001',
143
+ projectId: 'proj-1',
144
+ });
145
+ const text = result.content[0].text;
146
+ expect(text).toContain('npm test');
147
+ });
148
+ it('should default to vitest for unknown language', async () => {
149
+ mockGetKnowledge.mockResolvedValue({
150
+ ...baseKnowledge,
151
+ language: 'unknown-lang',
152
+ stack: [],
153
+ });
154
+ mockGetSpec.mockResolvedValue(baseSpec);
155
+ const result = await handleGenerateTests({
156
+ specId: 'SPEC-001',
157
+ projectId: 'proj-1',
158
+ });
159
+ const text = result.content[0].text;
160
+ expect(text).toContain('vitest');
161
+ });
162
+ it('should omit existing test command when testCommand is null', async () => {
163
+ mockGetKnowledge.mockResolvedValue({
164
+ ...baseKnowledge,
165
+ testCommand: null,
166
+ });
167
+ mockGetSpec.mockResolvedValue(baseSpec);
168
+ const result = await handleGenerateTests({
169
+ specId: 'SPEC-001',
170
+ projectId: 'proj-1',
171
+ });
172
+ const text = result.content[0].text;
173
+ expect(text).not.toContain('# Run all tests');
174
+ expect(text).toContain('vitest'); // still shows framework commands
175
+ });
176
+ it('should omit framework commands for unknown framework', async () => {
177
+ mockGetKnowledge.mockResolvedValue({
178
+ ...baseKnowledge,
179
+ language: 'dart',
180
+ stack: [],
181
+ testCommand: null,
182
+ });
183
+ mockGetSpec.mockResolvedValue(baseSpec);
184
+ const result = await handleGenerateTests({
185
+ specId: 'SPEC-001',
186
+ projectId: 'proj-1',
187
+ });
188
+ const text = result.content[0].text;
189
+ // dart defaults to 'flutter-test' which has no entry in frameworkCmds
190
+ expect(text).not.toContain('Commands');
191
+ });
192
+ it('should use jest when jest is in stack', async () => {
193
+ mockGetKnowledge.mockResolvedValue({
194
+ ...baseKnowledge,
195
+ stack: ['jest'],
196
+ });
197
+ mockGetSpec.mockResolvedValue(baseSpec);
198
+ const result = await handleGenerateTests({
199
+ specId: 'SPEC-001',
200
+ projectId: 'proj-1',
201
+ });
202
+ const text = result.content[0].text;
203
+ expect(text).toContain('jest');
204
+ // jest commands should be present
205
+ expect(text).toContain('npx jest');
206
+ });
207
+ it('should use pytest when pytest is in stack (non-python language)', async () => {
208
+ mockGetKnowledge.mockResolvedValue({
209
+ ...baseKnowledge,
210
+ language: 'typescript',
211
+ stack: ['pytest'],
212
+ });
213
+ mockGetSpec.mockResolvedValue(baseSpec);
214
+ const result = await handleGenerateTests({
215
+ specId: 'SPEC-001',
216
+ projectId: 'proj-1',
217
+ });
218
+ const text = result.content[0].text;
219
+ expect(text).toContain('pytest');
220
+ });
221
+ });
222
+ //# sourceMappingURL=generate-tests.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-tests.test.js","sourceRoot":"","sources":["../../src/tools/generate-tests.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=init-constitution.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-constitution.test.d.ts","sourceRoot":"","sources":["../../src/tools/init-constitution.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,398 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ vi.mock('../i18n/index.js', () => ({
3
+ ti: vi.fn((_key, params) => `translated:${JSON.stringify(params)}`),
4
+ }));
5
+ vi.mock('../storage/index.js', () => ({
6
+ knowledgeStore: {
7
+ getKnowledge: vi.fn(),
8
+ getConstitution: vi.fn(),
9
+ saveConstitution: vi.fn(),
10
+ },
11
+ }));
12
+ vi.mock('node:fs/promises', () => ({
13
+ readFile: vi.fn(),
14
+ }));
15
+ import { handleInitConstitution } from './init-constitution.js';
16
+ import { knowledgeStore } from '../storage/index.js';
17
+ import { readFile } from 'node:fs/promises';
18
+ const makeKnowledge = (overrides = {}) => ({
19
+ projectPath: '/test/project',
20
+ language: 'TypeScript',
21
+ framework: 'Express',
22
+ packageManager: 'npm',
23
+ database: 'postgresql',
24
+ architecture: {
25
+ primary: 'layered',
26
+ secondary: [],
27
+ layers: [
28
+ { name: 'domain', neverDependsOn: ['infrastructure'], responsibility: 'Business logic' },
29
+ ],
30
+ boundaries: [],
31
+ communicationPatterns: [],
32
+ deploymentUnits: [],
33
+ },
34
+ linting: {
35
+ maturityScore: 80,
36
+ detectedLinters: [{ tool: 'eslint', status: 'configured' }],
37
+ rulesConflicts: [],
38
+ },
39
+ ...overrides,
40
+ });
41
+ beforeEach(() => {
42
+ vi.clearAllMocks();
43
+ vi.mocked(readFile).mockRejectedValue(new Error('not found'));
44
+ });
45
+ describe('handleInitConstitution', () => {
46
+ it('should return error when project not found', async () => {
47
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(null);
48
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
49
+ expect(result.isError).toBe(true);
50
+ expect(result.content).toHaveLength(1);
51
+ });
52
+ it('should create constitution with auto-detected principles', async () => {
53
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
54
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
55
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
56
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
57
+ expect(result.isError).toBeUndefined();
58
+ const parsed = JSON.parse(result.content[0].text);
59
+ expect(parsed.projectId).toBe('proj-123');
60
+ expect(parsed.version).toBe(1);
61
+ expect(parsed.isUpdate).toBe(false);
62
+ expect(parsed.principlesCount).toBeGreaterThan(0);
63
+ expect(parsed.bySource['auto-detected']).toBeGreaterThan(0);
64
+ expect(knowledgeStore.saveConstitution).toHaveBeenCalled();
65
+ });
66
+ it('should increment version on existing constitution', async () => {
67
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
68
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue({
69
+ projectId: 'proj-123',
70
+ principles: [
71
+ {
72
+ id: 'auto-1',
73
+ category: 'security',
74
+ principle: 'Immutable principle',
75
+ rationale: 'test',
76
+ enforceLevel: 'strict',
77
+ autoEnforceable: true,
78
+ source: 'auto-detected',
79
+ immutable: true,
80
+ },
81
+ ],
82
+ createdAt: '2024-01-01',
83
+ updatedAt: '2024-01-01',
84
+ version: 2,
85
+ });
86
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
87
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
88
+ const parsed = JSON.parse(result.content[0].text);
89
+ expect(parsed.version).toBe(3);
90
+ expect(parsed.isUpdate).toBe(true);
91
+ });
92
+ it('should add manual principles', async () => {
93
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
94
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
95
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
96
+ const manualPrinciple = {
97
+ id: 'custom-1',
98
+ category: 'workflow',
99
+ principle: 'Always write tests first',
100
+ rationale: 'TDD practice',
101
+ enforceLevel: 'strict',
102
+ autoEnforceable: false,
103
+ source: 'user-defined',
104
+ immutable: false,
105
+ };
106
+ const result = await handleInitConstitution({
107
+ projectId: 'proj-123',
108
+ principles: [manualPrinciple],
109
+ });
110
+ const parsed = JSON.parse(result.content[0].text);
111
+ expect(parsed.principles.some((p) => p.id === 'custom-1')).toBe(true);
112
+ });
113
+ it('should skip auto-detect when disabled', async () => {
114
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
115
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
116
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
117
+ const result = await handleInitConstitution({
118
+ projectId: 'proj-123',
119
+ autoDetect: false,
120
+ principles: [
121
+ {
122
+ id: 'manual-1',
123
+ category: 'workflow',
124
+ principle: 'Manual only',
125
+ rationale: 'test',
126
+ enforceLevel: 'recommended',
127
+ autoEnforceable: false,
128
+ source: 'user-defined',
129
+ immutable: false,
130
+ },
131
+ ],
132
+ });
133
+ const parsed = JSON.parse(result.content[0].text);
134
+ expect(parsed.bySource['auto-detected']).toBe(0);
135
+ expect(parsed.principlesCount).toBe(1);
136
+ });
137
+ it('should extract principles from CLAUDE.md', async () => {
138
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
139
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
140
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
141
+ vi.mocked(readFile).mockImplementation(((path) => {
142
+ if (path.includes('CLAUDE.md')) {
143
+ return Promise.resolve('# Rules\n- Always use TypeScript strict mode for all projects\n- Run security checks before deployment\n');
144
+ }
145
+ return Promise.reject(new Error('not found'));
146
+ }));
147
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
148
+ const parsed = JSON.parse(result.content[0].text);
149
+ expect(parsed.bySource['claude-md']).toBeGreaterThan(0);
150
+ });
151
+ it('should handle errors gracefully', async () => {
152
+ vi.mocked(knowledgeStore.getKnowledge).mockRejectedValue(new Error('DB error'));
153
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
154
+ expect(result.isError).toBe(true);
155
+ });
156
+ it('should handle knowledge without database', async () => {
157
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge({ database: 'unknown', packageManager: null, framework: null }));
158
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
159
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
160
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
161
+ expect(result.isError).toBeUndefined();
162
+ const parsed = JSON.parse(result.content[0].text);
163
+ expect(parsed.principlesCount).toBeGreaterThan(0);
164
+ });
165
+ // --- Coverage for linting principles with no configured linters (line 117) ---
166
+ it('should not add linting principle when no linters are configured', async () => {
167
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge({
168
+ linting: {
169
+ maturityScore: 0,
170
+ detectedLinters: [{ tool: 'eslint', status: 'not-configured' }],
171
+ rulesConflicts: [],
172
+ },
173
+ }));
174
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
175
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
176
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
177
+ const parsed = JSON.parse(result.content[0].text);
178
+ const lintPrinciple = parsed.principles.find((p) => p.principle.includes('linting'));
179
+ expect(lintPrinciple).toBeUndefined();
180
+ });
181
+ // --- Coverage for classifyPrinciple: tech-stack category (line 225) ---
182
+ it('should classify stack/framework/language/database principles as tech-stack', async () => {
183
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
184
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
185
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
186
+ vi.mocked(readFile).mockImplementation(((path) => {
187
+ if (path.includes('CLAUDE.md')) {
188
+ return Promise.resolve('# Rules\n- Use the approved tech stack for all features\n- The database must be PostgreSQL\n');
189
+ }
190
+ return Promise.reject(new Error('not found'));
191
+ }));
192
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
193
+ const parsed = JSON.parse(result.content[0].text);
194
+ const techStackPrinciples = parsed.principles.filter((p) => p.category === 'tech-stack' && p.source === 'claude-md');
195
+ expect(techStackPrinciples.length).toBeGreaterThan(0);
196
+ });
197
+ // --- Coverage for classifyPrinciple: conventions category ---
198
+ it('should classify naming convention principles as conventions', async () => {
199
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
200
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
201
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
202
+ vi.mocked(readFile).mockImplementation(((path) => {
203
+ if (path.includes('CLAUDE.md')) {
204
+ return Promise.resolve('# Rules\n- Use camelCase naming convention for all variables\n');
205
+ }
206
+ return Promise.reject(new Error('not found'));
207
+ }));
208
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
209
+ const parsed = JSON.parse(result.content[0].text);
210
+ const conventionPrinciples = parsed.principles.filter((p) => p.category === 'conventions' && p.source === 'claude-md');
211
+ expect(conventionPrinciples.length).toBeGreaterThan(0);
212
+ });
213
+ // --- Coverage for classifyPrinciple: workflow category (default, line 227) ---
214
+ it('should classify unrecognized principles as workflow', async () => {
215
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
216
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
217
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
218
+ vi.mocked(readFile).mockImplementation(((path) => {
219
+ if (path.includes('CLAUDE.md')) {
220
+ return Promise.resolve('# Rules\n- Always review pull requests before merging them\n');
221
+ }
222
+ return Promise.reject(new Error('not found'));
223
+ }));
224
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
225
+ const parsed = JSON.parse(result.content[0].text);
226
+ const workflowPrinciples = parsed.principles.filter((p) => p.category === 'workflow' && p.source === 'claude-md');
227
+ expect(workflowPrinciples.length).toBeGreaterThan(0);
228
+ });
229
+ // --- Coverage for manual principle overriding auto-detected (line 263) ---
230
+ it('should override auto-detected principle with same ID as manual principle', async () => {
231
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
232
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
233
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
234
+ const result = await handleInitConstitution({
235
+ projectId: 'proj-123',
236
+ principles: [
237
+ {
238
+ id: 'auto-1', // same ID as first auto-detected principle
239
+ category: 'architecture',
240
+ principle: 'Custom architecture rule',
241
+ rationale: 'Override',
242
+ enforceLevel: 'recommended',
243
+ autoEnforceable: false,
244
+ source: 'user-defined',
245
+ immutable: false,
246
+ },
247
+ ],
248
+ });
249
+ const parsed = JSON.parse(result.content[0].text);
250
+ const overriddenPrinciple = parsed.principles.find((p) => p.id === 'auto-1');
251
+ expect(overriddenPrinciple.principle).toBe('Custom architecture rule');
252
+ expect(overriddenPrinciple.source).toBe('user-defined');
253
+ });
254
+ // --- Coverage for immutable principle preservation: existing immutable not in new (line 279) ---
255
+ it('should preserve immutable principles from existing constitution even when not auto-detected', async () => {
256
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
257
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue({
258
+ projectId: 'proj-123',
259
+ principles: [
260
+ {
261
+ id: 'custom-immutable',
262
+ category: 'security',
263
+ principle: 'Never bypass auth checks',
264
+ rationale: 'Critical security',
265
+ enforceLevel: 'strict',
266
+ autoEnforceable: false,
267
+ source: 'user-defined',
268
+ immutable: true,
269
+ },
270
+ ],
271
+ createdAt: '2024-01-01',
272
+ updatedAt: '2024-01-01',
273
+ version: 1,
274
+ });
275
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
276
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
277
+ const parsed = JSON.parse(result.content[0].text);
278
+ const immutablePrinciple = parsed.principles.find((p) => p.id === 'custom-immutable');
279
+ // Should be added back even though it was not in the auto-detected set
280
+ expect(immutablePrinciple).toBeDefined();
281
+ expect(immutablePrinciple.principle).toBe('Never bypass auth checks');
282
+ });
283
+ // --- Coverage for layers without neverDependsOn ---
284
+ it('should not add layer dependency principle when neverDependsOn is empty', async () => {
285
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge({
286
+ architecture: {
287
+ primary: 'layered',
288
+ secondary: [],
289
+ layers: [
290
+ { name: 'domain', neverDependsOn: [], responsibility: 'Business logic' },
291
+ ],
292
+ },
293
+ }));
294
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
295
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
296
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
297
+ const parsed = JSON.parse(result.content[0].text);
298
+ const layerPrinciples = parsed.principles.filter((p) => p.principle.includes('must never depend on'));
299
+ expect(layerPrinciples).toHaveLength(0);
300
+ });
301
+ // --- Coverage for extractPrinciplesFromClaudeMd: .cursorrules file ---
302
+ it('should extract principles from .cursorrules file', async () => {
303
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
304
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
305
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
306
+ vi.mocked(readFile).mockImplementation(((path) => {
307
+ if (path.includes('.cursorrules')) {
308
+ return Promise.resolve('# Cursor Rules\n- Always test before committing code changes\n');
309
+ }
310
+ return Promise.reject(new Error('not found'));
311
+ }));
312
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
313
+ const parsed = JSON.parse(result.content[0].text);
314
+ expect(parsed.bySource['claude-md']).toBeGreaterThan(0);
315
+ });
316
+ // --- Coverage for classifyPrinciple: security ---
317
+ it('should classify security-related principles from CLAUDE.md', async () => {
318
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
319
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
320
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
321
+ vi.mocked(readFile).mockImplementation(((path) => {
322
+ if (path.includes('CLAUDE.md')) {
323
+ return Promise.resolve('# Security\n- Always encrypt sensitive user data at rest\n');
324
+ }
325
+ return Promise.reject(new Error('not found'));
326
+ }));
327
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
328
+ const parsed = JSON.parse(result.content[0].text);
329
+ const securityPrinciples = parsed.principles.filter((p) => p.category === 'security' && p.source === 'claude-md');
330
+ expect(securityPrinciples.length).toBeGreaterThan(0);
331
+ });
332
+ // --- Coverage for classifyPrinciple: architecture ---
333
+ it('should classify architecture-related principles from CLAUDE.md', async () => {
334
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
335
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
336
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
337
+ vi.mocked(readFile).mockImplementation(((path) => {
338
+ if (path.includes('CLAUDE.md')) {
339
+ return Promise.resolve('# Arch\n- Follow the layered architecture pattern strictly\n');
340
+ }
341
+ return Promise.reject(new Error('not found'));
342
+ }));
343
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
344
+ const parsed = JSON.parse(result.content[0].text);
345
+ const archPrinciples = parsed.principles.filter((p) => p.category === 'architecture' && p.source === 'claude-md');
346
+ expect(archPrinciples.length).toBeGreaterThan(0);
347
+ });
348
+ // --- Coverage for classifyPrinciple: quality ---
349
+ it('should classify quality/test-related principles from CLAUDE.md', async () => {
350
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge());
351
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
352
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
353
+ vi.mocked(readFile).mockImplementation(((path) => {
354
+ if (path.includes('CLAUDE.md')) {
355
+ return Promise.resolve('# Quality\n- All code must have comprehensive test coverage\n');
356
+ }
357
+ return Promise.reject(new Error('not found'));
358
+ }));
359
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
360
+ const parsed = JSON.parse(result.content[0].text);
361
+ const qualityPrinciples = parsed.principles.filter((p) => p.category === 'quality' && p.source === 'claude-md');
362
+ expect(qualityPrinciples.length).toBeGreaterThan(0);
363
+ });
364
+ // --- Coverage for non-Error thrown in catch block ---
365
+ it('should handle non-Error thrown values in catch block', async () => {
366
+ vi.mocked(knowledgeStore.getKnowledge).mockRejectedValue('string error');
367
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
368
+ expect(result.isError).toBe(true);
369
+ expect(result.content[0].text).toContain('string error');
370
+ });
371
+ // --- Coverage for empty layers array ---
372
+ it('should handle empty layers array in architecture', async () => {
373
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge({
374
+ architecture: {
375
+ primary: 'monolith',
376
+ secondary: [],
377
+ layers: [],
378
+ },
379
+ }));
380
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
381
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
382
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
383
+ expect(result.isError).toBeUndefined();
384
+ const parsed = JSON.parse(result.content[0].text);
385
+ expect(parsed.principlesCount).toBeGreaterThan(0);
386
+ });
387
+ // --- Coverage for no language set ---
388
+ it('should skip tech-stack language principle when language is empty', async () => {
389
+ vi.mocked(knowledgeStore.getKnowledge).mockResolvedValue(makeKnowledge({ language: '' }));
390
+ vi.mocked(knowledgeStore.getConstitution).mockResolvedValue(null);
391
+ vi.mocked(knowledgeStore.saveConstitution).mockResolvedValue(undefined);
392
+ const result = await handleInitConstitution({ projectId: 'proj-123' });
393
+ const parsed = JSON.parse(result.content[0].text);
394
+ const langPrinciple = parsed.principles.find((p) => p.source === 'auto-detected' && p.principle.startsWith('Use ') && p.principle.includes('for all new code'));
395
+ expect(langPrinciple).toBeUndefined();
396
+ });
397
+ });
398
+ //# sourceMappingURL=init-constitution.test.js.map