@paths.design/caws-cli 10.2.0 → 11.0.0

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 (421) hide show
  1. package/README.md +125 -374
  2. package/dist/index.js +43 -785
  3. package/dist/shell/binding/resolve-binding.d.ts +4 -0
  4. package/dist/shell/binding/resolve-binding.d.ts.map +1 -0
  5. package/dist/shell/binding/resolve-binding.js +228 -0
  6. package/dist/shell/binding/resolve-binding.js.map +1 -0
  7. package/dist/shell/binding/types.d.ts +42 -0
  8. package/dist/shell/binding/types.d.ts.map +1 -0
  9. package/dist/shell/binding/types.js +21 -0
  10. package/dist/shell/binding/types.js.map +1 -0
  11. package/dist/shell/commands/claim.d.ts +14 -0
  12. package/dist/shell/commands/claim.d.ts.map +1 -0
  13. package/dist/shell/commands/claim.js +197 -0
  14. package/dist/shell/commands/claim.js.map +1 -0
  15. package/dist/shell/commands/doctor.d.ts +13 -0
  16. package/dist/shell/commands/doctor.d.ts.map +1 -0
  17. package/dist/shell/commands/doctor.js +97 -0
  18. package/dist/shell/commands/doctor.js.map +1 -0
  19. package/dist/shell/commands/evidence.d.ts +28 -0
  20. package/dist/shell/commands/evidence.d.ts.map +1 -0
  21. package/dist/shell/commands/evidence.js +166 -0
  22. package/dist/shell/commands/evidence.js.map +1 -0
  23. package/dist/shell/commands/gates.d.ts +19 -0
  24. package/dist/shell/commands/gates.d.ts.map +1 -0
  25. package/dist/shell/commands/gates.js +181 -0
  26. package/dist/shell/commands/gates.js.map +1 -0
  27. package/dist/shell/commands/init.d.ts +8 -0
  28. package/dist/shell/commands/init.d.ts.map +1 -0
  29. package/dist/shell/commands/init.js +64 -0
  30. package/dist/shell/commands/init.js.map +1 -0
  31. package/dist/shell/commands/scope.d.ts +11 -0
  32. package/dist/shell/commands/scope.d.ts.map +1 -0
  33. package/dist/shell/commands/scope.js +92 -0
  34. package/dist/shell/commands/scope.js.map +1 -0
  35. package/dist/shell/commands/status.d.ts +15 -0
  36. package/dist/shell/commands/status.d.ts.map +1 -0
  37. package/dist/shell/commands/status.js +106 -0
  38. package/dist/shell/commands/status.js.map +1 -0
  39. package/dist/shell/commands/waiver.d.ts +38 -0
  40. package/dist/shell/commands/waiver.d.ts.map +1 -0
  41. package/dist/shell/commands/waiver.js +240 -0
  42. package/dist/shell/commands/waiver.js.map +1 -0
  43. package/dist/shell/gates/disposition.d.ts +23 -0
  44. package/dist/shell/gates/disposition.d.ts.map +1 -0
  45. package/dist/shell/gates/disposition.js +87 -0
  46. package/dist/shell/gates/disposition.js.map +1 -0
  47. package/dist/shell/gates/gate-result-contract.d.ts +39 -0
  48. package/dist/shell/gates/gate-result-contract.d.ts.map +1 -0
  49. package/dist/shell/gates/gate-result-contract.js +150 -0
  50. package/dist/shell/gates/gate-result-contract.js.map +1 -0
  51. package/dist/shell/gates/quality-gates-adapter.d.ts +55 -0
  52. package/dist/shell/gates/quality-gates-adapter.d.ts.map +1 -0
  53. package/dist/shell/gates/quality-gates-adapter.js +161 -0
  54. package/dist/shell/gates/quality-gates-adapter.js.map +1 -0
  55. package/dist/shell/gates/waiver-filter.d.ts +58 -0
  56. package/dist/shell/gates/waiver-filter.d.ts.map +1 -0
  57. package/dist/shell/gates/waiver-filter.js +119 -0
  58. package/dist/shell/gates/waiver-filter.js.map +1 -0
  59. package/dist/shell/index.d.ts +50 -0
  60. package/dist/shell/index.d.ts.map +1 -0
  61. package/dist/shell/index.js +73 -0
  62. package/dist/shell/index.js.map +1 -0
  63. package/dist/shell/register.d.ts +11 -0
  64. package/dist/shell/register.d.ts.map +1 -0
  65. package/dist/shell/register.js +274 -0
  66. package/dist/shell/register.js.map +1 -0
  67. package/dist/shell/render/claim.d.ts +22 -0
  68. package/dist/shell/render/claim.d.ts.map +1 -0
  69. package/dist/shell/render/claim.js +75 -0
  70. package/dist/shell/render/claim.js.map +1 -0
  71. package/dist/shell/render/decision.d.ts +15 -0
  72. package/dist/shell/render/decision.d.ts.map +1 -0
  73. package/dist/shell/render/decision.js +66 -0
  74. package/dist/shell/render/decision.js.map +1 -0
  75. package/dist/shell/render/diagnostic.d.ts +19 -0
  76. package/dist/shell/render/diagnostic.d.ts.map +1 -0
  77. package/dist/shell/render/diagnostic.js +76 -0
  78. package/dist/shell/render/diagnostic.js.map +1 -0
  79. package/dist/shell/render/finding.d.ts +15 -0
  80. package/dist/shell/render/finding.d.ts.map +1 -0
  81. package/dist/shell/render/finding.js +57 -0
  82. package/dist/shell/render/finding.js.map +1 -0
  83. package/dist/shell/render/gates.d.ts +3 -0
  84. package/dist/shell/render/gates.d.ts.map +1 -0
  85. package/dist/shell/render/gates.js +56 -0
  86. package/dist/shell/render/gates.js.map +1 -0
  87. package/dist/shell/render/init.d.ts +11 -0
  88. package/dist/shell/render/init.d.ts.map +1 -0
  89. package/dist/shell/render/init.js +32 -0
  90. package/dist/shell/render/init.js.map +1 -0
  91. package/dist/shell/render/status.d.ts +26 -0
  92. package/dist/shell/render/status.d.ts.map +1 -0
  93. package/dist/shell/render/status.js +143 -0
  94. package/dist/shell/render/status.js.map +1 -0
  95. package/dist/shell/render/waiver.d.ts +21 -0
  96. package/dist/shell/render/waiver.d.ts.map +1 -0
  97. package/dist/shell/render/waiver.js +94 -0
  98. package/dist/shell/render/waiver.js.map +1 -0
  99. package/dist/shell/rules.d.ts +37 -0
  100. package/dist/shell/rules.d.ts.map +1 -0
  101. package/dist/shell/rules.js +51 -0
  102. package/dist/shell/rules.js.map +1 -0
  103. package/dist/shell/session/actor.d.ts +14 -0
  104. package/dist/shell/session/actor.d.ts.map +1 -0
  105. package/dist/shell/session/actor.js +34 -0
  106. package/dist/shell/session/actor.js.map +1 -0
  107. package/dist/shell/session/resolve-session.d.ts +5 -0
  108. package/dist/shell/session/resolve-session.d.ts.map +1 -0
  109. package/dist/shell/session/resolve-session.js +239 -0
  110. package/dist/shell/session/resolve-session.js.map +1 -0
  111. package/dist/shell/session/types.d.ts +56 -0
  112. package/dist/shell/session/types.d.ts.map +1 -0
  113. package/dist/shell/session/types.js +15 -0
  114. package/dist/shell/session/types.js.map +1 -0
  115. package/dist/store/agents-store.d.ts +3 -0
  116. package/dist/store/agents-store.d.ts.map +1 -0
  117. package/dist/store/agents-store.js +63 -0
  118. package/dist/store/agents-store.js.map +1 -0
  119. package/dist/store/apply-patch.d.ts +16 -0
  120. package/dist/store/apply-patch.d.ts.map +1 -0
  121. package/dist/store/apply-patch.js +191 -0
  122. package/dist/store/apply-patch.js.map +1 -0
  123. package/dist/store/atomic-write.d.ts +16 -0
  124. package/dist/store/atomic-write.d.ts.map +1 -0
  125. package/dist/store/atomic-write.js +132 -0
  126. package/dist/store/atomic-write.js.map +1 -0
  127. package/dist/store/doctor-snapshot.d.ts +20 -0
  128. package/dist/store/doctor-snapshot.d.ts.map +1 -0
  129. package/dist/store/doctor-snapshot.js +176 -0
  130. package/dist/store/doctor-snapshot.js.map +1 -0
  131. package/dist/store/events-store.d.ts +33 -0
  132. package/dist/store/events-store.d.ts.map +1 -0
  133. package/dist/store/events-store.js +297 -0
  134. package/dist/store/events-store.js.map +1 -0
  135. package/dist/store/index.d.ts +21 -0
  136. package/dist/store/index.d.ts.map +1 -0
  137. package/dist/store/index.js +47 -0
  138. package/dist/store/index.js.map +1 -0
  139. package/dist/store/init-store.d.ts +21 -0
  140. package/dist/store/init-store.d.ts.map +1 -0
  141. package/dist/store/init-store.js +295 -0
  142. package/dist/store/init-store.js.map +1 -0
  143. package/dist/store/json-store.d.ts +3 -0
  144. package/dist/store/json-store.d.ts.map +1 -0
  145. package/dist/store/json-store.js +65 -0
  146. package/dist/store/json-store.js.map +1 -0
  147. package/dist/store/policy-store.d.ts +3 -0
  148. package/dist/store/policy-store.d.ts.map +1 -0
  149. package/dist/store/policy-store.js +65 -0
  150. package/dist/store/policy-store.js.map +1 -0
  151. package/dist/store/repo-root.d.ts +46 -0
  152. package/dist/store/repo-root.d.ts.map +1 -0
  153. package/dist/store/repo-root.js +145 -0
  154. package/dist/store/repo-root.js.map +1 -0
  155. package/dist/store/rules.d.ts +53 -0
  156. package/dist/store/rules.d.ts.map +1 -0
  157. package/dist/store/rules.js +78 -0
  158. package/dist/store/rules.js.map +1 -0
  159. package/dist/store/specs-store.d.ts +3 -0
  160. package/dist/store/specs-store.d.ts.map +1 -0
  161. package/dist/store/specs-store.js +131 -0
  162. package/dist/store/specs-store.js.map +1 -0
  163. package/dist/store/types.d.ts +84 -0
  164. package/dist/store/types.d.ts.map +1 -0
  165. package/dist/store/types.js +14 -0
  166. package/dist/store/types.js.map +1 -0
  167. package/dist/store/waivers-store.d.ts +25 -0
  168. package/dist/store/waivers-store.d.ts.map +1 -0
  169. package/dist/store/waivers-store.js +232 -0
  170. package/dist/store/waivers-store.js.map +1 -0
  171. package/dist/store/worktrees-store.d.ts +3 -0
  172. package/dist/store/worktrees-store.d.ts.map +1 -0
  173. package/dist/store/worktrees-store.js +62 -0
  174. package/dist/store/worktrees-store.js.map +1 -0
  175. package/dist/store/yaml-store.d.ts +9 -0
  176. package/dist/store/yaml-store.d.ts.map +1 -0
  177. package/dist/store/yaml-store.js +121 -0
  178. package/dist/store/yaml-store.js.map +1 -0
  179. package/package.json +15 -13
  180. package/dist/budget-derivation.js +0 -751
  181. package/dist/cicd-optimizer.js +0 -504
  182. package/dist/commands/agents.js +0 -124
  183. package/dist/commands/archive.js +0 -500
  184. package/dist/commands/burnup.js +0 -198
  185. package/dist/commands/diagnose.js +0 -525
  186. package/dist/commands/evaluate.js +0 -314
  187. package/dist/commands/gates.js +0 -149
  188. package/dist/commands/init.js +0 -857
  189. package/dist/commands/iterate.js +0 -417
  190. package/dist/commands/mode.js +0 -269
  191. package/dist/commands/parallel.js +0 -242
  192. package/dist/commands/plan.js +0 -438
  193. package/dist/commands/provenance.js +0 -1143
  194. package/dist/commands/quality-monitor.js +0 -284
  195. package/dist/commands/scope.js +0 -264
  196. package/dist/commands/session.js +0 -312
  197. package/dist/commands/sidecar.js +0 -74
  198. package/dist/commands/specs.js +0 -1656
  199. package/dist/commands/status.js +0 -1172
  200. package/dist/commands/templates.js +0 -237
  201. package/dist/commands/tool.js +0 -136
  202. package/dist/commands/tutorial.js +0 -480
  203. package/dist/commands/validate.js +0 -357
  204. package/dist/commands/verify-acs.js +0 -443
  205. package/dist/commands/waivers.js +0 -599
  206. package/dist/commands/workflow.js +0 -243
  207. package/dist/commands/worktree.js +0 -502
  208. package/dist/config/lite-scope.js +0 -158
  209. package/dist/config/modes.js +0 -347
  210. package/dist/constants/spec-types.js +0 -65
  211. package/dist/gates/budget-limit.js +0 -121
  212. package/dist/gates/feedback.js +0 -260
  213. package/dist/gates/format.js +0 -179
  214. package/dist/gates/god-object.js +0 -117
  215. package/dist/gates/pipeline.js +0 -167
  216. package/dist/gates/scope-boundary.js +0 -112
  217. package/dist/gates/spec-completeness.js +0 -109
  218. package/dist/gates/todo-detection.js +0 -205
  219. package/dist/generators/jest-config-generator.js +0 -242
  220. package/dist/generators/working-spec.js +0 -237
  221. package/dist/minimal-cli.js +0 -88
  222. package/dist/parallel/parallel-manager.js +0 -433
  223. package/dist/policy/PolicyManager.js +0 -470
  224. package/dist/scaffold/claude-hooks.js +0 -443
  225. package/dist/scaffold/cursor-hooks.js +0 -177
  226. package/dist/scaffold/git-hooks.js +0 -928
  227. package/dist/scaffold/index.js +0 -794
  228. package/dist/session/session-manager.js +0 -653
  229. package/dist/sidecars/index.js +0 -33
  230. package/dist/sidecars/listeners.js +0 -40
  231. package/dist/sidecars/provenance-summary.js +0 -238
  232. package/dist/sidecars/quality-gaps.js +0 -258
  233. package/dist/sidecars/schema.js +0 -149
  234. package/dist/sidecars/spec-drift.js +0 -151
  235. package/dist/sidecars/waiver-draft.js +0 -176
  236. package/dist/spec/SpecFileManager.js +0 -419
  237. package/dist/templates/.caws/schemas/policy.schema.json +0 -117
  238. package/dist/templates/.caws/schemas/scope.schema.json +0 -52
  239. package/dist/templates/.caws/schemas/waivers.schema.json +0 -106
  240. package/dist/templates/.caws/schemas/working-spec.schema.json +0 -340
  241. package/dist/templates/.caws/schemas/worktrees.schema.json +0 -38
  242. package/dist/templates/.caws/templates/working-spec.template.yml +0 -80
  243. package/dist/templates/.caws/tools/README.md +0 -18
  244. package/dist/templates/.caws/tools/scope-guard.js +0 -203
  245. package/dist/templates/.caws/tools-allow.json +0 -331
  246. package/dist/templates/.caws/waivers.yml +0 -19
  247. package/dist/templates/.claude/README.md +0 -190
  248. package/dist/templates/.claude/hooks/audit.sh +0 -121
  249. package/dist/templates/.claude/hooks/block-dangerous.sh +0 -203
  250. package/dist/templates/.claude/hooks/classify_command.py +0 -592
  251. package/dist/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  252. package/dist/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  253. package/dist/templates/.claude/hooks/naming-check.sh +0 -100
  254. package/dist/templates/.claude/hooks/protected-paths.sh +0 -39
  255. package/dist/templates/.claude/hooks/quality-check.sh +0 -81
  256. package/dist/templates/.claude/hooks/scan-secrets.sh +0 -85
  257. package/dist/templates/.claude/hooks/scope-guard.sh +0 -381
  258. package/dist/templates/.claude/hooks/session-caws-status.sh +0 -117
  259. package/dist/templates/.claude/hooks/session-log.sh +0 -634
  260. package/dist/templates/.claude/hooks/simplification-guard.sh +0 -92
  261. package/dist/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  262. package/dist/templates/.claude/hooks/test_classify_command.py +0 -370
  263. package/dist/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  264. package/dist/templates/.claude/hooks/validate-spec.sh +0 -76
  265. package/dist/templates/.claude/hooks/worktree-guard.sh +0 -220
  266. package/dist/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  267. package/dist/templates/.claude/rules/git-safety.md +0 -26
  268. package/dist/templates/.claude/rules/worktree-isolation.md +0 -101
  269. package/dist/templates/.claude/settings.json +0 -141
  270. package/dist/templates/.cursor/README.md +0 -299
  271. package/dist/templates/.cursor/hooks/audit.sh +0 -55
  272. package/dist/templates/.cursor/hooks/block-dangerous.sh +0 -84
  273. package/dist/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  274. package/dist/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  275. package/dist/templates/.cursor/hooks/format.sh +0 -38
  276. package/dist/templates/.cursor/hooks/naming-check.sh +0 -64
  277. package/dist/templates/.cursor/hooks/scan-secrets.sh +0 -51
  278. package/dist/templates/.cursor/hooks/scope-guard.sh +0 -52
  279. package/dist/templates/.cursor/hooks/session-log.sh +0 -924
  280. package/dist/templates/.cursor/hooks/validate-spec.sh +0 -83
  281. package/dist/templates/.cursor/hooks.json +0 -76
  282. package/dist/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  283. package/dist/templates/.cursor/rules/01-working-style.mdc +0 -50
  284. package/dist/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  285. package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  286. package/dist/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  287. package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  288. package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  289. package/dist/templates/.cursor/rules/07-process-ops.mdc +0 -20
  290. package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  291. package/dist/templates/.cursor/rules/09-docstrings.mdc +0 -89
  292. package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  293. package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  294. package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  295. package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  296. package/dist/templates/.cursor/rules/README.md +0 -148
  297. package/dist/templates/.github/copilot-instructions.md +0 -82
  298. package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  299. package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  300. package/dist/templates/.junie/guidelines.md +0 -73
  301. package/dist/templates/.vscode/launch.json +0 -17
  302. package/dist/templates/.vscode/settings.json +0 -95
  303. package/dist/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  304. package/dist/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  305. package/dist/templates/CLAUDE.md +0 -196
  306. package/dist/templates/COMMIT_CONVENTIONS.md +0 -86
  307. package/dist/templates/OIDC_SETUP.md +0 -300
  308. package/dist/templates/agents.md +0 -171
  309. package/dist/templates/codemod/README.md +0 -1
  310. package/dist/templates/codemod/test.js +0 -93
  311. package/dist/templates/docs/README.md +0 -151
  312. package/dist/templates/scripts/new_feature.sh +0 -80
  313. package/dist/templates/scripts/quality-gates/check-god-objects.js +0 -146
  314. package/dist/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  315. package/dist/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
  316. package/dist/test-analysis.js +0 -786
  317. package/dist/tool-interface.js +0 -314
  318. package/dist/tool-loader.js +0 -303
  319. package/dist/tool-validator.js +0 -393
  320. package/dist/utils/agent-display.js +0 -210
  321. package/dist/utils/agent-session.js +0 -344
  322. package/dist/utils/async-utils.js +0 -188
  323. package/dist/utils/command-wrapper.js +0 -200
  324. package/dist/utils/event-log.js +0 -584
  325. package/dist/utils/event-renderer.js +0 -521
  326. package/dist/utils/finalization.js +0 -230
  327. package/dist/utils/git-lock.js +0 -119
  328. package/dist/utils/gitignore-updater.js +0 -158
  329. package/dist/utils/ide-detection.js +0 -133
  330. package/dist/utils/lifecycle-events.js +0 -94
  331. package/dist/utils/project-analysis.js +0 -367
  332. package/dist/utils/promise-utils.js +0 -72
  333. package/dist/utils/quality-gates-errors.js +0 -520
  334. package/dist/utils/quality-gates-utils.js +0 -387
  335. package/dist/utils/schema-validator.js +0 -50
  336. package/dist/utils/spec-resolver.js +0 -711
  337. package/dist/utils/typescript-detector.js +0 -369
  338. package/dist/utils/working-state.js +0 -530
  339. package/dist/utils/yaml-validation.js +0 -156
  340. package/dist/validation/spec-validation.js +0 -924
  341. package/dist/waivers-manager.js +0 -732
  342. package/dist/worktree/worktree-manager.js +0 -1735
  343. package/templates/.caws/schemas/policy.schema.json +0 -117
  344. package/templates/.caws/schemas/scope.schema.json +0 -52
  345. package/templates/.caws/schemas/waivers.schema.json +0 -106
  346. package/templates/.caws/schemas/working-spec.schema.json +0 -340
  347. package/templates/.caws/schemas/worktrees.schema.json +0 -38
  348. package/templates/.caws/templates/working-spec.template.yml +0 -80
  349. package/templates/.caws/tools/README.md +0 -18
  350. package/templates/.caws/tools/scope-guard.js +0 -203
  351. package/templates/.caws/tools-allow.json +0 -331
  352. package/templates/.caws/waivers.yml +0 -19
  353. package/templates/.claude/README.md +0 -190
  354. package/templates/.claude/hooks/audit.sh +0 -121
  355. package/templates/.claude/hooks/block-dangerous.sh +0 -203
  356. package/templates/.claude/hooks/classify_command.py +0 -592
  357. package/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  358. package/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  359. package/templates/.claude/hooks/naming-check.sh +0 -100
  360. package/templates/.claude/hooks/protected-paths.sh +0 -39
  361. package/templates/.claude/hooks/quality-check.sh +0 -81
  362. package/templates/.claude/hooks/scan-secrets.sh +0 -85
  363. package/templates/.claude/hooks/scope-guard.sh +0 -381
  364. package/templates/.claude/hooks/session-caws-status.sh +0 -117
  365. package/templates/.claude/hooks/session-log.sh +0 -634
  366. package/templates/.claude/hooks/simplification-guard.sh +0 -92
  367. package/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  368. package/templates/.claude/hooks/test_classify_command.py +0 -370
  369. package/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  370. package/templates/.claude/hooks/validate-spec.sh +0 -76
  371. package/templates/.claude/hooks/worktree-guard.sh +0 -220
  372. package/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  373. package/templates/.claude/rules/git-safety.md +0 -26
  374. package/templates/.claude/rules/worktree-isolation.md +0 -101
  375. package/templates/.claude/settings.json +0 -141
  376. package/templates/.cursor/README.md +0 -299
  377. package/templates/.cursor/hooks/audit.sh +0 -55
  378. package/templates/.cursor/hooks/block-dangerous.sh +0 -84
  379. package/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  380. package/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  381. package/templates/.cursor/hooks/format.sh +0 -38
  382. package/templates/.cursor/hooks/naming-check.sh +0 -64
  383. package/templates/.cursor/hooks/scan-secrets.sh +0 -51
  384. package/templates/.cursor/hooks/scope-guard.sh +0 -52
  385. package/templates/.cursor/hooks/session-log.sh +0 -924
  386. package/templates/.cursor/hooks/validate-spec.sh +0 -83
  387. package/templates/.cursor/hooks.json +0 -76
  388. package/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  389. package/templates/.cursor/rules/01-working-style.mdc +0 -50
  390. package/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  391. package/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  392. package/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  393. package/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  394. package/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  395. package/templates/.cursor/rules/07-process-ops.mdc +0 -20
  396. package/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  397. package/templates/.cursor/rules/09-docstrings.mdc +0 -89
  398. package/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  399. package/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  400. package/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  401. package/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  402. package/templates/.cursor/rules/README.md +0 -148
  403. package/templates/.github/copilot-instructions.md +0 -82
  404. package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  405. package/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  406. package/templates/.junie/guidelines.md +0 -73
  407. package/templates/.vscode/launch.json +0 -17
  408. package/templates/.vscode/settings.json +0 -95
  409. package/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  410. package/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  411. package/templates/CLAUDE.md +0 -196
  412. package/templates/COMMIT_CONVENTIONS.md +0 -86
  413. package/templates/OIDC_SETUP.md +0 -300
  414. package/templates/agents.md +0 -171
  415. package/templates/codemod/README.md +0 -1
  416. package/templates/codemod/test.js +0 -93
  417. package/templates/docs/README.md +0 -151
  418. package/templates/scripts/new_feature.sh +0 -80
  419. package/templates/scripts/quality-gates/check-god-objects.js +0 -146
  420. package/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  421. package/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
