@paths.design/caws-cli 10.2.0 → 11.1.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 (493) hide show
  1. package/README.md +125 -374
  2. package/dist/index.js +45 -787
  3. package/dist/init/harness-detect.d.ts +18 -0
  4. package/dist/init/harness-detect.d.ts.map +1 -0
  5. package/dist/init/harness-detect.js +90 -0
  6. package/dist/init/harness-detect.js.map +1 -0
  7. package/dist/init/hook-install.d.ts +53 -0
  8. package/dist/init/hook-install.d.ts.map +1 -0
  9. package/dist/init/hook-install.js +421 -0
  10. package/dist/init/hook-install.js.map +1 -0
  11. package/dist/init/hook-packs/manifest-claude-code.d.ts +4 -0
  12. package/dist/init/hook-packs/manifest-claude-code.d.ts.map +1 -0
  13. package/dist/init/hook-packs/manifest-claude-code.js +190 -0
  14. package/dist/init/hook-packs/manifest-claude-code.js.map +1 -0
  15. package/dist/init/hook-packs/register.d.ts +19 -0
  16. package/dist/init/hook-packs/register.d.ts.map +1 -0
  17. package/dist/init/hook-packs/register.js +37 -0
  18. package/dist/init/hook-packs/register.js.map +1 -0
  19. package/dist/init/hook-packs/types.d.ts +123 -0
  20. package/dist/init/hook-packs/types.d.ts.map +1 -0
  21. package/dist/init/hook-packs/types.js +29 -0
  22. package/dist/init/hook-packs/types.js.map +1 -0
  23. package/dist/shell/binding/resolve-binding.d.ts +4 -0
  24. package/dist/shell/binding/resolve-binding.d.ts.map +1 -0
  25. package/dist/shell/binding/resolve-binding.js +228 -0
  26. package/dist/shell/binding/resolve-binding.js.map +1 -0
  27. package/dist/shell/binding/types.d.ts +42 -0
  28. package/dist/shell/binding/types.d.ts.map +1 -0
  29. package/dist/shell/binding/types.js +21 -0
  30. package/dist/shell/binding/types.js.map +1 -0
  31. package/dist/shell/commands/claim.d.ts +14 -0
  32. package/dist/shell/commands/claim.d.ts.map +1 -0
  33. package/dist/shell/commands/claim.js +197 -0
  34. package/dist/shell/commands/claim.js.map +1 -0
  35. package/dist/shell/commands/doctor.d.ts +13 -0
  36. package/dist/shell/commands/doctor.d.ts.map +1 -0
  37. package/dist/shell/commands/doctor.js +97 -0
  38. package/dist/shell/commands/doctor.js.map +1 -0
  39. package/dist/shell/commands/evidence.d.ts +28 -0
  40. package/dist/shell/commands/evidence.d.ts.map +1 -0
  41. package/dist/shell/commands/evidence.js +166 -0
  42. package/dist/shell/commands/evidence.js.map +1 -0
  43. package/dist/shell/commands/gates.d.ts +19 -0
  44. package/dist/shell/commands/gates.d.ts.map +1 -0
  45. package/dist/shell/commands/gates.js +208 -0
  46. package/dist/shell/commands/gates.js.map +1 -0
  47. package/dist/shell/commands/init.d.ts +17 -0
  48. package/dist/shell/commands/init.d.ts.map +1 -0
  49. package/dist/shell/commands/init.js +168 -0
  50. package/dist/shell/commands/init.js.map +1 -0
  51. package/dist/shell/commands/scope.d.ts +11 -0
  52. package/dist/shell/commands/scope.d.ts.map +1 -0
  53. package/dist/shell/commands/scope.js +92 -0
  54. package/dist/shell/commands/scope.js.map +1 -0
  55. package/dist/shell/commands/specs.d.ts +41 -0
  56. package/dist/shell/commands/specs.d.ts.map +1 -0
  57. package/dist/shell/commands/specs.js +264 -0
  58. package/dist/shell/commands/specs.js.map +1 -0
  59. package/dist/shell/commands/status.d.ts +15 -0
  60. package/dist/shell/commands/status.d.ts.map +1 -0
  61. package/dist/shell/commands/status.js +106 -0
  62. package/dist/shell/commands/status.js.map +1 -0
  63. package/dist/shell/commands/waiver.d.ts +38 -0
  64. package/dist/shell/commands/waiver.d.ts.map +1 -0
  65. package/dist/shell/commands/waiver.js +240 -0
  66. package/dist/shell/commands/waiver.js.map +1 -0
  67. package/dist/shell/commands/worktree.d.ts +38 -0
  68. package/dist/shell/commands/worktree.d.ts.map +1 -0
  69. package/dist/shell/commands/worktree.js +286 -0
  70. package/dist/shell/commands/worktree.js.map +1 -0
  71. package/dist/shell/gates/disposition.d.ts +23 -0
  72. package/dist/shell/gates/disposition.d.ts.map +1 -0
  73. package/dist/shell/gates/disposition.js +117 -0
  74. package/dist/shell/gates/disposition.js.map +1 -0
  75. package/dist/shell/gates/gate-result-contract.d.ts +39 -0
  76. package/dist/shell/gates/gate-result-contract.d.ts.map +1 -0
  77. package/dist/shell/gates/gate-result-contract.js +150 -0
  78. package/dist/shell/gates/gate-result-contract.js.map +1 -0
  79. package/dist/shell/gates/local-evaluators/budget-limit.d.ts +24 -0
  80. package/dist/shell/gates/local-evaluators/budget-limit.d.ts.map +1 -0
  81. package/dist/shell/gates/local-evaluators/budget-limit.js +67 -0
  82. package/dist/shell/gates/local-evaluators/budget-limit.js.map +1 -0
  83. package/dist/shell/gates/local-evaluators/diff-helpers.d.ts +25 -0
  84. package/dist/shell/gates/local-evaluators/diff-helpers.d.ts.map +1 -0
  85. package/dist/shell/gates/local-evaluators/diff-helpers.js +74 -0
  86. package/dist/shell/gates/local-evaluators/diff-helpers.js.map +1 -0
  87. package/dist/shell/gates/local-evaluators/index.d.ts +28 -0
  88. package/dist/shell/gates/local-evaluators/index.d.ts.map +1 -0
  89. package/dist/shell/gates/local-evaluators/index.js +67 -0
  90. package/dist/shell/gates/local-evaluators/index.js.map +1 -0
  91. package/dist/shell/gates/local-evaluators/scope-boundary.d.ts +23 -0
  92. package/dist/shell/gates/local-evaluators/scope-boundary.d.ts.map +1 -0
  93. package/dist/shell/gates/local-evaluators/scope-boundary.js +67 -0
  94. package/dist/shell/gates/local-evaluators/scope-boundary.js.map +1 -0
  95. package/dist/shell/gates/local-evaluators/spec-completeness.d.ts +12 -0
  96. package/dist/shell/gates/local-evaluators/spec-completeness.d.ts.map +1 -0
  97. package/dist/shell/gates/local-evaluators/spec-completeness.js +73 -0
  98. package/dist/shell/gates/local-evaluators/spec-completeness.js.map +1 -0
  99. package/dist/shell/gates/quality-gates-adapter.d.ts +55 -0
  100. package/dist/shell/gates/quality-gates-adapter.d.ts.map +1 -0
  101. package/dist/shell/gates/quality-gates-adapter.js +161 -0
  102. package/dist/shell/gates/quality-gates-adapter.js.map +1 -0
  103. package/dist/shell/gates/waiver-filter.d.ts +58 -0
  104. package/dist/shell/gates/waiver-filter.d.ts.map +1 -0
  105. package/dist/shell/gates/waiver-filter.js +119 -0
  106. package/dist/shell/gates/waiver-filter.js.map +1 -0
  107. package/dist/shell/index.d.ts +54 -0
  108. package/dist/shell/index.d.ts.map +1 -0
  109. package/dist/shell/index.js +85 -0
  110. package/dist/shell/index.js.map +1 -0
  111. package/dist/shell/register.d.ts +11 -0
  112. package/dist/shell/register.d.ts.map +1 -0
  113. package/dist/shell/register.js +464 -0
  114. package/dist/shell/register.js.map +1 -0
  115. package/dist/shell/render/claim.d.ts +22 -0
  116. package/dist/shell/render/claim.d.ts.map +1 -0
  117. package/dist/shell/render/claim.js +75 -0
  118. package/dist/shell/render/claim.js.map +1 -0
  119. package/dist/shell/render/decision.d.ts +15 -0
  120. package/dist/shell/render/decision.d.ts.map +1 -0
  121. package/dist/shell/render/decision.js +66 -0
  122. package/dist/shell/render/decision.js.map +1 -0
  123. package/dist/shell/render/diagnostic.d.ts +19 -0
  124. package/dist/shell/render/diagnostic.d.ts.map +1 -0
  125. package/dist/shell/render/diagnostic.js +76 -0
  126. package/dist/shell/render/diagnostic.js.map +1 -0
  127. package/dist/shell/render/finding.d.ts +15 -0
  128. package/dist/shell/render/finding.d.ts.map +1 -0
  129. package/dist/shell/render/finding.js +57 -0
  130. package/dist/shell/render/finding.js.map +1 -0
  131. package/dist/shell/render/gates.d.ts +3 -0
  132. package/dist/shell/render/gates.d.ts.map +1 -0
  133. package/dist/shell/render/gates.js +56 -0
  134. package/dist/shell/render/gates.js.map +1 -0
  135. package/dist/shell/render/init-hook-pack.d.ts +16 -0
  136. package/dist/shell/render/init-hook-pack.d.ts.map +1 -0
  137. package/dist/shell/render/init-hook-pack.js +206 -0
  138. package/dist/shell/render/init-hook-pack.js.map +1 -0
  139. package/dist/shell/render/init.d.ts +11 -0
  140. package/dist/shell/render/init.d.ts.map +1 -0
  141. package/dist/shell/render/init.js +32 -0
  142. package/dist/shell/render/init.js.map +1 -0
  143. package/dist/shell/render/status.d.ts +26 -0
  144. package/dist/shell/render/status.d.ts.map +1 -0
  145. package/dist/shell/render/status.js +143 -0
  146. package/dist/shell/render/status.js.map +1 -0
  147. package/dist/shell/render/waiver.d.ts +21 -0
  148. package/dist/shell/render/waiver.d.ts.map +1 -0
  149. package/dist/shell/render/waiver.js +94 -0
  150. package/dist/shell/render/waiver.js.map +1 -0
  151. package/dist/shell/rules.d.ts +37 -0
  152. package/dist/shell/rules.d.ts.map +1 -0
  153. package/dist/shell/rules.js +51 -0
  154. package/dist/shell/rules.js.map +1 -0
  155. package/dist/shell/session/actor.d.ts +14 -0
  156. package/dist/shell/session/actor.d.ts.map +1 -0
  157. package/dist/shell/session/actor.js +34 -0
  158. package/dist/shell/session/actor.js.map +1 -0
  159. package/dist/shell/session/resolve-session.d.ts +5 -0
  160. package/dist/shell/session/resolve-session.d.ts.map +1 -0
  161. package/dist/shell/session/resolve-session.js +239 -0
  162. package/dist/shell/session/resolve-session.js.map +1 -0
  163. package/dist/shell/session/types.d.ts +56 -0
  164. package/dist/shell/session/types.d.ts.map +1 -0
  165. package/dist/shell/session/types.js +15 -0
  166. package/dist/shell/session/types.js.map +1 -0
  167. package/dist/store/agents-store.d.ts +3 -0
  168. package/dist/store/agents-store.d.ts.map +1 -0
  169. package/dist/store/agents-store.js +63 -0
  170. package/dist/store/agents-store.js.map +1 -0
  171. package/dist/store/apply-patch.d.ts +16 -0
  172. package/dist/store/apply-patch.d.ts.map +1 -0
  173. package/dist/store/apply-patch.js +191 -0
  174. package/dist/store/apply-patch.js.map +1 -0
  175. package/dist/store/atomic-write.d.ts +34 -0
  176. package/dist/store/atomic-write.d.ts.map +1 -0
  177. package/dist/store/atomic-write.js +174 -0
  178. package/dist/store/atomic-write.js.map +1 -0
  179. package/dist/store/doctor-snapshot.d.ts +20 -0
  180. package/dist/store/doctor-snapshot.d.ts.map +1 -0
  181. package/dist/store/doctor-snapshot.js +176 -0
  182. package/dist/store/doctor-snapshot.js.map +1 -0
  183. package/dist/store/events-store.d.ts +33 -0
  184. package/dist/store/events-store.d.ts.map +1 -0
  185. package/dist/store/events-store.js +297 -0
  186. package/dist/store/events-store.js.map +1 -0
  187. package/dist/store/index.d.ts +21 -0
  188. package/dist/store/index.d.ts.map +1 -0
  189. package/dist/store/index.js +47 -0
  190. package/dist/store/index.js.map +1 -0
  191. package/dist/store/init-store.d.ts +21 -0
  192. package/dist/store/init-store.d.ts.map +1 -0
  193. package/dist/store/init-store.js +295 -0
  194. package/dist/store/init-store.js.map +1 -0
  195. package/dist/store/json-store.d.ts +3 -0
  196. package/dist/store/json-store.d.ts.map +1 -0
  197. package/dist/store/json-store.js +65 -0
  198. package/dist/store/json-store.js.map +1 -0
  199. package/dist/store/lifecycle-lock.d.ts +34 -0
  200. package/dist/store/lifecycle-lock.d.ts.map +1 -0
  201. package/dist/store/lifecycle-lock.js +168 -0
  202. package/dist/store/lifecycle-lock.js.map +1 -0
  203. package/dist/store/lifecycle-transaction.d.ts +79 -0
  204. package/dist/store/lifecycle-transaction.d.ts.map +1 -0
  205. package/dist/store/lifecycle-transaction.js +319 -0
  206. package/dist/store/lifecycle-transaction.js.map +1 -0
  207. package/dist/store/policy-store.d.ts +3 -0
  208. package/dist/store/policy-store.d.ts.map +1 -0
  209. package/dist/store/policy-store.js +65 -0
  210. package/dist/store/policy-store.js.map +1 -0
  211. package/dist/store/repo-root.d.ts +46 -0
  212. package/dist/store/repo-root.d.ts.map +1 -0
  213. package/dist/store/repo-root.js +145 -0
  214. package/dist/store/repo-root.js.map +1 -0
  215. package/dist/store/rules.d.ts +69 -0
  216. package/dist/store/rules.d.ts.map +1 -0
  217. package/dist/store/rules.js +95 -0
  218. package/dist/store/rules.js.map +1 -0
  219. package/dist/store/specs-store.d.ts +3 -0
  220. package/dist/store/specs-store.d.ts.map +1 -0
  221. package/dist/store/specs-store.js +131 -0
  222. package/dist/store/specs-store.js.map +1 -0
  223. package/dist/store/specs-writer.d.ts +61 -0
  224. package/dist/store/specs-writer.d.ts.map +1 -0
  225. package/dist/store/specs-writer.js +506 -0
  226. package/dist/store/specs-writer.js.map +1 -0
  227. package/dist/store/types.d.ts +84 -0
  228. package/dist/store/types.d.ts.map +1 -0
  229. package/dist/store/types.js +14 -0
  230. package/dist/store/types.js.map +1 -0
  231. package/dist/store/waivers-store.d.ts +25 -0
  232. package/dist/store/waivers-store.d.ts.map +1 -0
  233. package/dist/store/waivers-store.js +232 -0
  234. package/dist/store/waivers-store.js.map +1 -0
  235. package/dist/store/worktrees-store.d.ts +3 -0
  236. package/dist/store/worktrees-store.d.ts.map +1 -0
  237. package/dist/store/worktrees-store.js +62 -0
  238. package/dist/store/worktrees-store.js.map +1 -0
  239. package/dist/store/worktrees-writer.d.ts +77 -0
  240. package/dist/store/worktrees-writer.d.ts.map +1 -0
  241. package/dist/store/worktrees-writer.js +674 -0
  242. package/dist/store/worktrees-writer.js.map +1 -0
  243. package/dist/store/yaml-patch.d.ts +7 -0
  244. package/dist/store/yaml-patch.d.ts.map +1 -0
  245. package/dist/store/yaml-patch.js +250 -0
  246. package/dist/store/yaml-patch.js.map +1 -0
  247. package/dist/store/yaml-store.d.ts +9 -0
  248. package/dist/store/yaml-store.d.ts.map +1 -0
  249. package/dist/store/yaml-store.js +121 -0
  250. package/dist/store/yaml-store.js.map +1 -0
  251. package/package.json +15 -13
  252. package/dist/budget-derivation.js +0 -751
  253. package/dist/cicd-optimizer.js +0 -504
  254. package/dist/commands/agents.js +0 -124
  255. package/dist/commands/archive.js +0 -500
  256. package/dist/commands/burnup.js +0 -198
  257. package/dist/commands/diagnose.js +0 -525
  258. package/dist/commands/evaluate.js +0 -314
  259. package/dist/commands/gates.js +0 -149
  260. package/dist/commands/init.js +0 -857
  261. package/dist/commands/iterate.js +0 -417
  262. package/dist/commands/mode.js +0 -269
  263. package/dist/commands/parallel.js +0 -242
  264. package/dist/commands/plan.js +0 -438
  265. package/dist/commands/provenance.js +0 -1143
  266. package/dist/commands/quality-monitor.js +0 -284
  267. package/dist/commands/scope.js +0 -264
  268. package/dist/commands/session.js +0 -312
  269. package/dist/commands/sidecar.js +0 -74
  270. package/dist/commands/specs.js +0 -1656
  271. package/dist/commands/status.js +0 -1172
  272. package/dist/commands/templates.js +0 -237
  273. package/dist/commands/tool.js +0 -136
  274. package/dist/commands/tutorial.js +0 -480
  275. package/dist/commands/validate.js +0 -357
  276. package/dist/commands/verify-acs.js +0 -443
  277. package/dist/commands/waivers.js +0 -599
  278. package/dist/commands/workflow.js +0 -243
  279. package/dist/commands/worktree.js +0 -502
  280. package/dist/config/lite-scope.js +0 -158
  281. package/dist/config/modes.js +0 -347
  282. package/dist/constants/spec-types.js +0 -65
  283. package/dist/gates/budget-limit.js +0 -121
  284. package/dist/gates/feedback.js +0 -260
  285. package/dist/gates/format.js +0 -179
  286. package/dist/gates/god-object.js +0 -117
  287. package/dist/gates/pipeline.js +0 -167
  288. package/dist/gates/scope-boundary.js +0 -112
  289. package/dist/gates/spec-completeness.js +0 -109
  290. package/dist/gates/todo-detection.js +0 -205
  291. package/dist/generators/jest-config-generator.js +0 -242
  292. package/dist/generators/working-spec.js +0 -237
  293. package/dist/minimal-cli.js +0 -88
  294. package/dist/parallel/parallel-manager.js +0 -433
  295. package/dist/policy/PolicyManager.js +0 -470
  296. package/dist/scaffold/claude-hooks.js +0 -443
  297. package/dist/scaffold/cursor-hooks.js +0 -177
  298. package/dist/scaffold/git-hooks.js +0 -928
  299. package/dist/scaffold/index.js +0 -794
  300. package/dist/session/session-manager.js +0 -653
  301. package/dist/sidecars/index.js +0 -33
  302. package/dist/sidecars/listeners.js +0 -40
  303. package/dist/sidecars/provenance-summary.js +0 -238
  304. package/dist/sidecars/quality-gaps.js +0 -258
  305. package/dist/sidecars/schema.js +0 -149
  306. package/dist/sidecars/spec-drift.js +0 -151
  307. package/dist/sidecars/waiver-draft.js +0 -176
  308. package/dist/spec/SpecFileManager.js +0 -419
  309. package/dist/templates/.caws/schemas/policy.schema.json +0 -117
  310. package/dist/templates/.caws/schemas/scope.schema.json +0 -52
  311. package/dist/templates/.caws/schemas/waivers.schema.json +0 -106
  312. package/dist/templates/.caws/schemas/working-spec.schema.json +0 -340
  313. package/dist/templates/.caws/schemas/worktrees.schema.json +0 -38
  314. package/dist/templates/.caws/templates/working-spec.template.yml +0 -80
  315. package/dist/templates/.caws/tools/README.md +0 -18
  316. package/dist/templates/.caws/tools/scope-guard.js +0 -203
  317. package/dist/templates/.caws/tools-allow.json +0 -331
  318. package/dist/templates/.caws/waivers.yml +0 -19
  319. package/dist/templates/.claude/README.md +0 -190
  320. package/dist/templates/.claude/hooks/audit.sh +0 -121
  321. package/dist/templates/.claude/hooks/block-dangerous.sh +0 -203
  322. package/dist/templates/.claude/hooks/classify_command.py +0 -592
  323. package/dist/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  324. package/dist/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  325. package/dist/templates/.claude/hooks/naming-check.sh +0 -100
  326. package/dist/templates/.claude/hooks/protected-paths.sh +0 -39
  327. package/dist/templates/.claude/hooks/quality-check.sh +0 -81
  328. package/dist/templates/.claude/hooks/scan-secrets.sh +0 -85
  329. package/dist/templates/.claude/hooks/scope-guard.sh +0 -381
  330. package/dist/templates/.claude/hooks/session-caws-status.sh +0 -117
  331. package/dist/templates/.claude/hooks/session-log.sh +0 -634
  332. package/dist/templates/.claude/hooks/simplification-guard.sh +0 -92
  333. package/dist/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  334. package/dist/templates/.claude/hooks/test_classify_command.py +0 -370
  335. package/dist/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  336. package/dist/templates/.claude/hooks/validate-spec.sh +0 -76
  337. package/dist/templates/.claude/hooks/worktree-guard.sh +0 -220
  338. package/dist/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  339. package/dist/templates/.claude/rules/git-safety.md +0 -26
  340. package/dist/templates/.claude/rules/worktree-isolation.md +0 -101
  341. package/dist/templates/.claude/settings.json +0 -141
  342. package/dist/templates/.cursor/README.md +0 -299
  343. package/dist/templates/.cursor/hooks/audit.sh +0 -55
  344. package/dist/templates/.cursor/hooks/block-dangerous.sh +0 -84
  345. package/dist/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  346. package/dist/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  347. package/dist/templates/.cursor/hooks/format.sh +0 -38
  348. package/dist/templates/.cursor/hooks/naming-check.sh +0 -64
  349. package/dist/templates/.cursor/hooks/scan-secrets.sh +0 -51
  350. package/dist/templates/.cursor/hooks/scope-guard.sh +0 -52
  351. package/dist/templates/.cursor/hooks/session-log.sh +0 -924
  352. package/dist/templates/.cursor/hooks/validate-spec.sh +0 -83
  353. package/dist/templates/.cursor/hooks.json +0 -76
  354. package/dist/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  355. package/dist/templates/.cursor/rules/01-working-style.mdc +0 -50
  356. package/dist/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  357. package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  358. package/dist/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  359. package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  360. package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  361. package/dist/templates/.cursor/rules/07-process-ops.mdc +0 -20
  362. package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  363. package/dist/templates/.cursor/rules/09-docstrings.mdc +0 -89
  364. package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  365. package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  366. package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  367. package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  368. package/dist/templates/.cursor/rules/README.md +0 -148
  369. package/dist/templates/.github/copilot-instructions.md +0 -82
  370. package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  371. package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  372. package/dist/templates/.junie/guidelines.md +0 -73
  373. package/dist/templates/.vscode/launch.json +0 -17
  374. package/dist/templates/.vscode/settings.json +0 -95
  375. package/dist/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  376. package/dist/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  377. package/dist/templates/CLAUDE.md +0 -196
  378. package/dist/templates/COMMIT_CONVENTIONS.md +0 -86
  379. package/dist/templates/OIDC_SETUP.md +0 -300
  380. package/dist/templates/agents.md +0 -171
  381. package/dist/templates/codemod/README.md +0 -1
  382. package/dist/templates/codemod/test.js +0 -93
  383. package/dist/templates/docs/README.md +0 -151
  384. package/dist/templates/scripts/new_feature.sh +0 -80
  385. package/dist/templates/scripts/quality-gates/check-god-objects.js +0 -146
  386. package/dist/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  387. package/dist/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
  388. package/dist/test-analysis.js +0 -786
  389. package/dist/tool-interface.js +0 -314
  390. package/dist/tool-loader.js +0 -303
  391. package/dist/tool-validator.js +0 -393
  392. package/dist/utils/agent-display.js +0 -210
  393. package/dist/utils/agent-session.js +0 -344
  394. package/dist/utils/async-utils.js +0 -188
  395. package/dist/utils/command-wrapper.js +0 -200
  396. package/dist/utils/event-log.js +0 -584
  397. package/dist/utils/event-renderer.js +0 -521
  398. package/dist/utils/finalization.js +0 -230
  399. package/dist/utils/git-lock.js +0 -119
  400. package/dist/utils/gitignore-updater.js +0 -158
  401. package/dist/utils/ide-detection.js +0 -133
  402. package/dist/utils/lifecycle-events.js +0 -94
  403. package/dist/utils/project-analysis.js +0 -367
  404. package/dist/utils/promise-utils.js +0 -72
  405. package/dist/utils/quality-gates-errors.js +0 -520
  406. package/dist/utils/quality-gates-utils.js +0 -387
  407. package/dist/utils/schema-validator.js +0 -50
  408. package/dist/utils/spec-resolver.js +0 -711
  409. package/dist/utils/typescript-detector.js +0 -369
  410. package/dist/utils/working-state.js +0 -530
  411. package/dist/utils/yaml-validation.js +0 -156
  412. package/dist/validation/spec-validation.js +0 -924
  413. package/dist/waivers-manager.js +0 -732
  414. package/dist/worktree/worktree-manager.js +0 -1735
  415. package/templates/.caws/schemas/policy.schema.json +0 -117
  416. package/templates/.caws/schemas/scope.schema.json +0 -52
  417. package/templates/.caws/schemas/waivers.schema.json +0 -106
  418. package/templates/.caws/schemas/working-spec.schema.json +0 -340
  419. package/templates/.caws/schemas/worktrees.schema.json +0 -38
  420. package/templates/.caws/templates/working-spec.template.yml +0 -80
  421. package/templates/.caws/tools/README.md +0 -18
  422. package/templates/.caws/tools/scope-guard.js +0 -203
  423. package/templates/.caws/tools-allow.json +0 -331
  424. package/templates/.caws/waivers.yml +0 -19
  425. package/templates/.claude/README.md +0 -190
  426. package/templates/.claude/hooks/audit.sh +0 -121
  427. package/templates/.claude/hooks/block-dangerous.sh +0 -203
  428. package/templates/.claude/hooks/classify_command.py +0 -592
  429. package/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  430. package/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  431. package/templates/.claude/hooks/naming-check.sh +0 -100
  432. package/templates/.claude/hooks/protected-paths.sh +0 -39
  433. package/templates/.claude/hooks/quality-check.sh +0 -81
  434. package/templates/.claude/hooks/scan-secrets.sh +0 -85
  435. package/templates/.claude/hooks/scope-guard.sh +0 -381
  436. package/templates/.claude/hooks/session-caws-status.sh +0 -117
  437. package/templates/.claude/hooks/session-log.sh +0 -634
  438. package/templates/.claude/hooks/simplification-guard.sh +0 -92
  439. package/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  440. package/templates/.claude/hooks/test_classify_command.py +0 -370
  441. package/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  442. package/templates/.claude/hooks/validate-spec.sh +0 -76
  443. package/templates/.claude/hooks/worktree-guard.sh +0 -220
  444. package/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  445. package/templates/.claude/rules/git-safety.md +0 -26
  446. package/templates/.claude/rules/worktree-isolation.md +0 -101
  447. package/templates/.claude/settings.json +0 -141
  448. package/templates/.cursor/README.md +0 -299
  449. package/templates/.cursor/hooks/audit.sh +0 -55
  450. package/templates/.cursor/hooks/block-dangerous.sh +0 -84
  451. package/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  452. package/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  453. package/templates/.cursor/hooks/format.sh +0 -38
  454. package/templates/.cursor/hooks/naming-check.sh +0 -64
  455. package/templates/.cursor/hooks/scan-secrets.sh +0 -51
  456. package/templates/.cursor/hooks/scope-guard.sh +0 -52
  457. package/templates/.cursor/hooks/session-log.sh +0 -924
  458. package/templates/.cursor/hooks/validate-spec.sh +0 -83
  459. package/templates/.cursor/hooks.json +0 -76
  460. package/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  461. package/templates/.cursor/rules/01-working-style.mdc +0 -50
  462. package/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  463. package/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  464. package/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  465. package/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  466. package/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  467. package/templates/.cursor/rules/07-process-ops.mdc +0 -20
  468. package/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  469. package/templates/.cursor/rules/09-docstrings.mdc +0 -89
  470. package/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  471. package/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  472. package/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  473. package/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  474. package/templates/.cursor/rules/README.md +0 -148
  475. package/templates/.github/copilot-instructions.md +0 -82
  476. package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  477. package/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  478. package/templates/.junie/guidelines.md +0 -73
  479. package/templates/.vscode/launch.json +0 -17
  480. package/templates/.vscode/settings.json +0 -95
  481. package/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  482. package/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  483. package/templates/CLAUDE.md +0 -196
  484. package/templates/COMMIT_CONVENTIONS.md +0 -86
  485. package/templates/OIDC_SETUP.md +0 -300
  486. package/templates/agents.md +0 -171
  487. package/templates/codemod/README.md +0 -1
  488. package/templates/codemod/test.js +0 -93
  489. package/templates/docs/README.md +0 -151
  490. package/templates/scripts/new_feature.sh +0 -80
  491. package/templates/scripts/quality-gates/check-god-objects.js +0 -146
  492. package/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  493. package/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
