@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,1151 +0,0 @@
1
- /**
2
- * @fileoverview CAWS Status Command
3
- * Display project health overview
4
- * @author @darianrosebrook
5
- */
6
-
7
- const fs = require('fs-extra');
8
- const path = require('path');
9
- const yaml = require('js-yaml');
10
- const chalk = require('chalk');
11
- // child_process removed - execSync no longer used directly
12
- const { safeAsync, outputResult } = require('../error-handler');
13
- const { parallel } = require('../utils/async-utils');
14
- const { resolveSpec } = require('../utils/spec-resolver');
15
- // EVLOG-002 Phase 2 read flip: status reads working state from the event log
16
- // via the pure renderer. loadStateFromEvents matches loadState's null contract
17
- // exactly, so the `ws && ws.phase !== 'not-started'` guard and the
18
- // `loadState(id) || null` coalesce below stay semantically correct.
19
- const { loadStateFromEvents } = require('../utils/event-renderer');
20
-
21
- /**
22
- * Load working specification (legacy single file approach)
23
- * @param {string} specPath - Path to working spec
24
- * @returns {Promise<Object|null>} Parsed spec or null
25
- */
26
- async function loadWorkingSpec(specPath = '.caws/working-spec.yaml') {
27
- try {
28
- if (!(await fs.pathExists(specPath))) {
29
- return null;
30
- }
31
-
32
- const content = await fs.readFile(specPath, 'utf8');
33
- return yaml.load(content);
34
- } catch (error) {
35
- return null;
36
- }
37
- }
38
-
39
- /**
40
- * Resolve the primary spec for status display when explicitly targeted
41
- * or when the resolver can identify a single canonical spec.
42
- * Returns null when no spec can be auto-selected.
43
- * @param {Object} options
44
- * @returns {Promise<Object|null>}
45
- */
46
- async function loadResolvedStatusSpec(options = {}) {
47
- try {
48
- const resolved = await resolveSpec({
49
- specId: options.specId,
50
- specFile: options.spec,
51
- warnLegacy: false,
52
- interactive: false,
53
- quiet: Boolean(options.json),
54
- });
55
- return {
56
- ...resolved,
57
- selected: true,
58
- };
59
- } catch (error) {
60
- if (
61
- error.message === 'Spec ID required when multiple specs exist' &&
62
- !options.specId &&
63
- !options.spec
64
- ) {
65
- return null;
66
- }
67
- if (error.message.includes('No CAWS spec found')) {
68
- return null;
69
- }
70
- throw error;
71
- }
72
- }
73
-
74
- /**
75
- * Load specs from the new multi-spec system
76
- * @returns {Promise<Array>} Array of spec objects
77
- */
78
- async function loadSpecsFromMultiSpec() {
79
- const { listSpecFiles } = require('./specs');
80
-
81
- try {
82
- return await listSpecFiles();
83
- } catch (error) {
84
- return [];
85
- }
86
- }
87
-
88
- /**
89
- * Check Git hooks status
90
- * @returns {Promise<Object>} Hooks status
91
- */
92
- async function checkGitHooks() {
93
- const hooksDir = '.git/hooks';
94
-
95
- if (!(await fs.pathExists(hooksDir))) {
96
- return {
97
- installed: false,
98
- count: 0,
99
- active: [],
100
- };
101
- }
102
-
103
- const cawsHooks = ['pre-commit', 'post-commit', 'pre-push', 'commit-msg'];
104
- const activeHooks = [];
105
-
106
- for (const hook of cawsHooks) {
107
- const hookPath = path.join(hooksDir, hook);
108
- if (await fs.pathExists(hookPath)) {
109
- const content = await fs.readFile(hookPath, 'utf8');
110
- if (content.includes('CAWS')) {
111
- activeHooks.push(hook);
112
- }
113
- }
114
- }
115
-
116
- return {
117
- installed: activeHooks.length > 0,
118
- count: activeHooks.length,
119
- active: activeHooks,
120
- total: cawsHooks.length,
121
- };
122
- }
123
-
124
- /**
125
- * Load provenance chain
126
- * @returns {Promise<Object>} Provenance status
127
- */
128
- async function loadProvenanceChain() {
129
- const chainPath = '.caws/provenance/chain.json';
130
-
131
- if (!(await fs.pathExists(chainPath))) {
132
- return {
133
- exists: false,
134
- count: 0,
135
- lastUpdate: null,
136
- };
137
- }
138
-
139
- try {
140
- const chain = JSON.parse(await fs.readFile(chainPath, 'utf8'));
141
- const lastEntry = chain.length > 0 ? chain[chain.length - 1] : null;
142
-
143
- return {
144
- exists: true,
145
- count: chain.length,
146
- lastUpdate: lastEntry?.timestamp || null,
147
- lastCommit: lastEntry?.commit?.hash || null,
148
- };
149
- } catch (error) {
150
- return {
151
- exists: true,
152
- count: 0,
153
- lastUpdate: null,
154
- error: error.message,
155
- };
156
- }
157
- }
158
-
159
- /**
160
- * Load waiver status
161
- * @returns {Promise<Object>} Waiver status
162
- */
163
- async function loadWaiverStatus() {
164
- const waiversDir = '.caws/waivers';
165
-
166
- if (!(await fs.pathExists(waiversDir))) {
167
- return {
168
- exists: false,
169
- active: 0,
170
- expired: 0,
171
- revoked: 0,
172
- total: 0,
173
- };
174
- }
175
-
176
- try {
177
- const waiverFiles = await fs.readdir(waiversDir);
178
- const yamlFiles = waiverFiles.filter((f) => f.endsWith('.yaml'));
179
-
180
- let active = 0;
181
- let expired = 0;
182
- let revoked = 0;
183
-
184
- for (const file of yamlFiles) {
185
- const waiverPath = path.join(waiversDir, file);
186
- const content = await fs.readFile(waiverPath, 'utf8');
187
- const waiver = yaml.load(content);
188
-
189
- if (waiver.status === 'revoked') {
190
- revoked++;
191
- } else if (waiver.status === 'active') {
192
- const now = new Date();
193
- const expiresAt = new Date(waiver.expires_at);
194
- if (now > expiresAt) {
195
- expired++;
196
- } else {
197
- active++;
198
- }
199
- }
200
- }
201
-
202
- return {
203
- exists: true,
204
- active,
205
- expired,
206
- revoked,
207
- total: active + expired + revoked,
208
- };
209
- } catch (error) {
210
- return {
211
- exists: false,
212
- active: 0,
213
- expired: 0,
214
- revoked: 0,
215
- total: 0,
216
- error: error.message,
217
- };
218
- }
219
- }
220
-
221
- /**
222
- * Check quality gates status (simplified)
223
- * @returns {Promise<Object>} Quality gates status
224
- */
225
- async function checkQualityGates() {
226
- return {
227
- checked: false,
228
- message: 'Run: caws quality-gates for full gate status',
229
- };
230
- }
231
-
232
- /**
233
- * Get test coverage from coverage reports
234
- * Looks for common coverage report locations and formats
235
- * @returns {Promise<Object>} Coverage data with percentage and details
236
- */
237
- async function getTestCoverage() {
238
- const coverageLocations = [
239
- // Jest/Istanbul coverage
240
- { path: 'coverage/coverage-summary.json', type: 'istanbul' },
241
- { path: 'coverage/lcov-report/index.html', type: 'lcov-html' },
242
- { path: 'coverage/coverage-final.json', type: 'istanbul-final' },
243
- // NYC coverage
244
- { path: '.nyc_output/coverage-summary.json', type: 'nyc' },
245
- // C8 coverage
246
- { path: 'coverage/c8/coverage-summary.json', type: 'c8' },
247
- ];
248
-
249
- try {
250
- for (const loc of coverageLocations) {
251
- const coveragePath = path.join(process.cwd(), loc.path);
252
- if (await fs.pathExists(coveragePath)) {
253
- if (loc.type === 'istanbul' || loc.type === 'nyc' || loc.type === 'c8') {
254
- const content = await fs.readFile(coveragePath, 'utf8');
255
- const data = JSON.parse(content);
256
-
257
- // Istanbul/NYC format has a "total" key with coverage percentages
258
- if (data.total) {
259
- const lines = data.total.lines?.pct || 0;
260
- const statements = data.total.statements?.pct || 0;
261
- const branches = data.total.branches?.pct || 0;
262
- const functions = data.total.functions?.pct || 0;
263
-
264
- return {
265
- available: true,
266
- percentage: Math.round((lines + statements + branches + functions) / 4),
267
- lines: Math.round(lines),
268
- statements: Math.round(statements),
269
- branches: Math.round(branches),
270
- functions: Math.round(functions),
271
- source: loc.path,
272
- };
273
- }
274
- } else if (loc.type === 'istanbul-final') {
275
- // coverage-final.json has per-file data, need to aggregate
276
- const content = await fs.readFile(coveragePath, 'utf8');
277
- const data = JSON.parse(content);
278
-
279
- let totalStatements = 0;
280
- let coveredStatements = 0;
281
-
282
- for (const file of Object.values(data)) {
283
- const s = file.s || {};
284
- for (const count of Object.values(s)) {
285
- totalStatements++;
286
- if (count > 0) coveredStatements++;
287
- }
288
- }
289
-
290
- if (totalStatements > 0) {
291
- const percentage = Math.round((coveredStatements / totalStatements) * 100);
292
- return {
293
- available: true,
294
- percentage,
295
- source: loc.path,
296
- };
297
- }
298
- }
299
- }
300
- }
301
-
302
- // Try running test coverage command if no reports found
303
- try {
304
- // Check if package.json has a coverage script
305
- const pkgPath = path.join(process.cwd(), 'package.json');
306
- if (await fs.pathExists(pkgPath)) {
307
- const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'));
308
- if (pkg.scripts && (pkg.scripts.coverage || pkg.scripts['test:coverage'])) {
309
- return {
310
- available: false,
311
- percentage: null,
312
- message: 'Run npm run coverage to generate coverage report',
313
- };
314
- }
315
- }
316
- } catch {
317
- // Ignore package.json errors
318
- }
319
-
320
- return {
321
- available: false,
322
- percentage: null,
323
- message: 'No coverage report found',
324
- };
325
- } catch (error) {
326
- return {
327
- available: false,
328
- percentage: null,
329
- message: `Error reading coverage: ${error.message}`,
330
- };
331
- }
332
- }
333
-
334
- /**
335
- * Get time since last update
336
- * @param {string} timestamp - ISO timestamp
337
- * @returns {string} Human-readable time
338
- */
339
- function getTimeSince(timestamp) {
340
- if (!timestamp) return 'never';
341
-
342
- const now = new Date();
343
- const then = new Date(timestamp);
344
- const diffMs = now - then;
345
-
346
- const diffMins = Math.floor(diffMs / 60000);
347
- const diffHours = Math.floor(diffMs / 3600000);
348
- const diffDays = Math.floor(diffMs / 86400000);
349
-
350
- if (diffMins < 1) return 'just now';
351
- if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? 's' : ''} ago`;
352
- if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
353
- return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
354
- }
355
-
356
- /**
357
- * Display project status
358
- * @param {Object} data - Status data
359
- */
360
- function displayStatus(data) {
361
- const { spec, specSelection, hooks, provenance, waivers, gates } = data;
362
-
363
- console.log(chalk.bold.cyan('\nCAWS Project Status'));
364
- console.log(chalk.cyan('==============================================\n'));
365
-
366
- // Working Spec Status
367
- if (spec) {
368
- console.log(chalk.green('Working Spec'));
369
- console.log(chalk.gray(` ID: ${spec.id} | Tier: ${spec.risk_tier} | Mode: ${spec.mode}`));
370
- console.log(chalk.gray(` Title: ${spec.title}`));
371
- if (specSelection?.specType) {
372
- console.log(chalk.gray(` Source: ${specSelection.specType} (${specSelection.specPath})`));
373
- }
374
- } else {
375
- console.log(chalk.red('Working Spec'));
376
- console.log(chalk.gray(' No working spec found'));
377
- console.log(chalk.yellow(' Run: caws init . to create one'));
378
- }
379
-
380
- console.log('');
381
-
382
- // Working State (EVLOG-002: from event log)
383
- if (spec && spec.id) {
384
- let ws = null;
385
- try { ws = loadStateFromEvents(spec.id); } catch { /* non-fatal */ }
386
- if (ws && ws.phase !== 'not-started') {
387
- const phaseLabels = {
388
- 'not-started': 'Not Started',
389
- 'spec-authoring': 'Spec Authoring',
390
- 'implementation': 'Implementation',
391
- 'verification': 'Verification',
392
- 'complete': 'Complete',
393
- };
394
- console.log(chalk.green('Working State'));
395
- console.log(chalk.gray(` Phase: ${phaseLabels[ws.phase] || ws.phase}`));
396
- if (ws.validation) {
397
- const vIcon = ws.validation.passed ? chalk.green('pass') : chalk.red('fail');
398
- console.log(chalk.gray(` Validation: ${vIcon}${ws.validation.grade ? ` (Grade ${ws.validation.grade})` : ''}`));
399
- }
400
- if (ws.evaluation) {
401
- console.log(chalk.gray(` Evaluation: ${ws.evaluation.percentage}% (Grade ${ws.evaluation.grade})`));
402
- }
403
- if (ws.gates) {
404
- const gIcon = ws.gates.passed ? chalk.green('pass') : chalk.red('blocked');
405
- const s = ws.gates.summary;
406
- console.log(chalk.gray(` Gates: ${gIcon} (${s.passed} pass, ${s.blocked} blocked, ${s.warned} warned)`));
407
- }
408
- if (ws.acceptance_criteria) {
409
- const ac = ws.acceptance_criteria;
410
- console.log(chalk.gray(` ACs: ${ac.pass}/${ac.total} pass, ${ac.fail} fail, ${ac.unchecked} unchecked`));
411
- }
412
- if (ws.files_touched && ws.files_touched.length > 0) {
413
- console.log(chalk.gray(` Files touched: ${ws.files_touched.length}`));
414
- }
415
- if (ws.blockers && ws.blockers.length > 0) {
416
- console.log(chalk.red(` Blockers: ${ws.blockers.length}`));
417
- ws.blockers.forEach(b => console.log(chalk.red(` - ${b.message}`)));
418
- }
419
- console.log('');
420
- }
421
- }
422
-
423
- // Git Hooks Status
424
- if (hooks.installed) {
425
- console.log(chalk.green(`Git Hooks`));
426
- console.log(chalk.gray(` ${hooks.count}/${hooks.total} active: ${hooks.active.join(', ')}`));
427
- } else {
428
- console.log(chalk.yellow('Git Hooks'));
429
- console.log(chalk.gray(' No CAWS git hooks installed'));
430
- console.log(chalk.yellow(' Run: caws hooks install'));
431
- }
432
-
433
- console.log('');
434
-
435
- // Provenance Status
436
- if (provenance.exists) {
437
- console.log(chalk.green('Provenance'));
438
- console.log(chalk.gray(` Chain: ${provenance.count} entries`));
439
- if (provenance.lastUpdate) {
440
- console.log(chalk.gray(` Last update: ${getTimeSince(provenance.lastUpdate)}`));
441
- }
442
- } else {
443
- console.log(chalk.yellow('Provenance'));
444
- console.log(chalk.gray(' Provenance tracking not initialized'));
445
- console.log(chalk.yellow(' Run: caws provenance init'));
446
- }
447
-
448
- console.log('');
449
-
450
- // Waivers Status
451
- if (waivers.exists && waivers.total > 0) {
452
- console.log(chalk.green('Quality Gate Waivers'));
453
- console.log(
454
- chalk.gray(
455
- ` ${waivers.active} active, ${waivers.expired} expired, ${waivers.revoked} revoked`
456
- )
457
- );
458
- console.log(chalk.gray(` Total: ${waivers.total} waiver${waivers.total > 1 ? 's' : ''}`));
459
- } else if (waivers.exists) {
460
- console.log(chalk.blue('Quality Gate Waivers'));
461
- console.log(chalk.gray(' No waivers configured'));
462
- } else {
463
- console.log(chalk.yellow('Quality Gate Waivers'));
464
- console.log(chalk.gray(' Waiver system not initialized'));
465
- console.log(chalk.yellow(' Run: caws waivers create (when needed)'));
466
- }
467
-
468
- console.log('');
469
-
470
- // Quality Gates Status
471
- console.log(chalk.blue('Quality Gates'));
472
- console.log(chalk.gray(` ${gates.message}`));
473
-
474
- // Suggestions
475
- const suggestions = generateSuggestions(data);
476
- if (suggestions.length > 0) {
477
- console.log(chalk.bold.yellow('\nSuggestions:'));
478
- suggestions.forEach((suggestion) => {
479
- console.log(chalk.yellow(` ${suggestion}`));
480
- });
481
- }
482
-
483
- // Quick Links
484
- console.log(chalk.bold.blue('\nQuick Links:'));
485
- if (spec) {
486
- console.log(chalk.blue(' View spec: .caws/working-spec.yaml'));
487
- }
488
- if (hooks.installed) {
489
- console.log(chalk.blue(' View hooks: .git/hooks/'));
490
- }
491
- if (provenance.exists) {
492
- console.log(chalk.blue(' View provenance: caws provenance show --format=dashboard'));
493
- }
494
- if (waivers.exists && waivers.total > 0) {
495
- console.log(chalk.blue(' View waivers: caws waivers list'));
496
- }
497
- console.log(chalk.blue(' Full documentation: docs/agents/full-guide.md'));
498
-
499
- console.log('');
500
- }
501
-
502
- /**
503
- * Generate actionable suggestions based on status and mode
504
- * @param {Object} data - Status data
505
- * @param {string} currentMode - Current CAWS mode
506
- * @returns {string[]} Array of suggestions
507
- */
508
- function generateSuggestions(data, currentMode) {
509
- const { spec, specs, hooks, provenance, waivers } = data;
510
- const modes = require('../config/modes');
511
- const suggestions = [];
512
-
513
- // Basic setup suggestions
514
- if (!spec && (!specs || specs.length === 0)) {
515
- suggestions.push('Create a spec: caws specs create <id>');
516
- }
517
-
518
- // Mode-specific suggestions
519
- if (modes.isFeatureEnabled('gitHooks', currentMode) && !hooks.installed) {
520
- suggestions.push('Install Git hooks: caws hooks install');
521
- }
522
-
523
- if (modes.isFeatureEnabled('provenance', currentMode) && !provenance.exists) {
524
- suggestions.push('Initialize provenance tracking: caws provenance init');
525
- }
526
-
527
- if (modes.isFeatureEnabled('waivers', currentMode) && !waivers.exists) {
528
- suggestions.push('Initialize waiver system: caws waivers create (when needed)');
529
- }
530
-
531
- // Quality gate suggestions
532
- if (modes.isFeatureEnabled('qualityGates', currentMode)) {
533
- if (spec || (specs && specs.length > 0)) {
534
- suggestions.push('Run quality gates: caws diagnose');
535
- }
536
- }
537
-
538
- // Mode switching suggestion
539
- suggestions.push('Switch modes: caws mode set --interactive');
540
-
541
- return suggestions;
542
- }
543
-
544
- /**
545
- * Create progress bar string
546
- * @param {number} current - Current value
547
- * @param {number} total - Total value
548
- * @param {number} width - Bar width
549
- * @returns {string} Progress bar string
550
- */
551
- function createProgressBar(current, total, width = 20) {
552
- if (total === 0) return '░'.repeat(width);
553
-
554
- const percentage = Math.min(current / total, 1);
555
- const filled = Math.round(percentage * width);
556
- const empty = width - filled;
557
-
558
- return '▓'.repeat(filled) + '░'.repeat(empty);
559
- }
560
-
561
- /**
562
- * Get color for progress percentage
563
- * @param {number} percentage - Progress percentage
564
- * @returns {string} Chalk color function
565
- */
566
- function getProgressColor(percentage) {
567
- if (percentage >= 80) return chalk.green;
568
- if (percentage >= 50) return chalk.yellow;
569
- return chalk.red;
570
- }
571
-
572
- /**
573
- * Display enhanced visual status
574
- * @param {Object} data - Status data
575
- * @param {string} currentMode - Current CAWS mode
576
- */
577
- async function displayVisualStatus(data, currentMode) {
578
- const { spec, specs, hooks, provenance, waivers, gates } = data;
579
- const modes = require('../config/modes');
580
- const tierConfig = modes.getTier(currentMode);
581
-
582
- console.log(
583
- chalk.bold.cyan(
584
- `\nCAWS Project Status (${tierConfig.icon} ${tierConfig.color(currentMode)})`
585
- )
586
- );
587
- console.log(
588
- chalk.cyan(
589
- '=================================================================================\n'
590
- )
591
- );
592
-
593
- // Multi-spec system status
594
- if (specs && specs.length > 0) {
595
- console.log(chalk.green(`Specs System (${specs.length} specs)`));
596
-
597
- // Show active specs first
598
- const activeSpecs = specs.filter((s) => s.status === 'active' || s.status === 'in_progress');
599
- const draftSpecs = specs.filter((s) => s.status === 'draft');
600
- const completedSpecs = specs.filter((s) => s.status === 'completed');
601
- const closedSpecs = specs.filter((s) => s.status === 'closed' || s.status === 'archived');
602
-
603
- if (activeSpecs.length > 0) {
604
- console.log(
605
- chalk.gray(` Active: ${activeSpecs.map((s) => `${s.id}(${s.type})`).join(', ')}`)
606
- );
607
- }
608
- if (draftSpecs.length > 0) {
609
- console.log(
610
- chalk.gray(` Draft: ${draftSpecs.length} spec${draftSpecs.length > 1 ? 's' : ''}`)
611
- );
612
- // Show details for draft specs if not too many
613
- if (draftSpecs.length <= 3) {
614
- draftSpecs.forEach((s) => {
615
- console.log(chalk.gray(` - ${s.id}: ${s.title}`));
616
- });
617
- }
618
- }
619
- if (completedSpecs.length > 0) {
620
- console.log(
621
- chalk.gray(
622
- ` Completed: ${completedSpecs.length} spec${completedSpecs.length > 1 ? 's' : ''}`
623
- )
624
- );
625
- // Show details for completed specs if not too many
626
- if (completedSpecs.length <= 3) {
627
- completedSpecs.forEach((s) => {
628
- console.log(chalk.gray(` - ${s.id}: ${s.title}`));
629
- });
630
- }
631
- }
632
- if (closedSpecs.length > 0) {
633
- console.log(
634
- chalk.gray(
635
- ` Closed: ${closedSpecs.length} spec${closedSpecs.length > 1 ? 's' : ''}`
636
- )
637
- );
638
- }
639
-
640
- // Overall specs progress (completed + closed both count as done)
641
- const totalSpecs = specs.length;
642
- const completedSpecsCount = specs.filter((s) =>
643
- s.status === 'completed' || s.status === 'closed' || s.status === 'archived'
644
- ).length;
645
- const activeSpecsCount = specs.filter((s) => s.status === 'active').length;
646
- const progressPercentage =
647
- totalSpecs > 0 ? Math.round((completedSpecsCount / totalSpecs) * 100) : 0;
648
- const progressBar = createProgressBar(completedSpecsCount, totalSpecs);
649
- const color = getProgressColor(progressPercentage);
650
-
651
- console.log(
652
- chalk.gray(
653
- ` Overall Progress: ${color(`${progressPercentage}%`)} ${progressBar} ${completedSpecsCount}/${totalSpecs} completed`
654
- )
655
- );
656
-
657
- if (activeSpecsCount > 0) {
658
- console.log(chalk.gray(` Active Features: ${activeSpecsCount} in progress`));
659
- }
660
-
661
- // Show risk tier breakdown
662
- const riskBreakdown = {};
663
- specs.forEach((s) => {
664
- const tier = s.risk_tier || 'T3';
665
- riskBreakdown[tier] = (riskBreakdown[tier] || 0) + 1;
666
- });
667
-
668
- if (Object.keys(riskBreakdown).length > 1) {
669
- const tierDisplay = Object.entries(riskBreakdown)
670
- .map(([tier, count]) => `${tier}:${count}`)
671
- .join(', ');
672
- console.log(chalk.gray(` Risk Distribution: ${tierDisplay}`));
673
- }
674
- } else if (spec) {
675
- // Legacy single spec system
676
- console.log(chalk.green('Working Spec'));
677
- console.log(chalk.gray(` ID: ${spec.id} | Tier: ${spec.risk_tier} | Mode: ${spec.mode}`));
678
- console.log(chalk.gray(` Title: ${spec.title}`));
679
-
680
- // Acceptance Criteria Progress
681
- if (spec.acceptance_criteria && spec.acceptance_criteria.length > 0) {
682
- const total = spec.acceptance_criteria.length;
683
- const completed = spec.acceptance_criteria.filter((c) => c.completed).length;
684
- const percentage = Math.round((completed / total) * 100);
685
-
686
- const color = getProgressColor(percentage);
687
- const bar = createProgressBar(completed, total);
688
-
689
- console.log(
690
- chalk.gray(
691
- ` Acceptance Criteria: ${color(`${percentage}%`)} ${bar} ${completed}/${total}`
692
- )
693
- );
694
- }
695
-
696
- // Test Coverage
697
- const coverage = await getTestCoverage();
698
- if (coverage.available && coverage.percentage !== null) {
699
- const coverageColor =
700
- coverage.percentage >= 80
701
- ? chalk.green
702
- : coverage.percentage >= 50
703
- ? chalk.yellow
704
- : chalk.red;
705
- const coverageBar = createProgressBar(coverage.percentage, 100);
706
- console.log(
707
- chalk.gray(
708
- ` Test Coverage: ${coverageColor(`${coverage.percentage}%`)} ${coverageBar}`
709
- )
710
- );
711
- if (coverage.lines !== undefined) {
712
- console.log(
713
- chalk.gray(
714
- ` Lines: ${coverage.lines}% | Branches: ${coverage.branches}% | Functions: ${coverage.functions}%`
715
- )
716
- );
717
- }
718
- } else {
719
- console.log(
720
- chalk.gray(
721
- ` Test Coverage: ${chalk.yellow('N/A')} ${createProgressBar(0, 100)} ${chalk.gray(coverage.message || 'No report')}`
722
- )
723
- );
724
- }
725
-
726
- // Risk Tier Indicator
727
- const riskColor =
728
- spec.risk_tier === 'T1' ? chalk.red : spec.risk_tier === 'T2' ? chalk.yellow : chalk.green;
729
- console.log(
730
- chalk.gray(
731
- ` Risk Tier: ${riskColor(spec.risk_tier)} (Quality Gates: ${riskColor('Active')})`
732
- )
733
- );
734
- } else {
735
- console.log(chalk.red('No Specs Found'));
736
- console.log(chalk.gray(' No working spec or specs directory found'));
737
- console.log(chalk.yellow(' Run: caws specs create <id> to create specs'));
738
- console.log(chalk.yellow(' Or run: caws init . for legacy single spec'));
739
- }
740
-
741
- console.log('');
742
-
743
- // Git Hooks Status (only show in modes that support it)
744
- if (modes.isFeatureEnabled('gitHooks', currentMode)) {
745
- if (hooks.installed) {
746
- const hookBar = createProgressBar(hooks.count, hooks.total);
747
- console.log(chalk.green(`Git Hooks`));
748
- console.log(
749
- chalk.gray(` ${hookBar} ${hooks.count}/${hooks.total} active: ${hooks.active.join(', ')}`)
750
- );
751
- } else {
752
- console.log(chalk.yellow('Git Hooks'));
753
- console.log(chalk.gray(' No CAWS git hooks installed'));
754
- console.log(chalk.yellow(' Run: caws hooks install'));
755
- }
756
- }
757
-
758
- console.log('');
759
-
760
- // Provenance Status (only show in modes that support it)
761
- if (modes.isFeatureEnabled('provenance', currentMode)) {
762
- if (provenance.exists) {
763
- const provenanceBar = createProgressBar(provenance.count, Math.max(provenance.count, 10));
764
- console.log(chalk.green('Provenance'));
765
- console.log(chalk.gray(` ${provenanceBar} ${provenance.count} entries`));
766
- if (provenance.lastUpdate) {
767
- console.log(chalk.gray(` Last update: ${getTimeSince(provenance.lastUpdate)}`));
768
- }
769
- } else {
770
- console.log(chalk.yellow('Provenance'));
771
- console.log(chalk.gray(' Provenance tracking not initialized'));
772
- console.log(chalk.yellow(' Run: caws provenance init'));
773
- }
774
- }
775
-
776
- console.log('');
777
-
778
- // Waivers Status (only show in modes that support it)
779
- if (modes.isFeatureEnabled('waivers', currentMode)) {
780
- if (waivers.exists && waivers.total > 0) {
781
- const waiverBar = createProgressBar(waivers.active, waivers.total);
782
- console.log(chalk.green('Quality Gate Waivers'));
783
- console.log(
784
- chalk.gray(
785
- ` ${waiverBar} ${waivers.active} active, ${waivers.expired} expired, ${waivers.revoked} revoked`
786
- )
787
- );
788
- console.log(chalk.gray(` Total: ${waivers.total} waiver${waivers.total > 1 ? 's' : ''}`));
789
- } else if (waivers.exists) {
790
- console.log(chalk.blue('Quality Gate Waivers'));
791
- console.log(chalk.gray(' No waivers configured'));
792
- } else {
793
- console.log(chalk.yellow('Quality Gate Waivers'));
794
- console.log(chalk.gray(' Waiver system not initialized'));
795
- console.log(chalk.yellow(' Run: caws waivers create (when needed)'));
796
- }
797
- }
798
-
799
- console.log('');
800
-
801
- // Quality Gates Status (only show in modes that support it)
802
- if (modes.isFeatureEnabled('qualityGates', currentMode)) {
803
- console.log(chalk.blue('Quality Gates'));
804
- if (gates.checked) {
805
- if (gates.passed) {
806
- console.log(chalk.green(` ${createProgressBar(1, 1)} All gates passed`));
807
- gates.results?.forEach((gate) => {
808
- const gateStatus = gate.status === 'passed' ? chalk.green('[pass]') : chalk.red('[fail]');
809
- console.log(chalk.gray(` ${gateStatus} ${gate.name}: ${gate.message || 'OK'}`));
810
- });
811
- } else {
812
- console.log(
813
- chalk.red(
814
- ` ${createProgressBar(0, gates.results?.length || 1)} ${gates.failed || 0} gates failed`
815
- )
816
- );
817
- gates.results?.forEach((gate) => {
818
- const gateStatus = gate.status === 'passed' ? chalk.green('[pass]') : chalk.red('[fail]');
819
- console.log(chalk.gray(` ${gateStatus} ${gate.name}: ${gate.message || 'Failed'}`));
820
- });
821
- }
822
- } else {
823
- console.log(chalk.gray(` ${gates.message}`));
824
- }
825
- }
826
-
827
- // Progress Summary
828
- const overallProgress = calculateOverallProgress(data);
829
- const progressColor = getProgressColor(overallProgress);
830
- const progressBar = createProgressBar(overallProgress, 100);
831
-
832
- console.log('');
833
- console.log(chalk.bold.blue('Overall Progress'));
834
- console.log(chalk.gray(` ${progressBar} ${progressColor(`${overallProgress}%`)} complete`));
835
-
836
- // Suggestions (mode-aware)
837
- const suggestions = generateSuggestions(data, currentMode);
838
- if (suggestions.length > 0) {
839
- console.log(chalk.bold.yellow('\nNext Steps:'));
840
- suggestions.forEach((suggestion, index) => {
841
- console.log(chalk.yellow(` ${index + 1}. ${suggestion}`));
842
- });
843
- }
844
-
845
- // Quick Links (mode-aware)
846
- console.log(chalk.bold.blue('\nQuick Actions:'));
847
- if (spec || (specs && specs.length > 0)) {
848
- if (modes.isFeatureEnabled('validate', currentMode)) {
849
- console.log(chalk.blue(' View specs: caws specs list'));
850
- }
851
- if (modes.isFeatureEnabled('validate', currentMode)) {
852
- console.log(chalk.blue(' Validate: caws validate'));
853
- }
854
- }
855
-
856
- if (modes.isFeatureEnabled('gitHooks', currentMode) && hooks.installed) {
857
- console.log(chalk.blue(' View hooks: caws hooks status'));
858
- }
859
-
860
- if (modes.isFeatureEnabled('provenance', currentMode) && provenance.exists) {
861
- console.log(chalk.blue(' View provenance: caws provenance show'));
862
- }
863
-
864
- if (modes.isFeatureEnabled('waivers', currentMode) && waivers.exists && waivers.total > 0) {
865
- console.log(chalk.blue(' View waivers: caws waivers list'));
866
- }
867
-
868
- console.log(chalk.blue(' Get help: caws help'));
869
- console.log(chalk.blue(' Switch mode: caws mode set --interactive'));
870
-
871
- console.log('');
872
- }
873
-
874
- /**
875
- * Calculate overall project progress (mode-aware)
876
- * @param {Object} data - Status data
877
- * @returns {number} Overall progress percentage
878
- */
879
- function calculateOverallProgress(data) {
880
- const { spec, specs, hooks, provenance, waivers, currentMode } = data;
881
- const modes = require('../config/modes');
882
-
883
- let score = 0;
884
-
885
- // Multi-spec system
886
- if (specs && specs.length > 0) {
887
- // Specs system (40%)
888
- const completedSpecs = specs.filter((s) => s.status === 'completed').length;
889
- if (specs.length > 0) {
890
- const percentage = (completedSpecs / specs.length) * 40;
891
- score += percentage;
892
- }
893
-
894
- // Git hooks (20%) - only if enabled in mode
895
- if (modes.isFeatureEnabled('gitHooks', currentMode)) {
896
- if (hooks.installed) score += 20;
897
- }
898
-
899
- // Provenance (20%) - only if enabled in mode
900
- if (modes.isFeatureEnabled('provenance', currentMode)) {
901
- if (provenance.exists) score += 20;
902
- }
903
-
904
- // Waivers (15%) - only if enabled in mode
905
- if (modes.isFeatureEnabled('waivers', currentMode)) {
906
- if (waivers.exists) score += 15;
907
- }
908
-
909
- // Quality gates (5%) - only if enabled in mode
910
- if (modes.isFeatureEnabled('qualityGates', currentMode)) {
911
- if (specs.length > 0) score += 5;
912
- }
913
- } else if (spec) {
914
- // Legacy single spec system (30%)
915
- if (spec) score += 30;
916
-
917
- // Acceptance criteria progress (25%)
918
- if (spec && spec.acceptance_criteria && spec.acceptance_criteria.length > 0) {
919
- const completed = spec.acceptance_criteria.filter((c) => c.completed).length;
920
- const percentage = (completed / spec.acceptance_criteria.length) * 25;
921
- score += percentage;
922
- }
923
-
924
- // Git hooks (15%) - only if enabled in mode
925
- if (modes.isFeatureEnabled('gitHooks', currentMode)) {
926
- if (hooks.installed) score += 15;
927
- }
928
-
929
- // Provenance (15%) - only if enabled in mode
930
- if (modes.isFeatureEnabled('provenance', currentMode)) {
931
- if (provenance.exists) score += 15;
932
- }
933
-
934
- // Waivers (10%) - only if enabled in mode
935
- if (modes.isFeatureEnabled('waivers', currentMode)) {
936
- if (waivers.exists) score += 10;
937
- }
938
-
939
- // Quality gates (5%) - only if enabled in mode
940
- if (modes.isFeatureEnabled('qualityGates', currentMode)) {
941
- if (spec) score += 5;
942
- }
943
- } else {
944
- // No specs system - check basic setup (mode-aware)
945
-
946
- // Git hooks (30%) - only if enabled in mode
947
- if (modes.isFeatureEnabled('gitHooks', currentMode)) {
948
- if (hooks.installed) score += 30;
949
- }
950
-
951
- // Provenance (30%) - only if enabled in mode
952
- if (modes.isFeatureEnabled('provenance', currentMode)) {
953
- if (provenance.exists) score += 30;
954
- }
955
-
956
- // Waivers (20%) - only if enabled in mode
957
- if (modes.isFeatureEnabled('waivers', currentMode)) {
958
- if (waivers.exists) score += 20;
959
- }
960
-
961
- // Quality gates (20%) - only if enabled in mode
962
- if (modes.isFeatureEnabled('qualityGates', currentMode)) {
963
- if (hooks.installed || provenance.exists) score += 20;
964
- }
965
- }
966
-
967
- return Math.min(Math.round(score), 100);
968
- }
969
-
970
- /**
971
- * Status command handler
972
- * @param {Object} options - Command options
973
- */
974
- async function statusCommand(options = {}) {
975
- return safeAsync(
976
- async () => {
977
- // Check current mode and adjust behavior accordingly
978
- const modes = require('../config/modes');
979
- const currentMode = await modes.getCurrentMode();
980
-
981
- // Load all status data in parallel for better performance
982
- const [resolvedSpec, specs, hooks, provenance, waivers, gates] = await parallel([
983
- loadResolvedStatusSpec(options),
984
- loadSpecsFromMultiSpec(),
985
- checkGitHooks(),
986
- loadProvenanceChain(),
987
- loadWaiverStatus(),
988
- checkQualityGates(),
989
- ]);
990
- const spec = resolvedSpec?.spec || null;
991
- const specSelection = resolvedSpec
992
- ? {
993
- specPath: resolvedSpec.path
994
- ? path.relative(process.cwd(), resolvedSpec.path)
995
- : null,
996
- specType: resolvedSpec.type,
997
- }
998
- : null;
999
-
1000
- // Display status (visual mode if requested)
1001
- if (options.visual || options.json) {
1002
- if (options.json) {
1003
- // JSON output for automation
1004
- const result = {
1005
- command: 'status',
1006
- timestamp: new Date().toISOString(),
1007
- system: specs.length > 0 ? 'multi-spec' : 'single-spec',
1008
- specs:
1009
- specs.length > 0
1010
- ? {
1011
- count: specs.length,
1012
- active: specs.filter((s) => s.status === 'active').length,
1013
- draft: specs.filter((s) => s.status === 'draft').length,
1014
- completed: specs.filter((s) => s.status === 'completed').length,
1015
- list: specs.map((s) => ({
1016
- id: s.id,
1017
- type: s.type,
1018
- status: s.status,
1019
- title: s.title,
1020
- })),
1021
- }
1022
- : null,
1023
- legacySpec: spec
1024
- ? {
1025
- id: spec.id,
1026
- title: spec.title,
1027
- riskTier: spec.risk_tier,
1028
- mode: spec.mode,
1029
- specType: specSelection?.specType || null,
1030
- specPath: specSelection?.specPath || null,
1031
- acceptanceCriteria: spec.acceptance_criteria?.length || 0,
1032
- completedCriteria:
1033
- spec.acceptance_criteria?.filter((c) => c.completed).length || 0,
1034
- }
1035
- : null,
1036
- hooks: {
1037
- installed: hooks.installed,
1038
- count: hooks.count,
1039
- total: hooks.total,
1040
- active: hooks.active,
1041
- },
1042
- provenance: {
1043
- exists: provenance.exists,
1044
- count: provenance.count,
1045
- lastUpdate: provenance.lastUpdate,
1046
- },
1047
- waivers: {
1048
- exists: waivers.exists,
1049
- active: waivers.active,
1050
- expired: waivers.expired,
1051
- revoked: waivers.revoked,
1052
- total: waivers.total,
1053
- },
1054
- qualityGates: {
1055
- checked: gates.checked,
1056
- passed: gates.passed,
1057
- message: gates.message,
1058
- },
1059
- workingState: spec && spec.id ? (loadStateFromEvents(spec.id) || null) : null,
1060
- overallProgress: calculateOverallProgress({
1061
- spec,
1062
- specSelection,
1063
- specs,
1064
- hooks,
1065
- provenance,
1066
- waivers,
1067
- gates,
1068
- }),
1069
- };
1070
-
1071
- console.log(JSON.stringify(result, null, 2));
1072
- return result;
1073
- } else {
1074
- // Visual output
1075
- await displayVisualStatus(
1076
- {
1077
- spec,
1078
- specs,
1079
- hooks,
1080
- provenance,
1081
- waivers,
1082
- gates,
1083
- },
1084
- currentMode
1085
- );
1086
- }
1087
- } else {
1088
- // Original text-based output
1089
- displayStatus({
1090
- spec,
1091
- specSelection,
1092
- hooks,
1093
- provenance,
1094
- waivers,
1095
- gates,
1096
- });
1097
- }
1098
-
1099
- if (options.json) {
1100
- return {
1101
- command: 'status',
1102
- mode: 'json',
1103
- };
1104
- }
1105
-
1106
- const result = outputResult({
1107
- command: 'status',
1108
- mode: options.visual ? 'visual' : options.json ? 'json' : 'text',
1109
- system: specs.length > 0 ? 'multi-spec' : 'single-spec',
1110
- currentMode: currentMode,
1111
- specs: specs.length,
1112
- legacySpec: spec ? 'loaded' : 'not found',
1113
- hooks: modes.isFeatureEnabled('gitHooks', currentMode) ? hooks.installed : null,
1114
- provenance: modes.isFeatureEnabled('provenance', currentMode)
1115
- ? provenance.count || 0
1116
- : null,
1117
- waivers: modes.isFeatureEnabled('waivers', currentMode) ? waivers.active || 0 : null,
1118
- gates: modes.isFeatureEnabled('qualityGates', currentMode)
1119
- ? gates.passed
1120
- ? 'passed'
1121
- : 'failed'
1122
- : null,
1123
- overallProgress: calculateOverallProgress({
1124
- spec,
1125
- specs,
1126
- hooks,
1127
- provenance,
1128
- waivers,
1129
- gates,
1130
- currentMode,
1131
- }),
1132
- });
1133
-
1134
- return result;
1135
- },
1136
- 'status check',
1137
- !options.json
1138
- );
1139
- }
1140
-
1141
- module.exports = {
1142
- statusCommand,
1143
- loadWorkingSpec,
1144
- loadResolvedStatusSpec,
1145
- checkGitHooks,
1146
- loadProvenanceChain,
1147
- loadWaiverStatus,
1148
- checkQualityGates,
1149
- displayStatus,
1150
- generateSuggestions,
1151
- };