@paths.design/caws-cli 10.1.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 (419) hide show
  1. package/README.md +125 -374
  2. package/dist/index.js +43 -756
  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/archive.js +0 -500
  183. package/dist/commands/burnup.js +0 -198
  184. package/dist/commands/diagnose.js +0 -525
  185. package/dist/commands/evaluate.js +0 -314
  186. package/dist/commands/gates.js +0 -149
  187. package/dist/commands/init.js +0 -857
  188. package/dist/commands/iterate.js +0 -417
  189. package/dist/commands/mode.js +0 -269
  190. package/dist/commands/parallel.js +0 -242
  191. package/dist/commands/plan.js +0 -438
  192. package/dist/commands/provenance.js +0 -1143
  193. package/dist/commands/quality-monitor.js +0 -284
  194. package/dist/commands/scope.js +0 -264
  195. package/dist/commands/session.js +0 -312
  196. package/dist/commands/sidecar.js +0 -74
  197. package/dist/commands/specs.js +0 -1448
  198. package/dist/commands/status.js +0 -1151
  199. package/dist/commands/templates.js +0 -237
  200. package/dist/commands/tool.js +0 -136
  201. package/dist/commands/tutorial.js +0 -480
  202. package/dist/commands/validate.js +0 -357
  203. package/dist/commands/verify-acs.js +0 -443
  204. package/dist/commands/waivers.js +0 -599
  205. package/dist/commands/workflow.js +0 -243
  206. package/dist/commands/worktree.js +0 -386
  207. package/dist/config/lite-scope.js +0 -158
  208. package/dist/config/modes.js +0 -347
  209. package/dist/constants/spec-types.js +0 -65
  210. package/dist/gates/budget-limit.js +0 -121
  211. package/dist/gates/feedback.js +0 -260
  212. package/dist/gates/format.js +0 -179
  213. package/dist/gates/god-object.js +0 -117
  214. package/dist/gates/pipeline.js +0 -167
  215. package/dist/gates/scope-boundary.js +0 -93
  216. package/dist/gates/spec-completeness.js +0 -109
  217. package/dist/gates/todo-detection.js +0 -205
  218. package/dist/generators/jest-config-generator.js +0 -242
  219. package/dist/generators/working-spec.js +0 -237
  220. package/dist/minimal-cli.js +0 -88
  221. package/dist/parallel/parallel-manager.js +0 -433
  222. package/dist/policy/PolicyManager.js +0 -465
  223. package/dist/scaffold/claude-hooks.js +0 -443
  224. package/dist/scaffold/cursor-hooks.js +0 -177
  225. package/dist/scaffold/git-hooks.js +0 -928
  226. package/dist/scaffold/index.js +0 -794
  227. package/dist/session/session-manager.js +0 -653
  228. package/dist/sidecars/index.js +0 -33
  229. package/dist/sidecars/listeners.js +0 -40
  230. package/dist/sidecars/provenance-summary.js +0 -238
  231. package/dist/sidecars/quality-gaps.js +0 -258
  232. package/dist/sidecars/schema.js +0 -149
  233. package/dist/sidecars/spec-drift.js +0 -151
  234. package/dist/sidecars/waiver-draft.js +0 -176
  235. package/dist/spec/SpecFileManager.js +0 -419
  236. package/dist/templates/.caws/schemas/policy.schema.json +0 -112
  237. package/dist/templates/.caws/schemas/scope.schema.json +0 -52
  238. package/dist/templates/.caws/schemas/waivers.schema.json +0 -106
  239. package/dist/templates/.caws/schemas/working-spec.schema.json +0 -340
  240. package/dist/templates/.caws/schemas/worktrees.schema.json +0 -38
  241. package/dist/templates/.caws/templates/working-spec.template.yml +0 -80
  242. package/dist/templates/.caws/tools/README.md +0 -18
  243. package/dist/templates/.caws/tools/scope-guard.js +0 -203
  244. package/dist/templates/.caws/tools-allow.json +0 -331
  245. package/dist/templates/.caws/waivers.yml +0 -19
  246. package/dist/templates/.claude/README.md +0 -190
  247. package/dist/templates/.claude/hooks/audit.sh +0 -121
  248. package/dist/templates/.claude/hooks/block-dangerous.sh +0 -203
  249. package/dist/templates/.claude/hooks/classify_command.py +0 -592
  250. package/dist/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  251. package/dist/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  252. package/dist/templates/.claude/hooks/naming-check.sh +0 -100
  253. package/dist/templates/.claude/hooks/protected-paths.sh +0 -39
  254. package/dist/templates/.claude/hooks/quality-check.sh +0 -81
  255. package/dist/templates/.claude/hooks/scan-secrets.sh +0 -85
  256. package/dist/templates/.claude/hooks/scope-guard.sh +0 -381
  257. package/dist/templates/.claude/hooks/session-caws-status.sh +0 -117
  258. package/dist/templates/.claude/hooks/session-log.sh +0 -634
  259. package/dist/templates/.claude/hooks/simplification-guard.sh +0 -92
  260. package/dist/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  261. package/dist/templates/.claude/hooks/test_classify_command.py +0 -370
  262. package/dist/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  263. package/dist/templates/.claude/hooks/validate-spec.sh +0 -76
  264. package/dist/templates/.claude/hooks/worktree-guard.sh +0 -220
  265. package/dist/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  266. package/dist/templates/.claude/rules/git-safety.md +0 -26
  267. package/dist/templates/.claude/rules/worktree-isolation.md +0 -83
  268. package/dist/templates/.claude/settings.json +0 -141
  269. package/dist/templates/.cursor/README.md +0 -299
  270. package/dist/templates/.cursor/hooks/audit.sh +0 -55
  271. package/dist/templates/.cursor/hooks/block-dangerous.sh +0 -84
  272. package/dist/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  273. package/dist/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  274. package/dist/templates/.cursor/hooks/format.sh +0 -38
  275. package/dist/templates/.cursor/hooks/naming-check.sh +0 -64
  276. package/dist/templates/.cursor/hooks/scan-secrets.sh +0 -51
  277. package/dist/templates/.cursor/hooks/scope-guard.sh +0 -52
  278. package/dist/templates/.cursor/hooks/session-log.sh +0 -924
  279. package/dist/templates/.cursor/hooks/validate-spec.sh +0 -83
  280. package/dist/templates/.cursor/hooks.json +0 -76
  281. package/dist/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  282. package/dist/templates/.cursor/rules/01-working-style.mdc +0 -50
  283. package/dist/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  284. package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  285. package/dist/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  286. package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  287. package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  288. package/dist/templates/.cursor/rules/07-process-ops.mdc +0 -20
  289. package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  290. package/dist/templates/.cursor/rules/09-docstrings.mdc +0 -89
  291. package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  292. package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  293. package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  294. package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  295. package/dist/templates/.cursor/rules/README.md +0 -148
  296. package/dist/templates/.github/copilot-instructions.md +0 -82
  297. package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  298. package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  299. package/dist/templates/.junie/guidelines.md +0 -73
  300. package/dist/templates/.vscode/launch.json +0 -17
  301. package/dist/templates/.vscode/settings.json +0 -95
  302. package/dist/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  303. package/dist/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  304. package/dist/templates/CLAUDE.md +0 -174
  305. package/dist/templates/COMMIT_CONVENTIONS.md +0 -86
  306. package/dist/templates/OIDC_SETUP.md +0 -300
  307. package/dist/templates/agents.md +0 -145
  308. package/dist/templates/codemod/README.md +0 -1
  309. package/dist/templates/codemod/test.js +0 -93
  310. package/dist/templates/docs/README.md +0 -151
  311. package/dist/templates/scripts/new_feature.sh +0 -80
  312. package/dist/templates/scripts/quality-gates/check-god-objects.js +0 -146
  313. package/dist/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  314. package/dist/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
  315. package/dist/test-analysis.js +0 -786
  316. package/dist/tool-interface.js +0 -314
  317. package/dist/tool-loader.js +0 -303
  318. package/dist/tool-validator.js +0 -393
  319. package/dist/utils/agent-session.js +0 -202
  320. package/dist/utils/async-utils.js +0 -188
  321. package/dist/utils/command-wrapper.js +0 -200
  322. package/dist/utils/event-log.js +0 -584
  323. package/dist/utils/event-renderer.js +0 -521
  324. package/dist/utils/finalization.js +0 -230
  325. package/dist/utils/git-lock.js +0 -119
  326. package/dist/utils/gitignore-updater.js +0 -158
  327. package/dist/utils/ide-detection.js +0 -133
  328. package/dist/utils/lifecycle-events.js +0 -94
  329. package/dist/utils/project-analysis.js +0 -367
  330. package/dist/utils/promise-utils.js +0 -72
  331. package/dist/utils/quality-gates-errors.js +0 -520
  332. package/dist/utils/quality-gates-utils.js +0 -387
  333. package/dist/utils/schema-validator.js +0 -50
  334. package/dist/utils/spec-resolver.js +0 -711
  335. package/dist/utils/typescript-detector.js +0 -369
  336. package/dist/utils/working-state.js +0 -530
  337. package/dist/utils/yaml-validation.js +0 -156
  338. package/dist/validation/spec-validation.js +0 -921
  339. package/dist/waivers-manager.js +0 -732
  340. package/dist/worktree/worktree-manager.js +0 -1374
  341. package/templates/.caws/schemas/policy.schema.json +0 -112
  342. package/templates/.caws/schemas/scope.schema.json +0 -52
  343. package/templates/.caws/schemas/waivers.schema.json +0 -106
  344. package/templates/.caws/schemas/working-spec.schema.json +0 -340
  345. package/templates/.caws/schemas/worktrees.schema.json +0 -38
  346. package/templates/.caws/templates/working-spec.template.yml +0 -80
  347. package/templates/.caws/tools/README.md +0 -18
  348. package/templates/.caws/tools/scope-guard.js +0 -203
  349. package/templates/.caws/tools-allow.json +0 -331
  350. package/templates/.caws/waivers.yml +0 -19
  351. package/templates/.claude/README.md +0 -190
  352. package/templates/.claude/hooks/audit.sh +0 -121
  353. package/templates/.claude/hooks/block-dangerous.sh +0 -203
  354. package/templates/.claude/hooks/classify_command.py +0 -592
  355. package/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  356. package/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  357. package/templates/.claude/hooks/naming-check.sh +0 -100
  358. package/templates/.claude/hooks/protected-paths.sh +0 -39
  359. package/templates/.claude/hooks/quality-check.sh +0 -81
  360. package/templates/.claude/hooks/scan-secrets.sh +0 -85
  361. package/templates/.claude/hooks/scope-guard.sh +0 -381
  362. package/templates/.claude/hooks/session-caws-status.sh +0 -117
  363. package/templates/.claude/hooks/session-log.sh +0 -634
  364. package/templates/.claude/hooks/simplification-guard.sh +0 -92
  365. package/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  366. package/templates/.claude/hooks/test_classify_command.py +0 -370
  367. package/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  368. package/templates/.claude/hooks/validate-spec.sh +0 -76
  369. package/templates/.claude/hooks/worktree-guard.sh +0 -220
  370. package/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  371. package/templates/.claude/rules/git-safety.md +0 -26
  372. package/templates/.claude/rules/worktree-isolation.md +0 -83
  373. package/templates/.claude/settings.json +0 -141
  374. package/templates/.cursor/README.md +0 -299
  375. package/templates/.cursor/hooks/audit.sh +0 -55
  376. package/templates/.cursor/hooks/block-dangerous.sh +0 -84
  377. package/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  378. package/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  379. package/templates/.cursor/hooks/format.sh +0 -38
  380. package/templates/.cursor/hooks/naming-check.sh +0 -64
  381. package/templates/.cursor/hooks/scan-secrets.sh +0 -51
  382. package/templates/.cursor/hooks/scope-guard.sh +0 -52
  383. package/templates/.cursor/hooks/session-log.sh +0 -924
  384. package/templates/.cursor/hooks/validate-spec.sh +0 -83
  385. package/templates/.cursor/hooks.json +0 -76
  386. package/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  387. package/templates/.cursor/rules/01-working-style.mdc +0 -50
  388. package/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  389. package/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  390. package/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  391. package/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  392. package/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  393. package/templates/.cursor/rules/07-process-ops.mdc +0 -20
  394. package/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  395. package/templates/.cursor/rules/09-docstrings.mdc +0 -89
  396. package/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  397. package/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  398. package/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  399. package/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  400. package/templates/.cursor/rules/README.md +0 -148
  401. package/templates/.github/copilot-instructions.md +0 -82
  402. package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  403. package/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  404. package/templates/.junie/guidelines.md +0 -73
  405. package/templates/.vscode/launch.json +0 -17
  406. package/templates/.vscode/settings.json +0 -95
  407. package/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  408. package/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  409. package/templates/CLAUDE.md +0 -174
  410. package/templates/COMMIT_CONVENTIONS.md +0 -86
  411. package/templates/OIDC_SETUP.md +0 -300
  412. package/templates/agents.md +0 -145
  413. package/templates/codemod/README.md +0 -1
  414. package/templates/codemod/test.js +0 -93
  415. package/templates/docs/README.md +0 -151
  416. package/templates/scripts/new_feature.sh +0 -80
  417. package/templates/scripts/quality-gates/check-god-objects.js +0 -146
  418. package/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  419. 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
- };