@@ -1,786 +0,0 @@
1
- /**
2
- * @fileoverview Test Analysis Module - v0.1 Statistical Learning
3
- * Learns from waivers and historical data to improve budget allocation and test selection
4
- * @author @darianrosebrook
5
- */
6
-
7
- const fs = require('fs-extra');
8
- const path = require('path');
9
- const yaml = require('js-yaml');
10
- const { resolveSpec } = require('./utils/spec-resolver');
11
-
12
- /**
13
- * Waiver Pattern Learning Engine
14
- * Analyzes waiver history to find systematic patterns in budget overruns
15
- */
16
- class WaiverPatternLearner {
17
- constructor(projectRoot = process.cwd()) {
18
- this.projectRoot = projectRoot;
19
- }
20
-
21
- /**
22
- * Analyze waiver patterns from historical data
23
- */
24
- analyzePatterns() {
25
- try {
26
- const waivers = this.loadWaivers();
27
- const specs = this.loadHistoricalSpecs();
28
-
29
- if (waivers.length === 0) {
30
- return {
31
- status: 'insufficient_data',
32
- message: 'No waiver data available for analysis',
33
- patterns: {},
34
- };
35
- }
36
-
37
- const patterns = {
38
- total_waivers: waivers.length,
39
- budget_overruns: this.analyzeBudgetOverruns(waivers, specs),
40
- common_reasons: this.analyzeCommonReasons(waivers),
41
- risk_factors: this.identifyRiskFactors(waivers, specs),
42
- generated_at: new Date().toISOString(),
43
- };
44
-
45
- return {
46
- status: 'success',
47
- patterns,
48
- };
49
- } catch (error) {
50
- return {
51
- status: 'error',
52
- message: error.message,
53
- patterns: {},
54
- };
55
- }
56
- }
57
-
58
- /**
59
- * Load all waiver files from .caws/waivers/
60
- */
61
- loadWaivers() {
62
- const waiversDir = path.join(this.projectRoot, '.caws', 'waivers');
63
- if (!fs.existsSync(waiversDir)) {
64
- return [];
65
- }
66
-
67
- const waiverFiles = fs
68
- .readdirSync(waiversDir)
69
- .filter((file) => file.endsWith('.yaml'))
70
- .map((file) => {
71
- try {
72
- const waiverPath = path.join(waiversDir, file);
73
- const waiver = yaml.load(fs.readFileSync(waiverPath, 'utf8'));
74
- return { ...waiver, file: file };
75
- } catch (error) {
76
- console.warn(`Failed to load waiver ${file}: ${error.message}`);
77
- return null;
78
- }
79
- })
80
- .filter((waiver) => waiver !== null);
81
-
82
- return waiverFiles;
83
- }
84
-
85
- /**
86
- * Load historical working specs from git history
87
- * Retrieves past versions of spec files to analyze patterns
88
- */
89
- loadHistoricalSpecs() {
90
- const { execSync } = require('child_process');
91
- const specs = [];
92
-
93
- try {
94
- // Get list of commits that modified spec files
95
- const specPaths = [
96
- '.caws/working-spec.yaml',
97
- '.caws/specs/*.yaml',
98
- ];
99
-
100
- for (const specPattern of specPaths) {
101
- try {
102
- // Get commits that touched spec files
103
- const logOutput = execSync(
104
- `git log --pretty=format:"%H" --follow -- "${specPattern}" 2>/dev/null | head -20`,
105
- { cwd: this.projectRoot, encoding: 'utf8' }
106
- ).trim();
107
-
108
- if (!logOutput) continue;
109
-
110
- const commits = logOutput.split('\n').filter(Boolean);
111
-
112
- for (const commitHash of commits) {
113
- try {
114
- // Get the list of files matching the pattern at that commit
115
- const filesOutput = execSync(
116
- `git ls-tree -r --name-only ${commitHash} -- "${specPattern}" 2>/dev/null`,
117
- { cwd: this.projectRoot, encoding: 'utf8' }
118
- ).trim();
119
-
120
- if (!filesOutput) continue;
121
-
122
- const files = filesOutput.split('\n').filter(Boolean);
123
-
124
- for (const filePath of files) {
125
- try {
126
- // Get the spec content at that commit
127
- const specContent = execSync(
128
- `git show ${commitHash}:"${filePath}" 2>/dev/null`,
129
- { cwd: this.projectRoot, encoding: 'utf8' }
130
- );
131
-
132
- const spec = yaml.load(specContent);
133
- if (spec && spec.id) {
134
- // Get commit date for context
135
- const commitDate = execSync(
136
- `git show -s --format=%ci ${commitHash}`,
137
- { cwd: this.projectRoot, encoding: 'utf8' }
138
- ).trim();
139
-
140
- specs.push({
141
- ...spec,
142
- _commit: commitHash.substring(0, 7),
143
- _date: commitDate,
144
- _file: filePath,
145
- });
146
- }
147
- } catch {
148
- // Skip files that can't be loaded
149
- }
150
- }
151
- } catch {
152
- // Skip commits with issues
153
- }
154
- }
155
- } catch {
156
- // Pattern didn't match any files
157
- }
158
- }
159
-
160
- // Also check archived specs in .caws/archive/
161
- const archiveDir = path.join(this.projectRoot, '.caws', 'archive');
162
- if (fs.existsSync(archiveDir)) {
163
- const archiveFiles = fs.readdirSync(archiveDir)
164
- .filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
165
-
166
- for (const file of archiveFiles) {
167
- try {
168
- const archivePath = path.join(archiveDir, file);
169
- const spec = yaml.load(fs.readFileSync(archivePath, 'utf8'));
170
- if (spec && spec.id) {
171
- specs.push({
172
- ...spec,
173
- _source: 'archive',
174
- _file: file,
175
- });
176
- }
177
- } catch {
178
- // Skip invalid archive files
179
- }
180
- }
181
- }
182
-
183
- // Deduplicate by spec ID, keeping the most recent version
184
- const uniqueSpecs = new Map();
185
- for (const spec of specs) {
186
- const existing = uniqueSpecs.get(spec.id);
187
- if (!existing || (spec._date && (!existing._date || spec._date > existing._date))) {
188
- uniqueSpecs.set(spec.id, spec);
189
- }
190
- }
191
-
192
- return Array.from(uniqueSpecs.values());
193
- } catch (error) {
194
- console.warn(`Failed to load historical specs: ${error.message}`);
195
- return [];
196
- }
197
- }
198
-
199
- /**
200
- * Analyze budget overrun patterns
201
- */
202
- analyzeBudgetOverruns(waivers, _specs) {
203
- const budgetWaivers = waivers.filter((w) => w.gates?.includes('budget_limit'));
204
-
205
- if (budgetWaivers.length === 0) {
206
- return {
207
- average_overrun_files: 0,
208
- average_overrun_loc: 0,
209
- common_patterns: [],
210
- };
211
- }
212
-
213
- const overruns = budgetWaivers
214
- .filter((w) => w.delta)
215
- .map((w) => ({
216
- files: w.delta.max_files || 0,
217
- loc: w.delta.max_loc || 0,
218
- reason: w.reason_code,
219
- applies_to: w.applies_to,
220
- }));
221
-
222
- const avgFiles = overruns.reduce((sum, o) => sum + o.files, 0) / overruns.length;
223
- const avgLoc = overruns.reduce((sum, o) => sum + o.loc, 0) / overruns.length;
224
-
225
- // Group by reason
226
- const byReason = overruns.reduce((acc, overrun) => {
227
- acc[overrun.reason] = acc[overrun.reason] || [];
228
- acc[overrun.reason].push(overrun);
229
- return acc;
230
- }, {});
231
-
232
- const commonPatterns = Object.entries(byReason)
233
- .map(([reason, overruns]) => ({
234
- reason,
235
- frequency: overruns.length / budgetWaivers.length,
236
- avg_overrun_files: overruns.reduce((sum, o) => sum + o.files, 0) / overruns.length,
237
- avg_overrun_loc: overruns.reduce((sum, o) => sum + o.loc, 0) / overruns.length,
238
- }))
239
- .sort((a, b) => b.frequency - a.frequency);
240
-
241
- return {
242
- total_budget_waivers: budgetWaivers.length,
243
- average_overrun_files: Math.round(avgFiles),
244
- average_overrun_loc: Math.round(avgLoc),
245
- common_patterns: commonPatterns.slice(0, 5), // Top 5 patterns
246
- };
247
- }
248
-
249
- /**
250
- * Analyze most common waiver reasons
251
- */
252
- analyzeCommonReasons(waivers) {
253
- const reasons = waivers.reduce((acc, waiver) => {
254
- acc[waiver.reason_code] = (acc[waiver.reason_code] || 0) + 1;
255
- return acc;
256
- }, {});
257
-
258
- return Object.entries(reasons)
259
- .map(([reason, count]) => ({
260
- reason,
261
- count,
262
- frequency: count / waivers.length,
263
- }))
264
- .sort((a, b) => b.count - a.count);
265
- }
266
-
267
- /**
268
- * Identify risk factors from waiver patterns
269
- */
270
- identifyRiskFactors(waivers, _specs) {
271
- // Simple risk factor identification based on waiver frequency
272
- const riskFactors = [];
273
-
274
- const reasons = this.analyzeCommonReasons(waivers);
275
- if (reasons.length > 0) {
276
- riskFactors.push({
277
- factor: 'common_waiver_reasons',
278
- description: `${reasons[0].reason} waivers occur in ${Math.round(reasons[0].frequency * 100)}% of cases`,
279
- risk_level:
280
- reasons[0].frequency > 0.5 ? 'high' : reasons[0].frequency > 0.3 ? 'medium' : 'low',
281
- });
282
- }
283
-
284
- return riskFactors;
285
- }
286
- }
287
-
288
- /**
289
- * Project Similarity Matcher
290
- * Finds historical projects similar to current work
291
- */
292
- class ProjectSimilarityMatcher {
293
- constructor(projectRoot = process.cwd()) {
294
- this.projectRoot = projectRoot;
295
- this.patternLearner = new WaiverPatternLearner(projectRoot);
296
- }
297
-
298
- /**
299
- * Find projects similar to the current spec
300
- * Uses real historical specs from git history when available
301
- */
302
- findSimilarProjects(currentSpec) {
303
- // Load real historical specs first
304
- const historicalSpecs = this.patternLearner.loadHistoricalSpecs();
305
-
306
- // Convert historical specs to project format with budget data
307
- const historicalProjects = historicalSpecs
308
- .filter(spec => spec.id !== currentSpec.id) // Exclude current spec
309
- .map(spec => this.specToProject(spec));
310
-
311
- // If we have real historical data, use it
312
- if (historicalProjects.length > 0) {
313
- return historicalProjects
314
- .map((project) => ({
315
- project: project.id,
316
- similarity_score: this.calculateSimilarity(currentSpec, project),
317
- budget_accuracy: project.allocated_budget.files > 0
318
- ? project.actual_budget.files / project.allocated_budget.files
319
- : 1.0,
320
- waiver_count: project.waivers?.length || 0,
321
- details: project,
322
- }))
323
- .filter((p) => p.similarity_score > 0.3)
324
- .sort((a, b) => b.similarity_score - a.similarity_score)
325
- .slice(0, 5);
326
- }
327
-
328
- // Fallback to demo data if no historical specs found
329
- const demoProjects = [
330
- {
331
- id: 'PROJ-0123',
332
- title: 'API Enhancement',
333
- risk_tier: 2,
334
- mode: 'feature',
335
- tech_stack: 'node',
336
- feature_type: 'api',
337
- actual_budget: { files: 85, loc: 8500 },
338
- allocated_budget: { files: 70, loc: 7000 },
339
- waivers: ['WV-0001'],
340
- },
341
- {
342
- id: 'FEAT-0456',
343
- title: 'UI Component Library',
344
- risk_tier: 2,
345
- mode: 'feature',
346
- tech_stack: 'react',
347
- feature_type: 'ui',
348
- actual_budget: { files: 45, loc: 4200 },
349
- allocated_budget: { files: 50, loc: 5000 },
350
- waivers: [],
351
- },
352
- {
353
- id: 'FIX-0789',
354
- title: 'Data Migration',
355
- risk_tier: 1,
356
- mode: 'feature',
357
- tech_stack: 'node',
358
- feature_type: 'data',
359
- actual_budget: { files: 25, loc: 2800 },
360
- allocated_budget: { files: 20, loc: 2000 },
361
- waivers: ['WV-0002'],
362
- },
363
- ];
364
-
365
- // Add a demo project similar to ARCH-0001 for demonstration
366
- if (currentSpec.id === 'ARCH-0001') {
367
- demoProjects.push({
368
- id: 'ARCH-0002',
369
- title: 'Policy System Refactor',
370
- risk_tier: 1,
371
- mode: 'feature',
372
- tech_stack: 'node',
373
- feature_type: 'architecture',
374
- actual_budget: { files: 120, loc: 12000 },
375
- allocated_budget: { files: 100, loc: 10000 },
376
- waivers: ['WV-0002'],
377
- });
378
- }
379
-
380
- return demoProjects
381
- .map((project) => ({
382
- project: project.id,
383
- similarity_score: this.calculateSimilarity(currentSpec, project),
384
- budget_accuracy: project.actual_budget.files / project.allocated_budget.files,
385
- waiver_count: project.waivers.length,
386
- details: project,
387
- }))
388
- .filter((p) => p.similarity_score > 0.3) // Lower threshold for demonstration
389
- .sort((a, b) => b.similarity_score - a.similarity_score)
390
- .slice(0, 5); // Top 5 matches
391
- }
392
-
393
- /**
394
- * Convert a spec object to project format for similarity comparison
395
- */
396
- specToProject(spec) {
397
- // Extract budget info from spec
398
- const budget = spec.budget || spec.scope?.budget || {};
399
- const allocatedFiles = budget.max_files || budget.files || 50;
400
- const allocatedLoc = budget.max_loc || budget.loc || 5000;
401
-
402
- // If spec has actual metrics, use them; otherwise estimate from allocated
403
- const actualFiles = spec.metrics?.files_changed || spec.actual_files || allocatedFiles;
404
- const actualLoc = spec.metrics?.lines_changed || spec.actual_loc || allocatedLoc;
405
-
406
- // Extract tech stack from spec metadata
407
- let techStack = spec.tech_stack || spec.metadata?.tech_stack || 'unknown';
408
- if (!techStack || techStack === 'unknown') {
409
- // Try to infer from title or description
410
- const text = `${spec.title || ''} ${spec.description || ''}`.toLowerCase();
411
- if (text.includes('react') || text.includes('ui') || text.includes('component')) {
412
- techStack = 'react';
413
- } else if (text.includes('api') || text.includes('node') || text.includes('server')) {
414
- techStack = 'node';
415
- } else if (text.includes('python') || text.includes('django') || text.includes('flask')) {
416
- techStack = 'python';
417
- }
418
- }
419
-
420
- // Extract feature type
421
- let featureType = spec.feature_type || spec.type || 'general';
422
- if (featureType === 'general') {
423
- const text = `${spec.title || ''} ${spec.description || ''}`.toLowerCase();
424
- if (text.includes('api') || text.includes('endpoint')) {
425
- featureType = 'api';
426
- } else if (text.includes('ui') || text.includes('component') || text.includes('view')) {
427
- featureType = 'ui';
428
- } else if (text.includes('data') || text.includes('migration') || text.includes('database')) {
429
- featureType = 'data';
430
- } else if (text.includes('refactor') || text.includes('architecture')) {
431
- featureType = 'architecture';
432
- }
433
- }
434
-
435
- return {
436
- id: spec.id,
437
- title: spec.title || spec.name || spec.id,
438
- risk_tier: spec.risk_tier || spec.tier || 2,
439
- mode: spec.mode || 'feature',
440
- tech_stack: techStack,
441
- feature_type: featureType,
442
- actual_budget: {
443
- files: actualFiles,
444
- loc: actualLoc,
445
- },
446
- allocated_budget: {
447
- files: allocatedFiles,
448
- loc: allocatedLoc,
449
- },
450
- waivers: spec.waivers || [],
451
- _source: spec._source,
452
- _date: spec._date,
453
- };
454
- }
455
-
456
- /**
457
- * Calculate similarity score between two specs/projects
458
- */
459
- calculateSimilarity(spec1, spec2) {
460
- let score = 0;
461
- let factors = 0;
462
-
463
- // Risk tier match
464
- if (spec1.risk_tier === spec2.risk_tier) {
465
- score += 0.3;
466
- }
467
- factors += 0.3;
468
-
469
- // Mode match
470
- if (spec1.mode === spec2.mode) {
471
- score += 0.2;
472
- }
473
- factors += 0.2;
474
-
475
- // Tech stack match (if available)
476
- if (spec1.tech_stack && spec2.tech_stack && spec1.tech_stack === spec2.tech_stack) {
477
- score += 0.2;
478
- }
479
- factors += 0.2;
480
-
481
- // Feature type match (if available)
482
- if (spec1.feature_type && spec2.feature_type && spec1.feature_type === spec2.feature_type) {
483
- score += 0.3;
484
- }
485
- factors += 0.3;
486
-
487
- return factors > 0 ? score / factors : 0;
488
- }
489
- }
490
-
491
- /**
492
- * Budget Predictor using statistical analysis
493
- */
494
- class BudgetPredictor {
495
- constructor(projectRoot = process.cwd()) {
496
- this.projectRoot = projectRoot;
497
- this.patternLearner = new WaiverPatternLearner(projectRoot);
498
- this.similarityMatcher = new ProjectSimilarityMatcher(projectRoot);
499
- }
500
-
501
- /**
502
- * Assess budget for a working spec
503
- */
504
- assessBudget(spec) {
505
- try {
506
- const patterns = this.patternLearner.analyzePatterns();
507
- const similarProjects = this.similarityMatcher.findSimilarProjects(spec);
508
-
509
- if (patterns.status !== 'success' || similarProjects.length === 0) {
510
- return {
511
- status: 'insufficient_data',
512
- message: 'Not enough historical data for accurate prediction',
513
- recommendation: {
514
- use_default_tier: true,
515
- confidence: 0.0,
516
- },
517
- };
518
- }
519
-
520
- // Calculate recommended budget based on similar projects
521
- const similarBudgets = similarProjects.map((p) => p.details.actual_budget);
522
- const avgFiles = similarBudgets.reduce((sum, b) => sum + b.files, 0) / similarBudgets.length;
523
- const avgLoc = similarBudgets.reduce((sum, b) => sum + b.loc, 0) / similarBudgets.length;
524
-
525
- // Apply buffer based on waiver patterns
526
- const fileBuffer = patterns.patterns.budget_overruns?.average_overrun_files || 0;
527
- const locBuffer = patterns.patterns.budget_overruns?.average_overrun_loc || 0;
528
-
529
- const recommendedFiles = Math.round(avgFiles * (1 + fileBuffer / 100));
530
- const recommendedLoc = Math.round(avgLoc * (1 + locBuffer / 100));
531
-
532
- // Calculate confidence based on sample size and variance
533
- const confidence = Math.min(0.9, similarProjects.length / 10); // Max 90% confidence
534
-
535
- return {
536
- status: 'success',
537
- assessment: {
538
- similar_projects_analyzed: similarProjects.length,
539
- recommended_budget: {
540
- files: recommendedFiles,
541
- loc: recommendedLoc,
542
- },
543
- baseline_budget: {
544
- files: Math.round(avgFiles),
545
- loc: Math.round(avgLoc),
546
- },
547
- buffer_applied: {
548
- files_percent: Math.round((fileBuffer / avgFiles) * 100),
549
- loc_percent: Math.round((locBuffer / avgLoc) * 100),
550
- },
551
- rationale: this.generateRationale(spec, similarProjects, patterns),
552
- risk_factors: patterns.patterns.risk_factors || [],
553
- confidence: Math.round(confidence * 100) / 100,
554
- },
555
- };
556
- } catch (error) {
557
- return {
558
- status: 'error',
559
- message: error.message,
560
- recommendation: {
561
- use_default_tier: true,
562
- confidence: 0.0,
563
- },
564
- };
565
- }
566
- }
567
-
568
- /**
569
- * Generate human-readable rationale for the recommendation
570
- */
571
- generateRationale(spec, similarProjects, patterns) {
572
- const reasons = [];
573
-
574
- if (similarProjects.length > 0) {
575
- const topMatch = similarProjects[0];
576
- reasons.push(
577
- `Similar to ${topMatch.project} (${Math.round(topMatch.similarity_score * 100)}% match)`
578
- );
579
- }
580
-
581
- if (patterns.patterns.budget_overruns?.common_patterns?.length > 0) {
582
- const topPattern = patterns.patterns.budget_overruns.common_patterns[0];
583
- reasons.push(
584
- `Historical ${topPattern.reason} overruns add ${topPattern.avg_overrun_files} files on average`
585
- );
586
- }
587
-
588
- if (spec.mode === 'feature') {
589
- reasons.push('Feature development typically needs 15-25% budget buffer');
590
- }
591
-
592
- return reasons;
593
- }
594
- }
595
-
596
- /**
597
- * Main Test Analysis CLI handler
598
- */
599
- async function testAnalysisCommand(subcommand, options = [], commandOptions = {}) {
600
- const chalk = (await import('chalk')).default;
601
-
602
- try {
603
- switch (subcommand) {
604
- case 'assess-budget':
605
- return await handleAssessBudget(options, commandOptions);
606
- case 'analyze-patterns':
607
- return await handleAnalyzePatterns(options);
608
- case 'find-similar':
609
- return await handleFindSimilar(options, commandOptions);
610
- default:
611
- console.log(chalk.red('Unknown test-analysis subcommand'));
612
- console.log('Available commands:');
613
- console.log(' assess-budget - Analyze budget needs for current spec');
614
- console.log(' analyze-patterns - Show waiver pattern analysis');
615
- console.log(' find-similar - Find similar historical projects');
616
- return;
617
- }
618
- } catch (error) {
619
- console.error(chalk.red('Test analysis failed:'), error.message);
620
- }
621
- }
622
-
623
- /**
624
- * Resolve the current spec for analysis commands.
625
- * Supports explicit `--spec <path>` for compatibility, but prefers
626
- * the suite-standard resolver and `--spec-id`.
627
- * @param {string[]} optionArgs
628
- * @param {Object} commandOptions
629
- * @returns {Promise<{spec: Object, specPath: string}>}
630
- */
631
- async function resolveAnalysisSpec(optionArgs = [], commandOptions = {}) {
632
- let specFile = null;
633
- if (Array.isArray(optionArgs) && optionArgs.includes('--spec')) {
634
- const specIndex = optionArgs.indexOf('--spec');
635
- if (specIndex + 1 < optionArgs.length) {
636
- specFile = optionArgs[specIndex + 1];
637
- }
638
- }
639
-
640
- const resolved = await resolveSpec({
641
- specId: commandOptions.specId,
642
- specFile,
643
- warnLegacy: false,
644
- interactive: false,
645
- });
646
-
647
- return {
648
- spec: resolved.spec,
649
- specPath: resolved.path,
650
- };
651
- }
652
-
653
- /**
654
- * Handle budget assessment command
655
- */
656
- async function handleAssessBudget(options, commandOptions = {}) {
657
- const chalk = (await import('chalk')).default;
658
- const predictor = new BudgetPredictor();
659
-
660
- try {
661
- const { spec, specPath } = await resolveAnalysisSpec(options, commandOptions);
662
-
663
- console.log(chalk.cyan(`Budget Assessment for ${spec.id}`));
664
- console.log('==============================================');
665
- console.log(chalk.gray(`Spec: ${path.relative(process.cwd(), specPath)}`));
666
-
667
- const result = predictor.assessBudget(spec);
668
-
669
- if (result.status === 'success') {
670
- const assessment = result.assessment;
671
- console.log(
672
- `Historical Analysis: ${assessment.similar_projects_analyzed} similar projects analyzed`
673
- );
674
- console.log(
675
- `Recommended Budget: ${assessment.recommended_budget.files} files, ${assessment.recommended_budget.loc} LOC (+${assessment.buffer_applied.files_percent}% buffer)`
676
- );
677
- console.log(`Rationale: ${assessment.rationale.join('; ')}`);
678
-
679
- if (assessment.risk_factors.length > 0) {
680
- console.log(
681
- chalk.yellow(
682
- `Risk Factors: ${assessment.risk_factors.map((f) => f.description).join('; ')}`
683
- )
684
- );
685
- }
686
-
687
- const confidenceLevel =
688
- assessment.confidence > 0.8 ? 'High' : assessment.confidence > 0.6 ? 'Medium' : 'Low';
689
- console.log(
690
- chalk.green(
691
- `Confidence: ${confidenceLevel} (${Math.round(assessment.confidence * 100)}%)`
692
- )
693
- );
694
- } else {
695
- console.log(chalk.yellow(`${result.message}`));
696
- console.log('Consider using default tier-based budgeting for now');
697
- }
698
- } catch (error) {
699
- console.error(chalk.red('Failed to load spec:'), error.message);
700
- }
701
- }
702
-
703
- /**
704
- * Handle pattern analysis command
705
- */
706
- async function handleAnalyzePatterns(_options) {
707
- const chalk = (await import('chalk')).default;
708
- const learner = new WaiverPatternLearner();
709
-
710
- console.log(chalk.cyan('Analyzing Waiver Patterns'));
711
- console.log('==============================================');
712
-
713
- const result = learner.analyzePatterns();
714
-
715
- if (result.status === 'success') {
716
- const patterns = result.patterns;
717
-
718
- console.log(`Total waivers analyzed: ${patterns.total_waivers}`);
719
-
720
- if (patterns.budget_overruns) {
721
- console.log('\nBudget Overrun Patterns:');
722
- console.log(
723
- ` Average overrun: ${patterns.budget_overruns.average_overrun_files} files, ${patterns.budget_overruns.average_overrun_loc} LOC`
724
- );
725
-
726
- if (patterns.budget_overruns.common_patterns.length > 0) {
727
- console.log(' Common patterns:');
728
- patterns.budget_overruns.common_patterns.forEach((pattern) => {
729
- console.log(
730
- ` ${pattern.reason}: ${Math.round(pattern.frequency * 100)}% frequency (+${pattern.avg_overrun_files} files avg)`
731
- );
732
- });
733
- }
734
- }
735
-
736
- if (patterns.common_reasons.length > 0) {
737
- console.log('\nMost Common Waiver Reasons:');
738
- patterns.common_reasons.slice(0, 5).forEach((reason) => {
739
- console.log(
740
- ` ${reason.reason}: ${reason.count} times (${Math.round(reason.frequency * 100)}%)`
741
- );
742
- });
743
- }
744
- } else {
745
- console.log(chalk.yellow(`${result.message}`));
746
- }
747
- }
748
-
749
- /**
750
- * Handle find similar projects command
751
- */
752
- async function handleFindSimilar(options, commandOptions = {}) {
753
- const chalk = (await import('chalk')).default;
754
- const matcher = new ProjectSimilarityMatcher();
755
-
756
- try {
757
- const { spec, specPath } = await resolveAnalysisSpec(options, commandOptions);
758
-
759
- console.log(chalk.cyan(`Finding projects similar to ${spec.id}`));
760
- console.log('==============================================');
761
- console.log(chalk.gray(`Spec: ${path.relative(process.cwd(), specPath)}`));
762
-
763
- const similar = matcher.findSimilarProjects(spec);
764
-
765
- if (similar.length > 0) {
766
- similar.forEach((project) => {
767
- const similarityPercent = Math.round(project.similarity_score * 100);
768
- const accuracyPercent = Math.round(project.budget_accuracy * 100);
769
- console.log(
770
- `${project.project}: ${similarityPercent}% similar, ${accuracyPercent}% budget accuracy, ${project.waiver_count} waivers`
771
- );
772
- });
773
- } else {
774
- console.log(chalk.yellow('No similar projects found'));
775
- }
776
- } catch (error) {
777
- console.error(chalk.red('Failed to load spec:'), error.message);
778
- }
779
- }
780
-
781
- module.exports = {
782
- testAnalysisCommand,
783
- WaiverPatternLearner,
784
- ProjectSimilarityMatcher,
785
- BudgetPredictor,
786
- };