@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,1143 +0,0 @@
1
- /**
2
- * @fileoverview Provenance Command Handler
3
- * Manages CAWS provenance tracking and audit trails
4
- * @author @darianrosebrook
5
- */
6
-
7
- /* global fetch */
8
-
9
- const fs = require('fs-extra');
10
- const path = require('path');
11
- const crypto = require('crypto');
12
- const yaml = require('js-yaml');
13
- const { execSync } = require('child_process');
14
- const { commandWrapper } = require('../utils/command-wrapper');
15
- const { resolveSpec } = require('../utils/spec-resolver');
16
-
17
- async function resolveProvenanceSpec(options = {}) {
18
- try {
19
- return await resolveSpec({
20
- specId: options.specId,
21
- specFile: options.specFile,
22
- warnLegacy: false,
23
- });
24
- } catch (error) {
25
- const shouldFallbackToLegacy =
26
- !options.specId &&
27
- !options.specFile &&
28
- error.message.includes('schema violations');
29
-
30
- if (!shouldFallbackToLegacy) {
31
- throw error;
32
- }
33
-
34
- const legacyPath = path.join(process.cwd(), '.caws', 'working-spec.yaml');
35
- if (!(await fs.pathExists(legacyPath))) {
36
- throw error;
37
- }
38
-
39
- const legacyContent = await fs.readFile(legacyPath, 'utf8');
40
- const legacySpec = yaml.load(legacyContent);
41
-
42
- return {
43
- path: legacyPath,
44
- type: 'legacy',
45
- spec: legacySpec,
46
- degradedValidation: true,
47
- };
48
- }
49
- }
50
-
51
- /**
52
- * Get quality gates status from saved report
53
- * @returns {Object} Quality gates status
54
- */
55
- function getQualityGatesStatus() {
56
- const reportPath = path.join(process.cwd(), '.caws', 'quality-gates-report.json');
57
-
58
- if (fs.existsSync(reportPath)) {
59
- try {
60
- const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
61
- return {
62
- status: report.passed ? 'passing' : 'failing',
63
- last_validated: report.timestamp || new Date().toISOString(),
64
- violations: report.violations || 0,
65
- gates: report.gates || {}
66
- };
67
- } catch (error) {
68
- // Fall through to default
69
- }
70
- }
71
-
72
- return {
73
- status: 'not_validated',
74
- last_validated: null,
75
- violations: null
76
- };
77
- }
78
-
79
- /**
80
- * Provenance command handler
81
- * @param {string} subcommand - The subcommand to execute
82
- * @param {Object} options - Command options
83
- */
84
- async function provenanceCommand(subcommand, options) {
85
- return commandWrapper(
86
- async () => {
87
- switch (subcommand) {
88
- case 'update':
89
- return await updateProvenance(options);
90
- case 'show':
91
- return await showProvenance(options);
92
- case 'verify':
93
- return await verifyProvenance(options);
94
- case 'analyze-ai':
95
- return await analyzeAIProvenance(options);
96
- case 'init':
97
- return await initProvenance(options);
98
- case 'install-hooks':
99
- return await installHooks(options);
100
- default:
101
- throw new Error(
102
- `Unknown provenance subcommand: ${subcommand}.\n` +
103
- 'Available commands: update, show, verify, analyze-ai, init, install-hooks'
104
- );
105
- }
106
- },
107
- {
108
- commandName: `provenance ${subcommand}`,
109
- context: { subcommand, options },
110
- }
111
- );
112
- }
113
-
114
- /**
115
- * Update provenance with new commit information
116
- * @param {Object} options - Command options
117
- */
118
- async function updateProvenance(options) {
119
- const { commit, message, author, quiet = false, output = '.caws/provenance' } = options;
120
-
121
- if (!commit) {
122
- throw new Error('Commit hash is required for provenance update');
123
- }
124
-
125
- // Ensure output directory exists
126
- await fs.ensureDir(output);
127
-
128
- const resolved = await resolveProvenanceSpec(options);
129
- const spec = resolved.spec;
130
-
131
- // Load existing provenance chain
132
- const provenanceChain = await loadProvenanceChain(output);
133
-
134
- // Create new provenance entry
135
- const newEntry = {
136
- id: `prov-${Date.now()}`,
137
- timestamp: new Date().toISOString(),
138
- commit: {
139
- hash: commit,
140
- message: message || '',
141
- author: author || 'Unknown',
142
- },
143
- working_spec: {
144
- id: spec.id,
145
- title: spec.title,
146
- risk_tier: spec.risk_tier,
147
- mode: spec.mode,
148
- type: resolved.type,
149
- path: resolved.path,
150
- status: spec.status || null,
151
- waiver_ids: spec.waiver_ids || [],
152
- },
153
- quality_gates: getQualityGatesStatus(),
154
- agent: {
155
- type: detectAgentType(),
156
- confidence_level: null, // Would be populated by agent actions
157
- },
158
- cursor_tracking: await getCursorTrackingData(commit), // AI code tracking data
159
- checkpoints: await getCursorCheckpoints(), // Composer checkpoint data
160
- };
161
-
162
- // Calculate hash including previous chain
163
- const previousHash =
164
- provenanceChain.length > 0 ? provenanceChain[provenanceChain.length - 1].hash : '';
165
- newEntry.previous_hash = previousHash;
166
-
167
- const hashContent = JSON.stringify(
168
- {
169
- ...newEntry,
170
- hash: undefined, // Exclude hash from hash calculation
171
- },
172
- Object.keys(newEntry).sort()
173
- );
174
-
175
- newEntry.hash = crypto.createHash('sha256').update(hashContent).digest('hex');
176
-
177
- // Add to chain and save
178
- provenanceChain.push(newEntry);
179
- await saveProvenanceChain(provenanceChain, output);
180
-
181
- if (!quiet) {
182
- console.log(`Provenance updated for commit ${commit.substring(0, 8)}`);
183
- console.log(` Spec: ${spec.id} (${resolved.type}) -> ${resolved.path}`);
184
- if (resolved.degradedValidation) {
185
- console.log(' Note: using legacy spec metadata despite schema validation issues');
186
- }
187
- console.log(` Chain length: ${provenanceChain.length} entries`);
188
- console.log(` Hash: ${newEntry.hash.substring(0, 16)}...`);
189
- }
190
- }
191
-
192
- /**
193
- * Show current provenance information
194
- * @param {Object} options - Command options
195
- */
196
- async function showProvenance(options) {
197
- const { output = '.caws/provenance', format = 'text' } = options;
198
-
199
- const chain = await loadProvenanceChain(output);
200
-
201
- if (chain.length === 0) {
202
- if (format === 'dashboard') {
203
- console.log('┌- CAWS Provenance Dashboard ----------------------┐');
204
- console.log('│ No provenance data found │');
205
- console.log('│ │');
206
- console.log('│ Run "caws provenance init" to get started │');
207
- console.log('└-------------------------------------------------┘');
208
- } else {
209
- console.log('No provenance data found');
210
- console.log(`Run "caws provenance init" to get started`);
211
- }
212
- return;
213
- }
214
-
215
- if (format === 'json') {
216
- console.log(JSON.stringify(chain, null, 2));
217
- return;
218
- }
219
-
220
- if (format === 'dashboard') {
221
- await showDashboardFormat(chain, output);
222
- return;
223
- }
224
-
225
- console.log('CAWS Provenance Chain');
226
- console.log('==============================================');
227
- console.log(`Total entries: ${chain.length}`);
228
- console.log('');
229
-
230
- // Show last 5 entries
231
- const recent = chain.slice(-5);
232
- recent.forEach((entry, index) => {
233
- const commit = entry.commit.hash.substring(0, 8);
234
- const time = new Date(entry.timestamp).toLocaleString();
235
- const offset = chain.length - recent.length + index + 1;
236
-
237
- console.log(`${offset}. ${commit} - ${time}`);
238
- console.log(` ${entry.commit.message.split('\n')[0]}`);
239
- console.log(` ${entry.commit.author}`);
240
- if (entry.working_spec) {
241
- console.log(` Spec: ${entry.working_spec.id} (${entry.working_spec.risk_tier})`);
242
- }
243
- if (entry.agent && entry.agent.type !== 'human') {
244
- console.log(` Agent: ${entry.agent.type}`);
245
- }
246
-
247
- // Display AI code tracking if available
248
- if (entry.cursor_tracking && entry.cursor_tracking.available) {
249
- const tracking = entry.cursor_tracking;
250
- console.log(
251
- ` AI Code: ${tracking.ai_code_breakdown.composer_chat.percentage}% composer, ${tracking.ai_code_breakdown.tab_completions.percentage}% tab-complete, ${tracking.ai_code_breakdown.manual_human.percentage}% manual`
252
- );
253
- console.log(
254
- ` Quality: ${Math.round(tracking.quality_metrics.ai_code_quality_score * 100)}% AI score, ${Math.round(tracking.quality_metrics.acceptance_rate * 100)}% acceptance`
255
- );
256
- }
257
-
258
- // Display checkpoint info if available
259
- if (entry.checkpoints && entry.checkpoints.available && entry.checkpoints.checkpoints) {
260
- console.log(` Checkpoints: ${entry.checkpoints.checkpoints.length} created`);
261
- }
262
-
263
- console.log('');
264
- });
265
-
266
- if (chain.length > 5) {
267
- console.log(`... and ${chain.length - 5} earlier entries`);
268
- }
269
- }
270
-
271
- /**
272
- * Verify provenance chain integrity
273
- * @param {Object} options - Command options
274
- */
275
- async function verifyProvenance(options) {
276
- const { output = '.caws/provenance' } = options;
277
-
278
- const chain = await loadProvenanceChain(output);
279
-
280
- if (chain.length === 0) {
281
- console.log('No provenance data to verify');
282
- return;
283
- }
284
-
285
- console.log('Verifying provenance chain integrity...');
286
-
287
- let valid = true;
288
- for (let i = 0; i < chain.length; i++) {
289
- const entry = chain[i];
290
-
291
- // Verify hash integrity
292
- const expectedPreviousHash = i === 0 ? '' : chain[i - 1].hash;
293
- if (entry.previous_hash !== expectedPreviousHash) {
294
- console.error(`Chain break at entry ${i + 1}: previous hash mismatch`);
295
- valid = false;
296
- }
297
-
298
- // Recalculate and verify current hash
299
- const entryForHash = { ...entry };
300
- delete entryForHash.hash; // Remove hash field before calculation
301
-
302
- const hashContent = JSON.stringify(entryForHash, Object.keys(entryForHash).sort());
303
-
304
- const calculatedHash = crypto.createHash('sha256').update(hashContent).digest('hex');
305
-
306
- if (calculatedHash !== entry.hash) {
307
- console.error(`Hash verification failed at entry ${i + 1}`);
308
- console.error(` Expected: ${entry.hash}`);
309
- console.error(` Calculated: ${calculatedHash}`);
310
- valid = false;
311
- }
312
- }
313
-
314
- if (valid) {
315
- console.log('Provenance chain integrity verified');
316
- console.log(` ${chain.length} entries, all hashes valid`);
317
- } else {
318
- console.error('Provenance chain integrity compromised');
319
- process.exit(1);
320
- }
321
- }
322
-
323
- /**
324
- * Load existing provenance chain from files
325
- * @param {string} outputDir - Directory containing provenance files
326
- * @returns {Array} Array of provenance entries
327
- */
328
- async function loadProvenanceChain(outputDir) {
329
- const chainFile = path.join(outputDir, 'chain.json');
330
-
331
- if (!(await fs.pathExists(chainFile))) {
332
- return [];
333
- }
334
-
335
- try {
336
- const content = await fs.readFile(chainFile, 'utf8');
337
- return JSON.parse(content);
338
- } catch (error) {
339
- console.warn(`Warning: Could not load provenance chain: ${error.message}`);
340
- return [];
341
- }
342
- }
343
-
344
- /**
345
- * Save provenance chain to file
346
- * @param {Array} chain - Provenance entries array
347
- * @param {string} outputDir - Directory to save to
348
- */
349
- async function saveProvenanceChain(chain, outputDir) {
350
- const chainFile = path.join(outputDir, 'chain.json');
351
- await fs.writeFile(chainFile, JSON.stringify(chain, null, 2));
352
- }
353
-
354
- /**
355
- * Analyze AI patterns and effectiveness from provenance data
356
- * @param {Object} options - Command options
357
- */
358
- async function analyzeAIProvenance(options) {
359
- const { output = '.caws/provenance' } = options;
360
-
361
- const chain = await loadProvenanceChain(output);
362
-
363
- if (chain.length === 0) {
364
- console.log('No provenance data to analyze');
365
- return;
366
- }
367
-
368
- console.log('AI Code Effectiveness Analysis');
369
- console.log('==============================================');
370
-
371
- // Filter entries with AI tracking data
372
- const aiEntries = chain.filter(
373
- (entry) =>
374
- entry.cursor_tracking &&
375
- entry.cursor_tracking.available &&
376
- entry.agent &&
377
- entry.agent.type !== 'human'
378
- );
379
-
380
- if (aiEntries.length === 0) {
381
- console.log('No AI tracking data found in provenance');
382
- console.log('Configure CURSOR_TRACKING_API and CURSOR_CHECKPOINT_API environment variables');
383
- return;
384
- }
385
-
386
- console.log(`Analyzed ${aiEntries.length} AI-assisted commits`);
387
- console.log('');
388
-
389
- // Analyze AI code contribution patterns
390
- const contributionPatterns = analyzeContributionPatterns(aiEntries);
391
- const qualityMetrics = analyzeQualityMetrics(aiEntries);
392
- const checkpointAnalysis = analyzeCheckpointUsage(aiEntries);
393
-
394
- console.log('AI Contribution Patterns:');
395
- console.log(` Average Composer/Chat contribution: ${contributionPatterns.avgComposerPercent}%`);
396
- console.log(
397
- ` Average Tab completion contribution: ${contributionPatterns.avgTabCompletePercent}%`
398
- );
399
- console.log(` Average Manual override rate: ${contributionPatterns.avgManualPercent}%`);
400
- console.log('');
401
-
402
- console.log('Quality Metrics:');
403
- console.log(
404
- ` Average AI code quality score: ${Math.round(qualityMetrics.avgQualityScore * 100)}%`
405
- );
406
- console.log(` Average acceptance rate: ${Math.round(qualityMetrics.avgAcceptanceRate * 100)}%`);
407
- console.log(
408
- ` Average human override rate: ${Math.round(qualityMetrics.avgOverrideRate * 100)}%`
409
- );
410
- console.log('');
411
-
412
- console.log('Checkpoint Analysis:');
413
- console.log(
414
- ` Commits with checkpoints: ${checkpointAnalysis.entriesWithCheckpoints}/${aiEntries.length}`
415
- );
416
- console.log(` Average checkpoints per commit: ${checkpointAnalysis.avgCheckpointsPerEntry}`);
417
- console.log(` Checkpoint revert rate: ${Math.round(checkpointAnalysis.revertRate * 100)}%`);
418
- console.log('');
419
-
420
- // Provide insights and recommendations
421
- provideAIInsights(contributionPatterns, qualityMetrics, checkpointAnalysis);
422
- }
423
-
424
- /**
425
- * Analyze AI contribution patterns across entries
426
- */
427
- function analyzeContributionPatterns(aiEntries) {
428
- const contributions = aiEntries
429
- .filter((entry) => entry.cursor_tracking?.ai_code_breakdown)
430
- .map((entry) => entry.cursor_tracking.ai_code_breakdown);
431
-
432
- if (contributions.length === 0) return {};
433
-
434
- const avgComposer =
435
- contributions.reduce((sum, c) => sum + c.composer_chat.percentage, 0) / contributions.length;
436
- const avgTab =
437
- contributions.reduce((sum, c) => sum + c.tab_completions.percentage, 0) / contributions.length;
438
- const avgManual =
439
- contributions.reduce((sum, c) => sum + c.manual_human.percentage, 0) / contributions.length;
440
-
441
- return {
442
- avgComposerPercent: Math.round(avgComposer),
443
- avgTabCompletePercent: Math.round(avgTab),
444
- avgManualPercent: Math.round(avgManual),
445
- };
446
- }
447
-
448
- /**
449
- * Analyze AI quality metrics across entries
450
- */
451
- function analyzeQualityMetrics(aiEntries) {
452
- const metrics = aiEntries
453
- .filter((entry) => entry.cursor_tracking?.quality_metrics)
454
- .map((entry) => entry.cursor_tracking.quality_metrics);
455
-
456
- if (metrics.length === 0) return {};
457
-
458
- const avgQuality = metrics.reduce((sum, m) => sum + m.ai_code_quality_score, 0) / metrics.length;
459
- const avgAcceptance = metrics.reduce((sum, m) => sum + m.acceptance_rate, 0) / metrics.length;
460
- const avgOverride = metrics.reduce((sum, m) => sum + m.human_override_rate, 0) / metrics.length;
461
-
462
- return {
463
- avgQualityScore: avgQuality,
464
- avgAcceptanceRate: avgAcceptance,
465
- avgOverrideRate: avgOverride,
466
- };
467
- }
468
-
469
- /**
470
- * Analyze checkpoint usage patterns
471
- */
472
- /**
473
- * Calculate actual revert rate from git history
474
- * Analyzes commits for revert patterns and calculates the percentage
475
- * @param {number} maxCommits - Maximum number of commits to analyze
476
- * @returns {number} Revert rate as a decimal (0.0 - 1.0)
477
- */
478
- function calculateRevertRate(maxCommits = 500) {
479
- try {
480
- // Get total commit count (limited)
481
- const logOutput = execSync(`git log --oneline -n ${maxCommits} 2>/dev/null`, {
482
- encoding: 'utf8',
483
- cwd: process.cwd(),
484
- }).trim();
485
-
486
- if (!logOutput) {
487
- return 0;
488
- }
489
-
490
- const totalCommits = logOutput.split('\n').filter(Boolean).length;
491
-
492
- // Count revert commits (commits with "revert" in the message)
493
- const revertOutput = execSync(
494
- `git log --oneline -n ${maxCommits} --grep="[Rr]evert" 2>/dev/null || true`,
495
- {
496
- encoding: 'utf8',
497
- cwd: process.cwd(),
498
- }
499
- ).trim();
500
-
501
- const revertCommits = revertOutput ? revertOutput.split('\n').filter(Boolean).length : 0;
502
-
503
- // Also check for reset/force-push patterns in reflog if available
504
- let additionalReverts = 0;
505
- try {
506
- const reflogOutput = execSync(`git reflog --oneline -n ${maxCommits} 2>/dev/null || true`, {
507
- encoding: 'utf8',
508
- cwd: process.cwd(),
509
- }).trim();
510
-
511
- if (reflogOutput) {
512
- const reflogLines = reflogOutput.split('\n').filter(Boolean);
513
- additionalReverts = reflogLines.filter(
514
- (line) => line.includes('reset:') || line.includes('checkout:')
515
- ).length;
516
- // Weight reflog reverts less since they may not be actual code reverts
517
- additionalReverts = Math.floor(additionalReverts * 0.1);
518
- }
519
- } catch {
520
- // Reflog not available or failed
521
- }
522
-
523
- const totalReverts = revertCommits + additionalReverts;
524
- const revertRate = totalCommits > 0 ? totalReverts / totalCommits : 0;
525
-
526
- return Math.min(1.0, revertRate); // Cap at 100%
527
- } catch {
528
- // Git not available or not a repo
529
- return 0;
530
- }
531
- }
532
-
533
- function analyzeCheckpointUsage(aiEntries) {
534
- const entriesWithCheckpoints = aiEntries.filter(
535
- (entry) => entry.checkpoints?.available && entry.checkpoints.checkpoints?.length > 0
536
- ).length;
537
-
538
- const totalCheckpoints = aiEntries
539
- .filter((entry) => entry.checkpoints?.available)
540
- .reduce((sum, entry) => sum + (entry.checkpoints.checkpoints?.length || 0), 0);
541
-
542
- // Calculate actual revert rate from git history
543
- const revertRate = calculateRevertRate();
544
-
545
- return {
546
- entriesWithCheckpoints,
547
- avgCheckpointsPerEntry:
548
- entriesWithCheckpoints > 0 ? (totalCheckpoints / entriesWithCheckpoints).toFixed(1) : 0,
549
- revertRate,
550
- };
551
- }
552
-
553
- /**
554
- * Install git hooks for automatic provenance updates
555
- * @param {Object} options - Command options
556
- */
557
- async function installHooks(options) {
558
- const { output = '.caws/provenance', skipPreCommit = false, skipPostCommit = false } = options;
559
-
560
- console.log('Installing CAWS Provenance Git Hooks');
561
- console.log('==================================================');
562
-
563
- // Check if we're in a git repository
564
- if (!(await fs.pathExists('.git'))) {
565
- console.log('Not in a git repository');
566
- console.log('Initialize git first: git init');
567
- process.exit(1);
568
- }
569
-
570
- // Check if provenance is initialized
571
- if (!(await fs.pathExists(path.join(output, 'chain.json')))) {
572
- console.log('Provenance not initialized');
573
- console.log('Run "caws provenance init" first');
574
- process.exit(1);
575
- }
576
-
577
- console.log('Found git repository and provenance setup');
578
-
579
- // Ensure hooks directory exists
580
- const hooksDir = '.git/hooks';
581
- await fs.ensureDir(hooksDir);
582
- console.log('Ensured hooks directory exists');
583
-
584
- let hooksInstalled = 0;
585
-
586
- // Install pre-commit hook for validation
587
- if (!skipPreCommit) {
588
- try {
589
- const preCommitHook = await createPreCommitHook(output);
590
- const preCommitPath = path.join(hooksDir, 'pre-commit');
591
-
592
- await fs.writeFile(preCommitPath, preCommitHook);
593
- await fs.chmod(preCommitPath, '755');
594
- console.log('Installed pre-commit hook for provenance validation');
595
- hooksInstalled++;
596
- } catch (error) {
597
- console.warn('Failed to install pre-commit hook:', error.message);
598
- }
599
- }
600
-
601
- // Install post-commit hook for provenance updates
602
- if (!skipPostCommit) {
603
- try {
604
- const postCommitHook = await createPostCommitHook(output);
605
- const postCommitPath = path.join(hooksDir, 'post-commit');
606
-
607
- await fs.writeFile(postCommitPath, postCommitHook);
608
- await fs.chmod(postCommitPath, '755');
609
- console.log('Installed post-commit hook for provenance updates');
610
- hooksInstalled++;
611
- } catch (error) {
612
- console.warn('Failed to install post-commit hook:', error.message);
613
- }
614
- }
615
-
616
- console.log('');
617
- console.log('Git hooks installation complete!');
618
- console.log('');
619
- console.log(`Installed ${hooksInstalled} hook(s):`);
620
- if (!skipPreCommit) {
621
- console.log(' - pre-commit: Validates provenance before commits');
622
- }
623
- if (!skipPostCommit) {
624
- console.log(' - post-commit: Updates provenance after commits');
625
- }
626
- console.log('');
627
- console.log('Your commits will now automatically maintain provenance!');
628
- console.log(' Run "caws provenance show" to view the updated chain');
629
- }
630
-
631
- /**
632
- * Create pre-commit hook script for provenance validation
633
- * @param {string} outputDir - Provenance output directory
634
- * @returns {string} Hook script content
635
- */
636
- async function createPreCommitHook(outputDir) {
637
- const scriptPath = path.resolve('node_modules/.bin/caws');
638
- const fallbackPath = path.resolve('packages/caws-cli/dist/index.js');
639
-
640
- return `#!/bin/sh
641
- # CAWS Provenance Pre-commit Hook
642
- # Validates provenance integrity before allowing commits
643
-
644
- echo "Validating CAWS provenance..."
645
-
646
- # Find caws CLI
647
- if command -v caws >/dev/null 2>&1; then
648
- CAWS_CMD="caws"
649
- elif [ -x "${scriptPath}" ]; then
650
- CAWS_CMD="${scriptPath}"
651
- elif [ -x "${fallbackPath}" ]; then
652
- CAWS_CMD="node ${fallbackPath}"
653
- else
654
- echo "CAWS CLI not found, skipping provenance validation"
655
- exit 0
656
- fi
657
-
658
- # Run provenance verification
659
- if $CAWS_CMD provenance verify --output "${outputDir}" >/dev/null 2>&1; then
660
- echo "Provenance validation passed"
661
- exit 0
662
- else
663
- echo "Provenance validation failed"
664
- echo "Run 'caws provenance show' to investigate"
665
- exit 1
666
- fi
667
- `;
668
- }
669
-
670
- /**
671
- * Create post-commit hook script for provenance updates
672
- * @param {string} outputDir - Provenance output directory
673
- * @returns {string} Hook script content
674
- */
675
- async function createPostCommitHook(outputDir) {
676
- const scriptPath = path.resolve('node_modules/.bin/caws');
677
- const fallbackPath = path.resolve('packages/caws-cli/dist/index.js');
678
-
679
- return `#!/bin/sh
680
- # CAWS Provenance Post-commit Hook
681
- # Updates provenance chain after successful commits
682
-
683
- echo "Updating CAWS provenance..."
684
-
685
- # Get the current commit hash
686
- COMMIT_HASH=$(git rev-parse HEAD)
687
- COMMIT_MSG=$(git log -1 --pretty=%B | head -n 1)
688
- AUTHOR=$(git log -1 --pretty=%an)
689
-
690
- # Find caws CLI
691
- if command -v caws >/dev/null 2>&1; then
692
- CAWS_CMD="caws"
693
- elif [ -x "${scriptPath}" ]; then
694
- CAWS_CMD="${scriptPath}"
695
- elif [ -x "${fallbackPath}" ]; then
696
- CAWS_CMD="node ${fallbackPath}"
697
- else
698
- echo "CAWS CLI not found, skipping provenance update"
699
- exit 0
700
- fi
701
-
702
- # Update provenance
703
- if $CAWS_CMD provenance update --commit "$COMMIT_HASH" --message "$COMMIT_MSG" --author "$AUTHOR" --output "${outputDir}" --quiet; then
704
- echo "Provenance updated for commit \${COMMIT_HASH:0:8}"
705
- else
706
- echo "Failed to update provenance (non-fatal)"
707
- fi
708
-
709
- exit 0
710
- `;
711
- }
712
-
713
- /**
714
- * Show provenance data in dashboard format
715
- * @param {Array} chain - Provenance chain entries
716
- * @param {string} outputDir - Output directory path
717
- */
718
- async function showDashboardFormat(chain, outputDir) {
719
- // Calculate key metrics
720
- const totalEntries = chain.length;
721
- const aiEntries = chain.filter(
722
- (entry) => entry.cursor_tracking?.available && entry.agent?.type !== 'human'
723
- ).length;
724
-
725
- const avgQualityScore =
726
- aiEntries > 0
727
- ? chain
728
- .filter((entry) => entry.cursor_tracking?.quality_metrics?.ai_code_quality_score)
729
- .reduce(
730
- (sum, entry) => sum + entry.cursor_tracking.quality_metrics.ai_code_quality_score,
731
- 0
732
- ) /
733
- chain.filter((entry) => entry.cursor_tracking?.quality_metrics?.ai_code_quality_score)
734
- .length
735
- : 0;
736
-
737
- const avgAcceptanceRate =
738
- aiEntries > 0
739
- ? chain
740
- .filter((entry) => entry.cursor_tracking?.quality_metrics?.acceptance_rate)
741
- .reduce((sum, entry) => sum + entry.cursor_tracking.quality_metrics.acceptance_rate, 0) /
742
- chain.filter((entry) => entry.cursor_tracking?.quality_metrics?.acceptance_rate).length
743
- : 0;
744
-
745
- // Check config
746
- let configStatus = 'Not configured';
747
- try {
748
- const configPath = path.join(outputDir, 'config.json');
749
- if (await fs.pathExists(configPath)) {
750
- const config = JSON.parse(await fs.readFile(configPath, 'utf8'));
751
- const configured = [
752
- config.cursor_tracking_api !== 'not_configured',
753
- config.cursor_checkpoint_api !== 'not_configured',
754
- config.cursor_project_id !== 'not_configured',
755
- ].filter(Boolean).length;
756
- configStatus = configured === 3 ? 'Fully configured' : `${configured}/3 configured`;
757
- }
758
- } catch (error) {
759
- // Ignore config read errors
760
- }
761
-
762
- // Display dashboard
763
- console.log('┌- CAWS Provenance Dashboard ----------------------┐');
764
- console.log(`│ Total Entries: ${totalEntries.toString().padEnd(33)} │`);
765
- console.log(`│ AI-Assisted: ${aiEntries.toString().padEnd(35)} │`);
766
- console.log(
767
- `│ Avg Quality: ${(avgQualityScore * 100).toFixed(0).padEnd(2)}%${' '.repeat(33)} │`
768
- );
769
- console.log(
770
- `│ Avg Acceptance: ${(avgAcceptanceRate * 100).toFixed(0).padEnd(2)}%${' '.repeat(30)} │`
771
- );
772
- console.log(`│ Config Status: ${configStatus.padEnd(31)} │`);
773
- console.log('├-------------------------------------------------┤');
774
-
775
- if (totalEntries > 0) {
776
- console.log('│ Recent Activity: │');
777
- const recent = chain.slice(-3);
778
- recent.forEach((entry, index) => {
779
- const commit = entry.commit.hash.substring(0, 8);
780
- const time = new Date(entry.timestamp).toLocaleDateString();
781
- const msg = entry.commit.message.split('\n')[0].substring(0, 30);
782
- const line = `${index + 1}. ${commit} ${time} ${msg}`;
783
- console.log(`│ ${line.padEnd(47)} │`);
784
- });
785
-
786
- if (aiEntries > 0) {
787
- console.log('├-------------------------------------------------┤');
788
- console.log('│ AI Contribution Breakdown: │');
789
-
790
- const contributions = chain
791
- .filter((entry) => entry.cursor_tracking?.ai_code_breakdown)
792
- .map((entry) => entry.cursor_tracking.ai_code_breakdown);
793
-
794
- if (contributions.length > 0) {
795
- const avgComposer =
796
- contributions.reduce((sum, c) => sum + c.composer_chat.percentage, 0) /
797
- contributions.length;
798
- const avgTab =
799
- contributions.reduce((sum, c) => sum + c.tab_completions.percentage, 0) /
800
- contributions.length;
801
- const avgManual =
802
- contributions.reduce((sum, c) => sum + c.manual_human.percentage, 0) /
803
- contributions.length;
804
-
805
- const composerBar = '█'.repeat(Math.round(avgComposer / 5));
806
- const tabBar = '█'.repeat(Math.round(avgTab / 5));
807
- const manualBar = '█'.repeat(Math.round(avgManual / 5));
808
-
809
- console.log(
810
- `│ Composer/Chat: ${composerBar.padEnd(10)} ${Math.round(avgComposer).toString().padStart(2)}%${' '.repeat(18)} │`
811
- );
812
- console.log(
813
- `│ Tab Complete: ${tabBar.padEnd(10)} ${Math.round(avgTab).toString().padStart(2)}%${' '.repeat(18)} │`
814
- );
815
- console.log(
816
- `│ Manual: ${manualBar.padEnd(10)} ${Math.round(avgManual).toString().padStart(2)}%${' '.repeat(18)} │`
817
- );
818
- }
819
- }
820
- }
821
-
822
- console.log('└-------------------------------------------------┘');
823
-
824
- // Add insights
825
- if (aiEntries > 0) {
826
- console.log('');
827
- console.log('Insights:');
828
- if (avgAcceptanceRate > 0.9) {
829
- console.log(' High AI acceptance rate indicates effective collaboration');
830
- } else if (avgAcceptanceRate < 0.7) {
831
- console.log(' Lower acceptance rate may indicate AI refinement needed');
832
- }
833
-
834
- if (avgQualityScore > 0.8) {
835
- console.log(' Excellent AI code quality - great results!');
836
- }
837
- }
838
- }
839
-
840
- /**
841
- * Provide insights and recommendations based on AI analysis
842
- */
843
- function provideAIInsights(contributionPatterns, qualityMetrics, checkpointAnalysis) {
844
- console.log('AI Effectiveness Insights:');
845
-
846
- if (contributionPatterns.avgComposerPercent > 60) {
847
- console.log(' High Composer usage suggests complex feature development');
848
- console.log(' → Consider breaking large features into smaller, focused sessions');
849
- }
850
-
851
- if (qualityMetrics.avgOverrideRate > 0.2) {
852
- console.log(' High human override rate indicates AI suggestions need refinement');
853
- console.log(' → Review AI confidence thresholds or provide clearer requirements');
854
- }
855
-
856
- if (checkpointAnalysis.avgCheckpointsPerEntry < 2) {
857
- console.log(' Low checkpoint usage may limit ability to recover from bad AI directions');
858
- console.log(' → Encourage more frequent checkpointing in Composer sessions');
859
- }
860
-
861
- if (qualityMetrics.avgAcceptanceRate > 0.9) {
862
- console.log(' High acceptance rate indicates effective AI assistance');
863
- console.log(' → Current AI integration is working well');
864
- }
865
-
866
- console.log('');
867
- console.log('Recommendations:');
868
- console.log(
869
- ` - Target Composer contribution: ${Math.max(40, contributionPatterns.avgComposerPercent - 10)}-${Math.min(80, contributionPatterns.avgComposerPercent + 10)}%`
870
- );
871
- console.log(
872
- ` - Acceptable override rate: <${Math.round((qualityMetrics.avgOverrideRate + 0.1) * 100)}%`
873
- );
874
- console.log(' - Checkpoint frequency: Every 10-15 minutes in active sessions');
875
- }
876
-
877
- /**
878
- * Get Cursor AI code tracking data for a commit
879
- * Uses Cursor's AI Code Tracking API (Enterprise feature)
880
- * @see https://cursor.com/docs/account/teams/ai-code-tracking-api
881
- * @param {string} commitHash - Git commit hash to analyze
882
- * @returns {Promise<Object>} AI code tracking data
883
- */
884
- async function getCursorTrackingData(commitHash) {
885
- const apiUrl = process.env.CURSOR_TRACKING_API;
886
- const apiKey = process.env.CURSOR_API_KEY;
887
-
888
- if (!apiUrl || !apiKey) {
889
- return {
890
- available: false,
891
- reason: 'Cursor API not configured. Set CURSOR_TRACKING_API and CURSOR_API_KEY environment variables.',
892
- documentation: 'https://cursor.com/docs/account/teams/ai-code-tracking-api'
893
- };
894
- }
895
-
896
- try {
897
- // Basic auth: base64(apiKey:) - Cursor API uses API key with empty password
898
- const auth = Buffer.from(`${apiKey}:`).toString('base64');
899
-
900
- const response = await fetch(`${apiUrl}/analytics/ai-code/commits`, {
901
- method: 'GET',
902
- headers: {
903
- 'Authorization': `Basic ${auth}`,
904
- 'Content-Type': 'application/json',
905
- }
906
- });
907
-
908
- if (!response.ok) {
909
- return {
910
- available: false,
911
- reason: `Cursor API error: ${response.status} ${response.statusText}`
912
- };
913
- }
914
-
915
- const data = await response.json();
916
-
917
- // Find commit-specific data if available
918
- const commitData = data.commits?.find(c => c.commit_hash === commitHash) || data;
919
-
920
- // Transform API response to our internal format
921
- return {
922
- available: true,
923
- commit_hash: commitHash,
924
- ai_code_breakdown: commitData.ai_code_breakdown || {
925
- tab_completions: { lines_added: 0, percentage: 0, files_affected: [] },
926
- composer_chat: { lines_added: 0, percentage: 0, files_affected: [], checkpoints_created: 0 },
927
- manual_human: { lines_added: 0, percentage: 0, files_affected: [] },
928
- },
929
- change_groups: commitData.change_groups || [],
930
- quality_metrics: commitData.quality_metrics || {
931
- ai_code_quality_score: 0,
932
- human_override_rate: 0,
933
- acceptance_rate: 0,
934
- },
935
- };
936
- } catch (error) {
937
- return {
938
- available: false,
939
- error: error.message,
940
- reason: 'Failed to retrieve Cursor tracking data',
941
- };
942
- }
943
- }
944
-
945
- /**
946
- * Initialize provenance tracking for the project
947
- * @param {Object} options - Command options
948
- */
949
- async function initProvenance(options) {
950
- const { output = '.caws/provenance', cursorApi } = options;
951
-
952
- console.log('Initializing CAWS Provenance Tracking');
953
- console.log('===================================================');
954
-
955
- // Check if already initialized
956
- if (await fs.pathExists(path.join(output, 'chain.json'))) {
957
- console.log('Provenance already initialized');
958
- console.log(` Chain exists at: ${output}/chain.json`);
959
- console.log('');
960
- console.log('To reset, delete the provenance directory and run again');
961
- return;
962
- }
963
-
964
- // Ensure output directory exists
965
- await fs.ensureDir(output);
966
- console.log(`Created provenance directory: ${output}`);
967
-
968
- const resolved = await resolveProvenanceSpec(options);
969
- console.log(`Found CAWS spec: ${resolved.spec.id} (${resolved.type})`);
970
- if (resolved.degradedValidation) {
971
- console.log(' Proceeding with legacy spec metadata despite schema validation issues');
972
- }
973
-
974
- // Initialize empty chain
975
- const initialChain = [];
976
- await saveProvenanceChain(initialChain, output);
977
- console.log('Initialized empty provenance chain');
978
-
979
- // Create environment configuration hints
980
- const envConfig = {
981
- spec: {
982
- id: resolved.spec.id,
983
- path: resolved.path,
984
- type: resolved.type,
985
- },
986
- cursor_tracking_api: cursorApi || process.env.CURSOR_TRACKING_API || 'not_configured',
987
- cursor_checkpoint_api: process.env.CURSOR_CHECKPOINT_API || 'not_configured',
988
- cursor_project_id: process.env.CURSOR_PROJECT_ID || 'not_configured',
989
- notes: [
990
- 'Configure CURSOR_TRACKING_API for AI code tracking',
991
- 'Configure CURSOR_CHECKPOINT_API for session recovery data',
992
- 'Configure CURSOR_PROJECT_ID to link with Cursor IDE',
993
- ],
994
- };
995
-
996
- await fs.writeFile(path.join(output, 'config.json'), JSON.stringify(envConfig, null, 2));
997
- console.log('Created configuration template');
998
-
999
- console.log('');
1000
- console.log('Provenance tracking initialized!');
1001
- console.log('');
1002
- console.log('Next steps:');
1003
- console.log('1. Install git hooks for automatic provenance (recommended):');
1004
- console.log(' caws provenance install-hooks');
1005
- console.log('');
1006
- console.log('2. Configure environment variables (optional):');
1007
- console.log(' export CURSOR_TRACKING_API="your-api-endpoint"');
1008
- console.log(' export CURSOR_CHECKPOINT_API="your-checkpoint-endpoint"');
1009
- console.log(' export CURSOR_PROJECT_ID="your-project-id"');
1010
- console.log('');
1011
- console.log('3. Manual provenance updates (if not using hooks):');
1012
- console.log(' caws provenance update --commit <hash>');
1013
- console.log('');
1014
- console.log('4. View provenance history:');
1015
- console.log(' caws provenance show');
1016
- }
1017
-
1018
- /**
1019
- * Get Cursor Composer/Chat checkpoint data
1020
- * Reads from local .cursor/ directory since checkpoints are stored locally by Cursor Agent
1021
- * @returns {Promise<Object>} Checkpoint data
1022
- */
1023
- async function getCursorCheckpoints() {
1024
- const cursorDir = path.join(process.cwd(), '.cursor');
1025
-
1026
- if (!fs.existsSync(cursorDir)) {
1027
- return {
1028
- available: false,
1029
- reason: 'No .cursor directory found. Checkpoints are only available when using Cursor IDE.'
1030
- };
1031
- }
1032
-
1033
- try {
1034
- // Look for checkpoint metadata in .cursor directory
1035
- // Cursor stores checkpoints locally during Composer/Agent sessions
1036
- const checkpointPatterns = [
1037
- '.cursor/**/checkpoint*.json',
1038
- '.cursor/**/checkpoints.json',
1039
- '.cursor/composer/checkpoints/*.json',
1040
- '.cursor/agent/checkpoints/*.json',
1041
- ];
1042
-
1043
- let checkpointFiles = [];
1044
- for (const pattern of checkpointPatterns) {
1045
- const glob = require('glob');
1046
- const matches = glob.sync(pattern, { cwd: process.cwd(), absolute: true });
1047
- checkpointFiles = checkpointFiles.concat(matches);
1048
- }
1049
-
1050
- // Remove duplicates
1051
- checkpointFiles = [...new Set(checkpointFiles)];
1052
-
1053
- if (checkpointFiles.length === 0) {
1054
- return {
1055
- available: false,
1056
- reason: 'No checkpoints found in current session. Checkpoints are created during Cursor Composer/Agent sessions.'
1057
- };
1058
- }
1059
-
1060
- // Parse checkpoint files and aggregate data
1061
- const checkpoints = [];
1062
- for (const file of checkpointFiles) {
1063
- try {
1064
- const content = await fs.readFile(file, 'utf8');
1065
- const data = JSON.parse(content);
1066
-
1067
- // Handle both single checkpoint and array of checkpoints
1068
- if (Array.isArray(data)) {
1069
- checkpoints.push(...data);
1070
- } else if (data.checkpoints) {
1071
- checkpoints.push(...data.checkpoints);
1072
- } else if (data.id || data.timestamp) {
1073
- checkpoints.push(data);
1074
- }
1075
- } catch (parseError) {
1076
- // Skip invalid checkpoint files
1077
- continue;
1078
- }
1079
- }
1080
-
1081
- if (checkpoints.length === 0) {
1082
- return {
1083
- available: false,
1084
- reason: 'No valid checkpoints found in checkpoint files.'
1085
- };
1086
- }
1087
-
1088
- // Sort by timestamp (newest first)
1089
- checkpoints.sort((a, b) => {
1090
- const timeA = new Date(a.timestamp || 0).getTime();
1091
- const timeB = new Date(b.timestamp || 0).getTime();
1092
- return timeB - timeA;
1093
- });
1094
-
1095
- // Mark latest checkpoint as non-revertible
1096
- if (checkpoints.length > 0) {
1097
- checkpoints[0].can_revert = false;
1098
- }
1099
-
1100
- return { available: true, checkpoints };
1101
- } catch (error) {
1102
- return {
1103
- available: false,
1104
- error: error.message,
1105
- reason: 'Failed to read Cursor checkpoint data',
1106
- };
1107
- }
1108
- }
1109
-
1110
- /**
1111
- * Attempt to detect the type of agent/system making changes
1112
- * @returns {string} Agent type identifier
1113
- */
1114
- function detectAgentType() {
1115
- // Check environment variables and context clues
1116
- if (
1117
- process.env.CURSOR_AGENT === 'true' ||
1118
- process.env.CURSOR_TRACKING_API ||
1119
- process.env.CURSOR_CHECKPOINT_API
1120
- ) {
1121
- return 'cursor-ide';
1122
- }
1123
-
1124
- if (process.env.GITHUB_ACTIONS === 'true') {
1125
- return 'github-actions';
1126
- }
1127
-
1128
- if (process.env.CI === 'true') {
1129
- return 'ci-system';
1130
- }
1131
-
1132
- // Default to human unless we can detect otherwise
1133
- return 'human';
1134
- }
1135
-
1136
- module.exports = {
1137
- provenanceCommand,
1138
- updateProvenance,
1139
- showProvenance,
1140
- verifyProvenance,
1141
- initProvenance,
1142
- installHooks,
1143
- };