@@ -1,928 +0,0 @@
1
- /**
2
- * @fileoverview Git Hooks Scaffolding for CAWS Provenance
3
- * Functions for setting up git hooks that automatically update provenance
4
- * @author @darianrosebrook
5
- */
6
-
7
- const fs = require('fs-extra');
8
- const path = require('path');
9
- const { getTodoAnalyzerSuggestion } = require('../utils/project-analysis');
10
-
11
- /**
12
- * Scaffold git hooks for CAWS provenance tracking
13
- * @param {string} projectDir - Project directory path
14
- * @param {Object} options - Hook options
15
- */
16
- async function scaffoldGitHooks(projectDir, options = {}) {
17
- const { provenance = true, validation = true, qualityGates = true, force = false } = options;
18
-
19
- console.log('Setting up Git hooks for CAWS provenance...');
20
-
21
- const gitDir = path.join(projectDir, '.git');
22
- const hooksDir = path.join(gitDir, 'hooks');
23
-
24
- // Check if this is a git repository
25
- if (!(await fs.pathExists(gitDir))) {
26
- console.log('Not a git repository - skipping git hooks setup');
27
- console.log('Initialize git first: git init');
28
- return { added: 0, skipped: 0 };
29
- }
30
-
31
- // Ensure hooks directory exists
32
- await fs.ensureDir(hooksDir);
33
-
34
- let addedCount = 0;
35
- let skippedCount = 0;
36
-
37
- // Define hook configurations
38
- const hooks = [
39
- {
40
- name: 'pre-commit',
41
- description: 'Pre-commit validation and quality checks',
42
- enabled: validation || qualityGates,
43
- content: generatePreCommitHook({ validation, qualityGates, projectDir }),
44
- },
45
- {
46
- name: 'post-commit',
47
- description: 'Post-commit provenance tracking',
48
- enabled: provenance,
49
- content: generatePostCommitHook(),
50
- },
51
- {
52
- name: 'pre-push',
53
- description: 'Pre-push comprehensive validation',
54
- enabled: qualityGates,
55
- content: generatePrePushHook(),
56
- },
57
- {
58
- name: 'commit-msg',
59
- description: 'Commit message validation',
60
- enabled: validation,
61
- content: generateCommitMsgHook(),
62
- },
63
- ];
64
-
65
- for (const hook of hooks) {
66
- if (!hook.enabled) continue;
67
-
68
- const hookPath = path.join(hooksDir, hook.name);
69
-
70
- try {
71
- // Check if hook already exists
72
- const exists = await fs.pathExists(hookPath);
73
-
74
- if (exists && !force) {
75
- // Check if it's already a CAWS hook
76
- const content = await fs.readFile(hookPath, 'utf8');
77
- if (content.includes('# CAWS Hook')) {
78
- console.log(`Skipped ${hook.description} (already configured)`);
79
- skippedCount++;
80
- continue;
81
- } else {
82
- console.log(`${hook.description} exists but not CAWS-managed`);
83
- if (!options.backup) {
84
- console.log(`Use --force to replace, or --backup to preserve original`);
85
- skippedCount++;
86
- continue;
87
- }
88
- }
89
- }
90
-
91
- // Backup existing hook if requested
92
- if (exists && options.backup) {
93
- const backupPath = `${hookPath}.backup.${Date.now()}`;
94
- await fs.copy(hookPath, backupPath);
95
- console.log(`Backed up existing ${hook.name} to ${path.basename(backupPath)}`);
96
- }
97
-
98
- // Write the hook
99
- await fs.writeFile(hookPath, hook.content);
100
- await fs.chmod(hookPath, 0o755);
101
-
102
- console.log(`Configured ${hook.description}`);
103
- addedCount++;
104
- } catch (error) {
105
- console.log(`Failed to configure ${hook.description}: ${error.message}`);
106
- }
107
- }
108
-
109
- if (addedCount > 0) {
110
- console.log(`\nGit hooks configured: ${addedCount} hooks active`);
111
- console.log('Hooks will run automatically on git operations');
112
- console.log('Use --no-verify to skip commit hooks: git commit --no-verify');
113
- console.log('Note: --no-verify is BLOCKED on git push for safety');
114
- }
115
-
116
- return { added: addedCount, skipped: skippedCount };
117
- }
118
-
119
- /**
120
- * Generate pre-commit hook content with staged file quality gates
121
- * Implements fallback chain: Node script → CLI → Python scripts → Skip gracefully
122
- */
123
- function generatePreCommitHook(options) {
124
- const { qualityGates = true, stagedOnly = true, projectDir = process.cwd() } = options;
125
-
126
- // Get language-agnostic suggestions based on runtime availability
127
- const todoSuggestion = getTodoAnalyzerSuggestion(projectDir);
128
-
129
- return `#!/bin/bash
130
- # CAWS Pre-commit Hook
131
- # Runs validation and quality checks before commits
132
- # Implements graceful fallback chain to avoid blocking commits
133
-
134
- set -e
135
-
136
- echo "Running CAWS Quality Gates${qualityGates ? ' (Crisis Response Mode)' : ''}..."
137
- echo "Analyzing ${stagedOnly ? 'staged files only' : 'all files'}..."
138
-
139
- # Check if CAWS is initialized
140
- if [ ! -d ".caws" ]; then
141
- echo "CAWS not initialized - skipping validation"
142
- exit 0
143
- fi
144
-
145
- # Check for git locks before proceeding
146
- if [ -f ".git/index.lock" ]; then
147
- LOCK_AGE=$(($(date +%s) - $(stat -f %m .git/index.lock 2>/dev/null || stat -c %Y .git/index.lock 2>/dev/null || echo 0)))
148
- LOCK_AGE_MINUTES=$((LOCK_AGE / 60))
149
-
150
- if [ $LOCK_AGE_MINUTES -gt 5 ]; then
151
- echo "Stale git lock detected (\${LOCK_AGE_MINUTES} minutes old)"
152
- echo "This may indicate a crashed git process"
153
- echo "Remove stale lock: rm .git/index.lock"
154
- echo "Warning: Check for running git/editor processes before removing"
155
- exit 1
156
- else
157
- echo "Git lock detected (\${LOCK_AGE_MINUTES} minutes old)"
158
- echo "Another git process may be running"
159
- echo "Wait for the other process to complete, or check for running processes"
160
- exit 1
161
- fi
162
- fi
163
-
164
- # Validate YAML syntax for all CAWS spec files
165
- echo "Validating YAML syntax for CAWS spec files..."
166
- YAML_VALIDATION_FAILED=false
167
-
168
- # Find all staged .yaml/.yml files in .caws directory
169
- STAGED_YAML_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\\.caws/.*\\.(yaml|yml)$' || true)
170
-
171
- if [ -n "$STAGED_YAML_FILES" ]; then
172
- # Use Node.js to validate YAML if available
173
- if command -v node >/dev/null 2>&1; then
174
- # Try to use CAWS CLI for validation
175
- if command -v caws >/dev/null 2>&1; then
176
- for file in $STAGED_YAML_FILES; do
177
- if [ -f "$file" ]; then
178
- # Use Node.js to validate YAML syntax
179
- if ! node -e "
180
- const yaml = require('js-yaml');
181
- const fs = require('fs');
182
- try {
183
- const content = fs.readFileSync('$file', 'utf8');
184
- yaml.load(content);
185
- process.exit(0);
186
- } catch (error) {
187
- console.error('Invalid YAML in $file');
188
- console.error(' Error:', error.message);
189
- if (error.mark) {
190
- console.error(' Line:', error.mark.line + 1, 'Column:', error.mark.column + 1);
191
- if (error.mark.snippet) console.error(' ' + error.mark.snippet);
192
- }
193
- process.exit(1);
194
- }
195
- " 2>&1; then
196
- YAML_VALIDATION_FAILED=true
197
- fi
198
- fi
199
- done
200
- else
201
- # Fallback: use node directly with js-yaml
202
- for file in $STAGED_YAML_FILES; do
203
- if [ -f "$file" ]; then
204
- if ! node -e "
205
- const yaml = require('js-yaml');
206
- const fs = require('fs');
207
- try {
208
- const content = fs.readFileSync('$file', 'utf8');
209
- yaml.load(content);
210
- process.exit(0);
211
- } catch (error) {
212
- console.error('Invalid YAML in $file');
213
- console.error(' Error:', error.message);
214
- if (error.mark) {
215
- console.error(' Line:', error.mark.line + 1, 'Column:', error.mark.column + 1);
216
- if (error.mark.snippet) console.error(' ' + error.mark.snippet);
217
- }
218
- process.exit(1);
219
- }
220
- " 2>&1; then
221
- YAML_VALIDATION_FAILED=true
222
- fi
223
- fi
224
- done
225
- fi
226
- else
227
- echo "Node.js not available - skipping YAML validation"
228
- echo "Install Node.js to enable YAML syntax validation"
229
- fi
230
- fi
231
-
232
- if [ "$YAML_VALIDATION_FAILED" = true ]; then
233
- echo "YAML syntax validation failed - commit blocked"
234
- echo "Fix YAML syntax errors above before committing"
235
- echo "Consider using 'caws specs create <id>' instead of manual creation"
236
- exit 1
237
- fi
238
-
239
- # ===== CAWS Multi-Agent Safety Guard =====
240
- # Prevents unsafe concurrent operations on shared branches
241
-
242
- if [ -d ".caws" ]; then
243
- CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
244
-
245
- # Guard 1a: Block commits on base branch when parallel worktrees are active (caws parallel)
246
- if [ -f ".caws/parallel.json" ] && command -v node >/dev/null 2>&1; then
247
- PARALLEL_BASE=$(node -e "
248
- try {
249
- var reg = JSON.parse(require('fs').readFileSync('.caws/parallel.json', 'utf8'));
250
- console.log(reg.baseBranch || '');
251
- } catch(e) { console.log(''); }
252
- " 2>/dev/null)
253
-
254
- if [ -n "$PARALLEL_BASE" ] && [ "$CURRENT_BRANCH" = "$PARALLEL_BASE" ]; then
255
- AGENT_COUNT=$(node -e "
256
- try {
257
- var reg = JSON.parse(require('fs').readFileSync('.caws/parallel.json', 'utf8'));
258
- console.log((reg.agents || []).length);
259
- } catch(e) { console.log('0'); }
260
- " 2>/dev/null)
261
-
262
- if [ "$AGENT_COUNT" -gt 0 ] 2>/dev/null; then
263
- echo "BLOCKED: Committing to '$CURRENT_BRANCH' while $AGENT_COUNT parallel agent worktree(s) are active."
264
- echo " Active agents are working in isolated worktrees."
265
- echo " Committing to the base branch risks interleaved history and merge conflicts."
266
- echo ""
267
- echo " To see parallel status: caws parallel status"
268
- echo " To merge agent work: caws parallel merge"
269
- echo " To override (unsafe): git commit --no-verify"
270
- exit 1
271
- fi
272
- fi
273
- fi
274
-
275
- # Guard 1b: Block commits on base branch when ANY active worktrees exist (caws worktree create)
276
- if [ -f ".caws/worktrees.json" ] && command -v node >/dev/null 2>&1; then
277
- ACTIVE_WORKTREES=$(node -e "
278
- try {
279
- var reg = JSON.parse(require('fs').readFileSync('.caws/worktrees.json', 'utf8'));
280
- var wts = Object.values(reg.worktrees || {});
281
- var active = wts.filter(function(w) {
282
- return (w.status === 'active' || w.status === 'fresh' || w.status === 'merged') && w.baseBranch === '$CURRENT_BRANCH';
283
- });
284
- console.log(active.length + ':' + active.map(function(w) { return w.name; }).join(','));
285
- } catch(e) { console.log('0:'); }
286
- " 2>/dev/null)
287
-
288
- WT_COUNT=$(echo "$ACTIVE_WORKTREES" | cut -d: -f1)
289
- WT_NAMES=$(echo "$ACTIVE_WORKTREES" | cut -d: -f2)
290
-
291
- if [ "$WT_COUNT" -gt 0 ] 2>/dev/null; then
292
- echo "BLOCKED: Committing to '$CURRENT_BRANCH' while $WT_COUNT active worktree(s) exist: $WT_NAMES"
293
- echo " You should be working in your worktree, not on the base branch."
294
- echo " Committing here risks interleaved history with agents in worktrees."
295
- echo ""
296
- echo " To work in your worktree: cd .caws/worktrees/<name>/"
297
- echo " To see worktrees: caws worktree list"
298
- echo " To override (unsafe): git commit --no-verify"
299
- exit 1
300
- fi
301
- fi
302
-
303
- # Guard 2: Warn if multiple active sessions exist on same branch
304
- if [ -f ".caws/sessions.json" ] && command -v node >/dev/null 2>&1; then
305
- ACTIVE_ON_BRANCH=$(node -e "
306
- try {
307
- var reg = JSON.parse(require('fs').readFileSync('.caws/sessions.json', 'utf8'));
308
- var count = Object.values(reg.sessions || {}).filter(
309
- function(s) { return s.status === 'active' && s.branch === '$CURRENT_BRANCH'; }
310
- ).length;
311
- console.log(count);
312
- } catch(e) { console.log('0'); }
313
- " 2>/dev/null)
314
-
315
- if [ "$ACTIVE_ON_BRANCH" -gt 1 ] 2>/dev/null; then
316
- echo "WARNING: $ACTIVE_ON_BRANCH active sessions detected on branch '$CURRENT_BRANCH'."
317
- echo " Multiple agents committing to the same branch risks interleaved history."
318
- echo " Consider using worktrees: caws parallel setup <plan-file>"
319
- echo ""
320
- fi
321
- fi
322
-
323
- # Guard 3: Block --amend when HEAD commit may not belong to current session
324
- # Detect --amend by inspecting the parent git process arguments
325
- AMEND_FLAG=false
326
- if command -v ps >/dev/null 2>&1; then
327
- PARENT_ARGS=$(ps -o args= -p $PPID 2>/dev/null || echo "")
328
- case "$PARENT_ARGS" in
329
- *--amend*) AMEND_FLAG=true ;;
330
- esac
331
- fi
332
-
333
- if [ "$AMEND_FLAG" = true ]; then
334
- BLOCK_AMEND=false
335
- if [ -f ".caws/parallel.json" ]; then
336
- BLOCK_AMEND=true
337
- elif [ -f ".caws/worktrees.json" ] && command -v node >/dev/null 2>&1; then
338
- HAS_ACTIVE_WT=$(node -e "
339
- try {
340
- var reg = JSON.parse(require('fs').readFileSync('.caws/worktrees.json', 'utf8'));
341
- var active = Object.values(reg.worktrees || {}).filter(function(w) { return w.status === 'active' || w.status === 'fresh' || w.status === 'merged'; });
342
- console.log(active.length > 0 ? 'yes' : 'no');
343
- } catch(e) { console.log('no'); }
344
- " 2>/dev/null)
345
- if [ "$HAS_ACTIVE_WT" = "yes" ]; then
346
- BLOCK_AMEND=true
347
- fi
348
- fi
349
-
350
- if [ "$BLOCK_AMEND" = true ]; then
351
- echo "BLOCKED: --amend is not allowed while worktrees are active."
352
- echo " Amending commits risks rewriting another agent's work."
353
- echo " Create a new commit instead."
354
- echo " To override (dangerous): git commit --amend --no-verify"
355
- exit 1
356
- fi
357
- fi
358
- fi
359
- # ===== End Multi-Agent Safety Guard =====
360
-
361
- # Run CAWS quality gates
362
- QUALITY_GATES_RAN=false
363
- QUALITY_GATES_WARNED=false
364
-
365
- # Resolve spec ID from worktree context if available
366
- SPEC_ID=""
367
- WORKTREE_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
368
- if [ -f ".caws/worktrees.json" ] && command -v node >/dev/null 2>&1; then
369
- SPEC_ID=$(node -e "
370
- try {
371
- var reg = JSON.parse(require('fs').readFileSync('.caws/worktrees.json', 'utf8'));
372
- var wt = Object.values(reg.worktrees || {}).find(function(w) {
373
- return w.branch === '$WORKTREE_BRANCH';
374
- });
375
- if (wt && wt.specId) console.log(wt.specId);
376
- } catch(e) {}
377
- " 2>/dev/null || echo "")
378
- fi
379
-
380
- GATES_ARGS="--context=commit --quiet"
381
- if [ -n "$SPEC_ID" ]; then
382
- GATES_ARGS="$GATES_ARGS --spec-id $SPEC_ID"
383
- fi
384
-
385
- if command -v caws >/dev/null 2>&1; then
386
- if caws gates run $GATES_ARGS; then
387
- echo "Quality gates passed"
388
- QUALITY_GATES_RAN=true
389
- else
390
- GATE_EXIT=$?
391
- echo "Quality gates BLOCKED the commit (exit code $GATE_EXIT)"
392
- exit 1
393
- fi
394
- else
395
- echo "CAWS CLI not available — skipping quality gates"
396
- echo "Install with: npm install -g @paths.design/caws-cli"
397
- QUALITY_GATES_RAN=true
398
- fi
399
-
400
- # Run hidden TODO analysis on staged files only (if available)
401
- if [ "$QUALITY_GATES_RAN" = true ]; then
402
- echo "Checking for hidden TODOs in staged files..."
403
-
404
- TODO_CHECK_RAN=false
405
-
406
- # Option 1: Find TODO analyzer .mjs file (if installed locally)
407
- if [ "$TODO_CHECK_RAN" = false ]; then
408
- TODO_ANALYZER=""
409
-
410
- # Try quality gates package TODO analyzer (published package)
411
- if [ -f "node_modules/@paths.design/quality-gates/todo-analyzer.mjs" ]; then
412
- TODO_ANALYZER="node_modules/@paths.design/quality-gates/todo-analyzer.mjs"
413
- # Try quality gates package TODO analyzer (monorepo/local copy)
414
- elif [ -f "node_modules/@caws/quality-gates/todo-analyzer.mjs" ]; then
415
- TODO_ANALYZER="node_modules/@caws/quality-gates/todo-analyzer.mjs"
416
- # Try monorepo structure (development)
417
- elif [ -f "packages/quality-gates/todo-analyzer.mjs" ]; then
418
- TODO_ANALYZER="packages/quality-gates/todo-analyzer.mjs"
419
- # Try local copy in scripts directory (if scaffolded)
420
- elif [ -f "scripts/todo-analyzer.mjs" ]; then
421
- TODO_ANALYZER="scripts/todo-analyzer.mjs"
422
- fi
423
-
424
- # Run TODO analyzer if found
425
- if [ -n "$TODO_ANALYZER" ] && command -v node >/dev/null 2>&1; then
426
- if node "$TODO_ANALYZER" --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
427
- echo "No critical hidden TODOs found in staged files"
428
- TODO_CHECK_RAN=true
429
- else
430
- echo "Critical hidden TODOs detected in staged files - commit blocked"
431
- echo "Fix stub implementations and placeholder code before committing"
432
- echo "See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
433
- echo ""
434
- echo "Running detailed analysis on staged files..."
435
- node "$TODO_ANALYZER" --staged-only --min-confidence 0.8
436
- exit 1
437
- fi
438
- fi
439
- fi
440
-
441
- # Option 2: Fallback to legacy Python analyzer (deprecated - will be removed)
442
- if [ "$TODO_CHECK_RAN" = false ] && command -v python3 >/dev/null 2>&1 && [ -f "scripts/v3/analysis/todo_analyzer.py" ]; then
443
- echo "Using legacy Python TODO analyzer (deprecated)"
444
- if python3 scripts/v3/analysis/todo_analyzer.py --staged-only --ci-mode --min-confidence 0.8 >/dev/null 2>&1; then
445
- echo "No critical hidden TODOs found in staged files"
446
- TODO_CHECK_RAN=true
447
- else
448
- echo "Critical hidden TODOs detected in staged files - commit blocked"
449
- echo "Fix stub implementations and placeholder code before committing"
450
- echo "See docs/PLACEHOLDER-DETECTION-GUIDE.md for classification"
451
- echo ""
452
- echo "Running detailed analysis on staged files..."
453
- python3 scripts/v3/analysis/todo_analyzer.py --staged-only --min-confidence 0.8
454
- exit 1
455
- fi
456
- fi
457
-
458
- # Option 3: No analyzer available - show language-aware suggestions
459
- if [ "$TODO_CHECK_RAN" = false ]; then
460
- echo "TODO analyzer not available - skipping hidden TODO check"
461
- echo "Available options for TODO analysis:"
462
- ${todoSuggestion
463
- .split('\n')
464
- .map((line) => ` echo "${line.replace(/"/g, '\\"')}"`)
465
- .join('\n')}
466
- fi
467
- fi
468
-
469
- if [ "$QUALITY_GATES_WARNED" = true ]; then
470
- echo "Proceeding with commit (some quality checks had warnings)"
471
- else
472
- echo "All quality checks passed - proceeding with commit"
473
- fi
474
- exit 0
475
- `;
476
- }
477
-
478
- /**
479
- * Generate post-commit hook content
480
- */
481
- function generatePostCommitHook() {
482
- return `#!/bin/bash
483
- # CAWS Post-commit Hook
484
- # Updates provenance tracking after successful commits
485
-
486
- # Run in background to avoid blocking git operations
487
- (
488
- # Check if CAWS is initialized
489
- if [ ! -d ".caws" ]; then
490
- exit 0
491
- fi
492
-
493
- # Skip during merge operations — caws worktree merge triggers a merge
494
- # commit, and writing to .caws/provenance/chain.json here would dirty
495
- # the tree mid-merge, blocking subsequent operations.
496
- if [ -f ".git/MERGE_HEAD" ] || [ -f "$(git rev-parse --git-dir 2>/dev/null)/MERGE_HEAD" ]; then
497
- exit 0
498
- fi
499
-
500
- # Get the current commit hash
501
- COMMIT_HASH=$(git rev-parse HEAD)
502
-
503
- # Get commit details
504
- COMMIT_MESSAGE=$(git log -1 --pretty=%B | head -1)
505
- AUTHOR_NAME=$(git log -1 --pretty=%an)
506
- AUTHOR_EMAIL=$(git log -1 --pretty=%ae)
507
-
508
- # Update provenance if CAWS CLI is available
509
- if command -v caws >/dev/null 2>&1; then
510
- echo "Updating CAWS provenance for commit \${COMMIT_HASH:0:8}..."
511
-
512
- # Run provenance update in background
513
- (
514
- caws provenance update \\
515
- --commit "$COMMIT_HASH" \\
516
- --message "$COMMIT_MESSAGE" \\
517
- --author "$AUTHOR_NAME <$AUTHOR_EMAIL>" \\
518
- --quiet
519
- ) &
520
- fi
521
- ) >/dev/null 2>&1 &
522
- `;
523
- }
524
-
525
- /**
526
- * Generate pre-push hook content
527
- * Blocks --no-verify to enforce quality gates before pushing
528
- */
529
- function generatePrePushHook() {
530
- return `#!/bin/bash
531
- # CAWS Pre-push Hook
532
- # Runs comprehensive checks before pushing
533
- # BLOCKS --no-verify for safety
534
-
535
- set -e
536
-
537
- # Block --no-verify on push operations
538
- for arg in "$@"; do
539
- if [[ "$arg" == "--no-verify" ]] || [[ "$arg" == "-n" ]]; then
540
- echo "Error: --no-verify is BLOCKED on git push"
541
- echo "==================================================="
542
- echo "Push operations must pass all quality gates."
543
- echo ""
544
- echo "To fix issues locally:"
545
- echo " 1. Run: caws validate"
546
- echo " 2. Fix reported issues"
547
- echo " 3. Commit fixes: git commit --no-verify \\(allowed\\)"
548
- echo " 4. Push again: git push \\(no --no-verify\\)"
549
- exit 1
550
- fi
551
- done
552
-
553
- echo "CAWS Pre-push Validation"
554
- echo "==================================================="
555
-
556
- # Check if CAWS is initialized
557
- if [ ! -d ".caws" ]; then
558
- echo "CAWS not initialized - skipping validation"
559
- exit 0
560
- fi
561
-
562
- # Run CAWS validation (supports multi-spec projects)
563
- CAWS_VALIDATION_FAILED=false
564
- if command -v caws >/dev/null 2>&1; then
565
- echo "Running CAWS validation..."
566
-
567
- # Multi-spec project: validate each open spec individually
568
- if [ -d ".caws/specs" ] && command -v node >/dev/null 2>&1; then
569
- OPEN_SPECS=$(node -e "
570
- var fs = require('fs'), path = require('path'), dir = '.caws/specs';
571
- try {
572
- fs.readdirSync(dir).filter(function(f) { return f.endsWith('.yaml'); }).forEach(function(f) {
573
- var content = fs.readFileSync(path.join(dir, f), 'utf8');
574
- if (content.indexOf('status: closed') === -1) {
575
- var match = content.match(/^id:\\s*(.+)$/m);
576
- if (match) console.log(match[1].trim());
577
- }
578
- });
579
- } catch(e) {}
580
- " 2>/dev/null || echo "")
581
-
582
- if [ -n "$OPEN_SPECS" ]; then
583
- echo " Multi-spec project detected, validating open specs..."
584
- while IFS= read -r spec_id; do
585
- [ -z "$spec_id" ] && continue
586
- echo " Validating spec: $spec_id"
587
- if ! caws validate --spec-id "$spec_id" --quiet 2>&1; then
588
- echo " Validation failed for spec: $spec_id"
589
- CAWS_VALIDATION_FAILED=true
590
- fi
591
- done <<< "$OPEN_SPECS"
592
- if [ "$CAWS_VALIDATION_FAILED" = false ]; then
593
- echo "CAWS validation passed (all open specs)"
594
- fi
595
- else
596
- echo " No open specs found, skipping CAWS validation"
597
- fi
598
- else
599
- # Single-spec project: validate working-spec directly
600
- VALIDATION_OUTPUT=$(caws validate --quiet 2>&1)
601
- if [ $? -ne 0 ]; then
602
- echo "$VALIDATION_OUTPUT"
603
- CAWS_VALIDATION_FAILED=true
604
- else
605
- echo "CAWS validation passed"
606
- fi
607
- fi
608
-
609
- if [ "$CAWS_VALIDATION_FAILED" = true ]; then
610
- echo ""
611
- echo "==================================================="
612
- echo "CAWS validation failed"
613
- echo "==================================================="
614
- echo "Next Steps:"
615
- echo " 1. Review errors above"
616
- echo " 2. Fix issues in .caws/working-spec.yaml or .caws/specs/"
617
- echo " 3. Run: caws validate (to verify fixes)"
618
- echo " 4. Push again: git push"
619
- echo "==================================================="
620
- exit 1
621
- fi
622
- fi
623
-
624
- # Run full pre-push checks (full test suite required before push)
625
- # Note: Pre-commit uses filtered tests for speed, but push requires full suite
626
- echo ""
627
- echo "Running full pre-push checks (full test suite required)..."
628
- echo "==================================================="
629
-
630
- QUICK_CHECKS_FAILED=false
631
-
632
- # 1. Linting (fast)
633
- if [ -f "package.json" ]; then
634
- if command -v npm >/dev/null 2>&1; then
635
- if grep -q '"lint"' package.json; then
636
- echo "Running linting..."
637
- if npm run lint >/dev/null 2>&1; then
638
- echo "Linting passed"
639
- else
640
- echo "Linting failed"
641
- echo "Fix lint errors: npm run lint"
642
- QUICK_CHECKS_FAILED=true
643
- fi
644
- fi
645
- fi
646
- fi
647
-
648
- # 2. Type checking (fast for TypeScript/JavaScript)
649
- if [ -f "package.json" ]; then
650
- if command -v npm >/dev/null 2>&1; then
651
- if grep -q '"typecheck"' package.json; then
652
- echo "Running type checking..."
653
- if npm run typecheck >/dev/null 2>&1; then
654
- echo "Type checking passed"
655
- else
656
- echo "Type checking failed"
657
- echo "Fix type errors: npm run typecheck"
658
- QUICK_CHECKS_FAILED=true
659
- fi
660
- fi
661
- fi
662
- fi
663
-
664
- # 3. Run FULL test suite (required for push) - no filtering
665
- # Pre-commit uses filtered tests for speed, but push requires full suite
666
- if [ -f "package.json" ]; then
667
- if command -v npm >/dev/null 2>&1 && grep -q '"test"' package.json; then
668
- echo "Running FULL test suite (required for push)..."
669
- echo "==================================================="
670
- if npm test 2>&1 | tee /tmp/pre-push-test-full.log; then
671
- echo "Full test suite passed"
672
- rm -f /tmp/pre-push-test-full.log
673
- else
674
- FULL_TEST_EXIT_CODE=\${PIPESTATUS[0]}
675
- echo "Full test suite failed (exit code: \${FULL_TEST_EXIT_CODE})"
676
- echo "==================================================="
677
- echo "Test output (last 100 lines):"
678
- tail -100 /tmp/pre-push-test-full.log 2>/dev/null || echo "No test output captured"
679
- echo "==================================================="
680
- echo "Fix test failures before pushing: npm test"
681
- rm -f /tmp/pre-push-test-full.log
682
- QUICK_CHECKS_FAILED=true
683
- fi
684
- fi
685
- fi
686
-
687
- # 4. Security checks (non-blocking warnings)
688
- echo ""
689
- echo "Running security checks..."
690
- if [ -f "package.json" ]; then
691
- if command -v npm >/dev/null 2>&1; then
692
- echo "Checking for vulnerabilities..."
693
- if npm audit --audit-level moderate >/dev/null 2>&1; then
694
- echo "Security audit passed"
695
- else
696
- echo "Security vulnerabilities found (non-blocking)"
697
- echo "Review with: npm audit"
698
- fi
699
- fi
700
- elif [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
701
- if command -v pip-audit >/dev/null 2>&1; then
702
- echo "Checking Python vulnerabilities..."
703
- pip-audit --desc 2>/dev/null || echo "Install pip-audit: pip install pip-audit"
704
- fi
705
- elif [ -f "Cargo.toml" ]; then
706
- if command -v cargo-audit >/dev/null 2>&1; then
707
- echo "Checking Rust vulnerabilities..."
708
- cargo audit 2>/dev/null || echo "Install cargo-audit: cargo install cargo-audit"
709
- fi
710
- fi
711
-
712
- # Fail if any checks failed
713
- if [ "$QUICK_CHECKS_FAILED" = true ]; then
714
- echo ""
715
- echo "==================================================="
716
- echo "Pre-push checks failed"
717
- echo "==================================================="
718
- echo "All checks (linting/type checking/full test suite) must pass before push."
719
- echo ""
720
- echo "Fix failures before pushing:"
721
- echo " - Linting: npm run lint"
722
- echo " - Type checking: npm run typecheck"
723
- echo " - Tests: npm test"
724
- echo "==================================================="
725
- exit 1
726
- fi
727
-
728
- echo ""
729
- echo "Pre-push checks completed!"
730
- echo "All quality gates passed - ready to push"
731
- `;
732
- }
733
-
734
- /**
735
- * Generate commit-msg hook content
736
- */
737
- function generateCommitMsgHook() {
738
- return `#!/bin/bash
739
- # CAWS Commit Message Hook
740
- # Validates commit message format and enforces merge(worktree): convention
741
-
742
- COMMIT_MSG_FILE=$1
743
-
744
- # Read the commit message
745
- COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
746
-
747
- # Resolve CAWS root (works from worktrees too)
748
- CAWS_ROOT="."
749
- if command -v git >/dev/null 2>&1; then
750
- _GIT_COMMON=$(git rev-parse --git-common-dir 2>/dev/null || echo ".git")
751
- if [ "$_GIT_COMMON" != ".git" ]; then
752
- _CANDIDATE=$(cd "$_GIT_COMMON/.." 2>/dev/null && pwd || echo "")
753
- if [ -n "$_CANDIDATE" ] && [ -d "$_CANDIDATE/.caws" ]; then
754
- CAWS_ROOT="$_CANDIDATE"
755
- fi
756
- fi
757
- fi
758
-
759
- # Check if CAWS is initialized
760
- if [ ! -d "$CAWS_ROOT/.caws" ]; then
761
- exit 0
762
- fi
763
-
764
- # ===== Worktree merge message guard =====
765
- CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
766
- GIT_DIR=$(git rev-parse --git-dir 2>/dev/null || echo ".git")
767
- HAS_ACTIVE_WORKTREES=false
768
-
769
- if [ -f "$CAWS_ROOT/.caws/worktrees.json" ] && command -v node >/dev/null 2>&1; then
770
- WT_COUNT=$(node -e "
771
- try {
772
- var reg = JSON.parse(require('fs').readFileSync('$CAWS_ROOT/.caws/worktrees.json', 'utf8'));
773
- var active = Object.values(reg.worktrees || {}).filter(function(w) {
774
- return (w.status === 'active' || w.status === 'fresh' || w.status === 'merged') && w.baseBranch === '$CURRENT_BRANCH';
775
- });
776
- console.log(active.length);
777
- } catch(e) { console.log('0'); }
778
- " 2>/dev/null)
779
- if [ "$WT_COUNT" -gt 0 ] 2>/dev/null; then
780
- HAS_ACTIVE_WORKTREES=true
781
- fi
782
- fi
783
-
784
- if [ "$HAS_ACTIVE_WORKTREES" = true ]; then
785
- IS_GIT_MERGE=false
786
- if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
787
- IS_GIT_MERGE=true
788
- fi
789
-
790
- if [[ "$COMMIT_MSG" =~ ^merge\\(worktree\\): ]] || [ "$IS_GIT_MERGE" = true ]; then
791
- echo "Merge commit to base branch allowed (worktrees active)"
792
- elif [[ "$COMMIT_MSG" =~ ^wip\\(checkpoint\\): ]]; then
793
- echo "Checkpoint commit allowed (prior-session cleanup)"
794
- else
795
- echo "BLOCKED: Direct commit to '$CURRENT_BRANCH' while worktrees are active."
796
- echo " Only these commit types are allowed on the base branch during parallel work:"
797
- echo ""
798
- echo " merge(worktree): <description> — merge a completed worktree branch"
799
- echo " wip(checkpoint): <description> — commit prior-session dirty files"
800
- echo " git merge --no-ff <branch> — git merge commit"
801
- echo ""
802
- echo " To override (unsafe): git commit --no-verify"
803
- exit 1
804
- fi
805
- fi
806
- # ===== End worktree merge message guard =====
807
-
808
- # Basic commit message validation
809
- if [ \${#COMMIT_MSG} -lt 10 ]; then
810
- echo "Commit message too short (minimum 10 characters)"
811
- echo " Write descriptive commit messages"
812
- exit 1
813
- fi
814
-
815
- # Check for conventional commit format (optional but encouraged)
816
- if [[ $COMMIT_MSG =~ ^(feat|fix|docs|style|refactor|test|chore|merge|perf|wip)(\\(.*\\))?: ]]; then
817
- : # valid format
818
- else
819
- if [[ ! $COMMIT_MSG =~ ^Merge\\ (branch|remote) ]]; then
820
- echo "Consider using conventional commit format:"
821
- echo " feat: / fix: / docs: / refactor: / chore: / merge(worktree):"
822
- fi
823
- fi
824
-
825
- echo "Commit message validation passed"
826
- `;
827
- }
828
-
829
- /**
830
- * Remove CAWS git hooks
831
- * @param {string} projectDir - Project directory path
832
- */
833
- async function removeGitHooks(projectDir) {
834
- console.log('Removing CAWS Git hooks...');
835
-
836
- const hooksDir = path.join(projectDir, '.git', 'hooks');
837
- const cawsHooks = ['pre-commit', 'post-commit', 'pre-push', 'commit-msg'];
838
-
839
- let removedCount = 0;
840
-
841
- for (const hookName of cawsHooks) {
842
- const hookPath = path.join(hooksDir, hookName);
843
-
844
- try {
845
- if (await fs.pathExists(hookPath)) {
846
- const content = await fs.readFile(hookPath, 'utf8');
847
- if (content.includes('# CAWS Hook') || content.includes('# CAWS Pre-commit Hook')) {
848
- await fs.remove(hookPath);
849
- console.log(`Removed ${hookName} hook`);
850
- removedCount++;
851
- } else {
852
- console.log(`Skipped ${hookName} (not CAWS-managed)`);
853
- }
854
- }
855
- } catch (error) {
856
- console.log(`Failed to remove ${hookName}: ${error.message}`);
857
- }
858
- }
859
-
860
- if (removedCount > 0) {
861
- console.log(`Removed ${removedCount} CAWS git hooks`);
862
- } else {
863
- console.log('No CAWS git hooks found');
864
- }
865
- }
866
-
867
- /**
868
- * Check git hooks status
869
- * @param {string} projectDir - Project directory path
870
- */
871
- async function checkGitHooksStatus(projectDir) {
872
- const hooksDir = path.join(projectDir, '.git', 'hooks');
873
- const cawsHooks = ['pre-commit', 'post-commit', 'pre-push', 'commit-msg'];
874
-
875
- console.log('Git Hooks Status:');
876
- console.log('===================================================');
877
-
878
- let activeCount = 0;
879
- let totalCount = 0;
880
-
881
- for (const hookName of cawsHooks) {
882
- totalCount++;
883
- const hookPath = path.join(hooksDir, hookName);
884
-
885
- try {
886
- if (await fs.pathExists(hookPath)) {
887
- const content = await fs.readFile(hookPath, 'utf8');
888
- const isExecutable = (await fs.stat(hookPath)).mode & 0o111;
889
-
890
- if (content.includes('# CAWS') && isExecutable) {
891
- console.log(`${hookName}: Active`);
892
- activeCount++;
893
- } else if (content.includes('# CAWS')) {
894
- console.log(`${hookName}: Configured but not executable`);
895
- } else {
896
- console.log(`${hookName}: Not CAWS-managed`);
897
- }
898
- } else {
899
- console.log(`${hookName}: Not installed`);
900
- }
901
- } catch (error) {
902
- console.log(`${hookName}: Error checking status`);
903
- }
904
- }
905
-
906
- console.log('');
907
- console.log(`Status: ${activeCount}/${totalCount} CAWS hooks active`);
908
-
909
- if (activeCount < totalCount) {
910
- console.log('');
911
- console.log('To install missing hooks:');
912
- console.log(' caws scaffold');
913
- console.log('');
914
- console.log('To check detailed status:');
915
- console.log(' ls -la .git/hooks/');
916
- }
917
- }
918
-
919
- module.exports = {
920
- scaffoldGitHooks,
921
- removeGitHooks,
922
- checkGitHooksStatus,
923
- // Export generator functions for testing
924
- generatePrePushHook,
925
- generatePreCommitHook,
926
- generatePostCommitHook,
927
- generateCommitMsgHook,
928
- };