@paths.design/caws-cli 10.2.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (421) hide show
  1. package/README.md +125 -374
  2. package/dist/index.js +43 -785
  3. package/dist/shell/binding/resolve-binding.d.ts +4 -0
  4. package/dist/shell/binding/resolve-binding.d.ts.map +1 -0
  5. package/dist/shell/binding/resolve-binding.js +228 -0
  6. package/dist/shell/binding/resolve-binding.js.map +1 -0
  7. package/dist/shell/binding/types.d.ts +42 -0
  8. package/dist/shell/binding/types.d.ts.map +1 -0
  9. package/dist/shell/binding/types.js +21 -0
  10. package/dist/shell/binding/types.js.map +1 -0
  11. package/dist/shell/commands/claim.d.ts +14 -0
  12. package/dist/shell/commands/claim.d.ts.map +1 -0
  13. package/dist/shell/commands/claim.js +197 -0
  14. package/dist/shell/commands/claim.js.map +1 -0
  15. package/dist/shell/commands/doctor.d.ts +13 -0
  16. package/dist/shell/commands/doctor.d.ts.map +1 -0
  17. package/dist/shell/commands/doctor.js +97 -0
  18. package/dist/shell/commands/doctor.js.map +1 -0
  19. package/dist/shell/commands/evidence.d.ts +28 -0
  20. package/dist/shell/commands/evidence.d.ts.map +1 -0
  21. package/dist/shell/commands/evidence.js +166 -0
  22. package/dist/shell/commands/evidence.js.map +1 -0
  23. package/dist/shell/commands/gates.d.ts +19 -0
  24. package/dist/shell/commands/gates.d.ts.map +1 -0
  25. package/dist/shell/commands/gates.js +181 -0
  26. package/dist/shell/commands/gates.js.map +1 -0
  27. package/dist/shell/commands/init.d.ts +8 -0
  28. package/dist/shell/commands/init.d.ts.map +1 -0
  29. package/dist/shell/commands/init.js +64 -0
  30. package/dist/shell/commands/init.js.map +1 -0
  31. package/dist/shell/commands/scope.d.ts +11 -0
  32. package/dist/shell/commands/scope.d.ts.map +1 -0
  33. package/dist/shell/commands/scope.js +92 -0
  34. package/dist/shell/commands/scope.js.map +1 -0
  35. package/dist/shell/commands/status.d.ts +15 -0
  36. package/dist/shell/commands/status.d.ts.map +1 -0
  37. package/dist/shell/commands/status.js +106 -0
  38. package/dist/shell/commands/status.js.map +1 -0
  39. package/dist/shell/commands/waiver.d.ts +38 -0
  40. package/dist/shell/commands/waiver.d.ts.map +1 -0
  41. package/dist/shell/commands/waiver.js +240 -0
  42. package/dist/shell/commands/waiver.js.map +1 -0
  43. package/dist/shell/gates/disposition.d.ts +23 -0
  44. package/dist/shell/gates/disposition.d.ts.map +1 -0
  45. package/dist/shell/gates/disposition.js +87 -0
  46. package/dist/shell/gates/disposition.js.map +1 -0
  47. package/dist/shell/gates/gate-result-contract.d.ts +39 -0
  48. package/dist/shell/gates/gate-result-contract.d.ts.map +1 -0
  49. package/dist/shell/gates/gate-result-contract.js +150 -0
  50. package/dist/shell/gates/gate-result-contract.js.map +1 -0
  51. package/dist/shell/gates/quality-gates-adapter.d.ts +55 -0
  52. package/dist/shell/gates/quality-gates-adapter.d.ts.map +1 -0
  53. package/dist/shell/gates/quality-gates-adapter.js +161 -0
  54. package/dist/shell/gates/quality-gates-adapter.js.map +1 -0
  55. package/dist/shell/gates/waiver-filter.d.ts +58 -0
  56. package/dist/shell/gates/waiver-filter.d.ts.map +1 -0
  57. package/dist/shell/gates/waiver-filter.js +119 -0
  58. package/dist/shell/gates/waiver-filter.js.map +1 -0
  59. package/dist/shell/index.d.ts +50 -0
  60. package/dist/shell/index.d.ts.map +1 -0
  61. package/dist/shell/index.js +73 -0
  62. package/dist/shell/index.js.map +1 -0
  63. package/dist/shell/register.d.ts +11 -0
  64. package/dist/shell/register.d.ts.map +1 -0
  65. package/dist/shell/register.js +274 -0
  66. package/dist/shell/register.js.map +1 -0
  67. package/dist/shell/render/claim.d.ts +22 -0
  68. package/dist/shell/render/claim.d.ts.map +1 -0
  69. package/dist/shell/render/claim.js +75 -0
  70. package/dist/shell/render/claim.js.map +1 -0
  71. package/dist/shell/render/decision.d.ts +15 -0
  72. package/dist/shell/render/decision.d.ts.map +1 -0
  73. package/dist/shell/render/decision.js +66 -0
  74. package/dist/shell/render/decision.js.map +1 -0
  75. package/dist/shell/render/diagnostic.d.ts +19 -0
  76. package/dist/shell/render/diagnostic.d.ts.map +1 -0
  77. package/dist/shell/render/diagnostic.js +76 -0
  78. package/dist/shell/render/diagnostic.js.map +1 -0
  79. package/dist/shell/render/finding.d.ts +15 -0
  80. package/dist/shell/render/finding.d.ts.map +1 -0
  81. package/dist/shell/render/finding.js +57 -0
  82. package/dist/shell/render/finding.js.map +1 -0
  83. package/dist/shell/render/gates.d.ts +3 -0
  84. package/dist/shell/render/gates.d.ts.map +1 -0
  85. package/dist/shell/render/gates.js +56 -0
  86. package/dist/shell/render/gates.js.map +1 -0
  87. package/dist/shell/render/init.d.ts +11 -0
  88. package/dist/shell/render/init.d.ts.map +1 -0
  89. package/dist/shell/render/init.js +32 -0
  90. package/dist/shell/render/init.js.map +1 -0
  91. package/dist/shell/render/status.d.ts +26 -0
  92. package/dist/shell/render/status.d.ts.map +1 -0
  93. package/dist/shell/render/status.js +143 -0
  94. package/dist/shell/render/status.js.map +1 -0
  95. package/dist/shell/render/waiver.d.ts +21 -0
  96. package/dist/shell/render/waiver.d.ts.map +1 -0
  97. package/dist/shell/render/waiver.js +94 -0
  98. package/dist/shell/render/waiver.js.map +1 -0
  99. package/dist/shell/rules.d.ts +37 -0
  100. package/dist/shell/rules.d.ts.map +1 -0
  101. package/dist/shell/rules.js +51 -0
  102. package/dist/shell/rules.js.map +1 -0
  103. package/dist/shell/session/actor.d.ts +14 -0
  104. package/dist/shell/session/actor.d.ts.map +1 -0
  105. package/dist/shell/session/actor.js +34 -0
  106. package/dist/shell/session/actor.js.map +1 -0
  107. package/dist/shell/session/resolve-session.d.ts +5 -0
  108. package/dist/shell/session/resolve-session.d.ts.map +1 -0
  109. package/dist/shell/session/resolve-session.js +239 -0
  110. package/dist/shell/session/resolve-session.js.map +1 -0
  111. package/dist/shell/session/types.d.ts +56 -0
  112. package/dist/shell/session/types.d.ts.map +1 -0
  113. package/dist/shell/session/types.js +15 -0
  114. package/dist/shell/session/types.js.map +1 -0
  115. package/dist/store/agents-store.d.ts +3 -0
  116. package/dist/store/agents-store.d.ts.map +1 -0
  117. package/dist/store/agents-store.js +63 -0
  118. package/dist/store/agents-store.js.map +1 -0
  119. package/dist/store/apply-patch.d.ts +16 -0
  120. package/dist/store/apply-patch.d.ts.map +1 -0
  121. package/dist/store/apply-patch.js +191 -0
  122. package/dist/store/apply-patch.js.map +1 -0
  123. package/dist/store/atomic-write.d.ts +16 -0
  124. package/dist/store/atomic-write.d.ts.map +1 -0
  125. package/dist/store/atomic-write.js +132 -0
  126. package/dist/store/atomic-write.js.map +1 -0
  127. package/dist/store/doctor-snapshot.d.ts +20 -0
  128. package/dist/store/doctor-snapshot.d.ts.map +1 -0
  129. package/dist/store/doctor-snapshot.js +176 -0
  130. package/dist/store/doctor-snapshot.js.map +1 -0
  131. package/dist/store/events-store.d.ts +33 -0
  132. package/dist/store/events-store.d.ts.map +1 -0
  133. package/dist/store/events-store.js +297 -0
  134. package/dist/store/events-store.js.map +1 -0
  135. package/dist/store/index.d.ts +21 -0
  136. package/dist/store/index.d.ts.map +1 -0
  137. package/dist/store/index.js +47 -0
  138. package/dist/store/index.js.map +1 -0
  139. package/dist/store/init-store.d.ts +21 -0
  140. package/dist/store/init-store.d.ts.map +1 -0
  141. package/dist/store/init-store.js +295 -0
  142. package/dist/store/init-store.js.map +1 -0
  143. package/dist/store/json-store.d.ts +3 -0
  144. package/dist/store/json-store.d.ts.map +1 -0
  145. package/dist/store/json-store.js +65 -0
  146. package/dist/store/json-store.js.map +1 -0
  147. package/dist/store/policy-store.d.ts +3 -0
  148. package/dist/store/policy-store.d.ts.map +1 -0
  149. package/dist/store/policy-store.js +65 -0
  150. package/dist/store/policy-store.js.map +1 -0
  151. package/dist/store/repo-root.d.ts +46 -0
  152. package/dist/store/repo-root.d.ts.map +1 -0
  153. package/dist/store/repo-root.js +145 -0
  154. package/dist/store/repo-root.js.map +1 -0
  155. package/dist/store/rules.d.ts +53 -0
  156. package/dist/store/rules.d.ts.map +1 -0
  157. package/dist/store/rules.js +78 -0
  158. package/dist/store/rules.js.map +1 -0
  159. package/dist/store/specs-store.d.ts +3 -0
  160. package/dist/store/specs-store.d.ts.map +1 -0
  161. package/dist/store/specs-store.js +131 -0
  162. package/dist/store/specs-store.js.map +1 -0
  163. package/dist/store/types.d.ts +84 -0
  164. package/dist/store/types.d.ts.map +1 -0
  165. package/dist/store/types.js +14 -0
  166. package/dist/store/types.js.map +1 -0
  167. package/dist/store/waivers-store.d.ts +25 -0
  168. package/dist/store/waivers-store.d.ts.map +1 -0
  169. package/dist/store/waivers-store.js +232 -0
  170. package/dist/store/waivers-store.js.map +1 -0
  171. package/dist/store/worktrees-store.d.ts +3 -0
  172. package/dist/store/worktrees-store.d.ts.map +1 -0
  173. package/dist/store/worktrees-store.js +62 -0
  174. package/dist/store/worktrees-store.js.map +1 -0
  175. package/dist/store/yaml-store.d.ts +9 -0
  176. package/dist/store/yaml-store.d.ts.map +1 -0
  177. package/dist/store/yaml-store.js +121 -0
  178. package/dist/store/yaml-store.js.map +1 -0
  179. package/package.json +15 -13
  180. package/dist/budget-derivation.js +0 -751
  181. package/dist/cicd-optimizer.js +0 -504
  182. package/dist/commands/agents.js +0 -124
  183. package/dist/commands/archive.js +0 -500
  184. package/dist/commands/burnup.js +0 -198
  185. package/dist/commands/diagnose.js +0 -525
  186. package/dist/commands/evaluate.js +0 -314
  187. package/dist/commands/gates.js +0 -149
  188. package/dist/commands/init.js +0 -857
  189. package/dist/commands/iterate.js +0 -417
  190. package/dist/commands/mode.js +0 -269
  191. package/dist/commands/parallel.js +0 -242
  192. package/dist/commands/plan.js +0 -438
  193. package/dist/commands/provenance.js +0 -1143
  194. package/dist/commands/quality-monitor.js +0 -284
  195. package/dist/commands/scope.js +0 -264
  196. package/dist/commands/session.js +0 -312
  197. package/dist/commands/sidecar.js +0 -74
  198. package/dist/commands/specs.js +0 -1656
  199. package/dist/commands/status.js +0 -1172
  200. package/dist/commands/templates.js +0 -237
  201. package/dist/commands/tool.js +0 -136
  202. package/dist/commands/tutorial.js +0 -480
  203. package/dist/commands/validate.js +0 -357
  204. package/dist/commands/verify-acs.js +0 -443
  205. package/dist/commands/waivers.js +0 -599
  206. package/dist/commands/workflow.js +0 -243
  207. package/dist/commands/worktree.js +0 -502
  208. package/dist/config/lite-scope.js +0 -158
  209. package/dist/config/modes.js +0 -347
  210. package/dist/constants/spec-types.js +0 -65
  211. package/dist/gates/budget-limit.js +0 -121
  212. package/dist/gates/feedback.js +0 -260
  213. package/dist/gates/format.js +0 -179
  214. package/dist/gates/god-object.js +0 -117
  215. package/dist/gates/pipeline.js +0 -167
  216. package/dist/gates/scope-boundary.js +0 -112
  217. package/dist/gates/spec-completeness.js +0 -109
  218. package/dist/gates/todo-detection.js +0 -205
  219. package/dist/generators/jest-config-generator.js +0 -242
  220. package/dist/generators/working-spec.js +0 -237
  221. package/dist/minimal-cli.js +0 -88
  222. package/dist/parallel/parallel-manager.js +0 -433
  223. package/dist/policy/PolicyManager.js +0 -470
  224. package/dist/scaffold/claude-hooks.js +0 -443
  225. package/dist/scaffold/cursor-hooks.js +0 -177
  226. package/dist/scaffold/git-hooks.js +0 -928
  227. package/dist/scaffold/index.js +0 -794
  228. package/dist/session/session-manager.js +0 -653
  229. package/dist/sidecars/index.js +0 -33
  230. package/dist/sidecars/listeners.js +0 -40
  231. package/dist/sidecars/provenance-summary.js +0 -238
  232. package/dist/sidecars/quality-gaps.js +0 -258
  233. package/dist/sidecars/schema.js +0 -149
  234. package/dist/sidecars/spec-drift.js +0 -151
  235. package/dist/sidecars/waiver-draft.js +0 -176
  236. package/dist/spec/SpecFileManager.js +0 -419
  237. package/dist/templates/.caws/schemas/policy.schema.json +0 -117
  238. package/dist/templates/.caws/schemas/scope.schema.json +0 -52
  239. package/dist/templates/.caws/schemas/waivers.schema.json +0 -106
  240. package/dist/templates/.caws/schemas/working-spec.schema.json +0 -340
  241. package/dist/templates/.caws/schemas/worktrees.schema.json +0 -38
  242. package/dist/templates/.caws/templates/working-spec.template.yml +0 -80
  243. package/dist/templates/.caws/tools/README.md +0 -18
  244. package/dist/templates/.caws/tools/scope-guard.js +0 -203
  245. package/dist/templates/.caws/tools-allow.json +0 -331
  246. package/dist/templates/.caws/waivers.yml +0 -19
  247. package/dist/templates/.claude/README.md +0 -190
  248. package/dist/templates/.claude/hooks/audit.sh +0 -121
  249. package/dist/templates/.claude/hooks/block-dangerous.sh +0 -203
  250. package/dist/templates/.claude/hooks/classify_command.py +0 -592
  251. package/dist/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  252. package/dist/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  253. package/dist/templates/.claude/hooks/naming-check.sh +0 -100
  254. package/dist/templates/.claude/hooks/protected-paths.sh +0 -39
  255. package/dist/templates/.claude/hooks/quality-check.sh +0 -81
  256. package/dist/templates/.claude/hooks/scan-secrets.sh +0 -85
  257. package/dist/templates/.claude/hooks/scope-guard.sh +0 -381
  258. package/dist/templates/.claude/hooks/session-caws-status.sh +0 -117
  259. package/dist/templates/.claude/hooks/session-log.sh +0 -634
  260. package/dist/templates/.claude/hooks/simplification-guard.sh +0 -92
  261. package/dist/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  262. package/dist/templates/.claude/hooks/test_classify_command.py +0 -370
  263. package/dist/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  264. package/dist/templates/.claude/hooks/validate-spec.sh +0 -76
  265. package/dist/templates/.claude/hooks/worktree-guard.sh +0 -220
  266. package/dist/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  267. package/dist/templates/.claude/rules/git-safety.md +0 -26
  268. package/dist/templates/.claude/rules/worktree-isolation.md +0 -101
  269. package/dist/templates/.claude/settings.json +0 -141
  270. package/dist/templates/.cursor/README.md +0 -299
  271. package/dist/templates/.cursor/hooks/audit.sh +0 -55
  272. package/dist/templates/.cursor/hooks/block-dangerous.sh +0 -84
  273. package/dist/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  274. package/dist/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  275. package/dist/templates/.cursor/hooks/format.sh +0 -38
  276. package/dist/templates/.cursor/hooks/naming-check.sh +0 -64
  277. package/dist/templates/.cursor/hooks/scan-secrets.sh +0 -51
  278. package/dist/templates/.cursor/hooks/scope-guard.sh +0 -52
  279. package/dist/templates/.cursor/hooks/session-log.sh +0 -924
  280. package/dist/templates/.cursor/hooks/validate-spec.sh +0 -83
  281. package/dist/templates/.cursor/hooks.json +0 -76
  282. package/dist/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  283. package/dist/templates/.cursor/rules/01-working-style.mdc +0 -50
  284. package/dist/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  285. package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  286. package/dist/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  287. package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  288. package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  289. package/dist/templates/.cursor/rules/07-process-ops.mdc +0 -20
  290. package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  291. package/dist/templates/.cursor/rules/09-docstrings.mdc +0 -89
  292. package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  293. package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  294. package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  295. package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  296. package/dist/templates/.cursor/rules/README.md +0 -148
  297. package/dist/templates/.github/copilot-instructions.md +0 -82
  298. package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  299. package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  300. package/dist/templates/.junie/guidelines.md +0 -73
  301. package/dist/templates/.vscode/launch.json +0 -17
  302. package/dist/templates/.vscode/settings.json +0 -95
  303. package/dist/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  304. package/dist/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  305. package/dist/templates/CLAUDE.md +0 -196
  306. package/dist/templates/COMMIT_CONVENTIONS.md +0 -86
  307. package/dist/templates/OIDC_SETUP.md +0 -300
  308. package/dist/templates/agents.md +0 -171
  309. package/dist/templates/codemod/README.md +0 -1
  310. package/dist/templates/codemod/test.js +0 -93
  311. package/dist/templates/docs/README.md +0 -151
  312. package/dist/templates/scripts/new_feature.sh +0 -80
  313. package/dist/templates/scripts/quality-gates/check-god-objects.js +0 -146
  314. package/dist/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  315. package/dist/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
  316. package/dist/test-analysis.js +0 -786
  317. package/dist/tool-interface.js +0 -314
  318. package/dist/tool-loader.js +0 -303
  319. package/dist/tool-validator.js +0 -393
  320. package/dist/utils/agent-display.js +0 -210
  321. package/dist/utils/agent-session.js +0 -344
  322. package/dist/utils/async-utils.js +0 -188
  323. package/dist/utils/command-wrapper.js +0 -200
  324. package/dist/utils/event-log.js +0 -584
  325. package/dist/utils/event-renderer.js +0 -521
  326. package/dist/utils/finalization.js +0 -230
  327. package/dist/utils/git-lock.js +0 -119
  328. package/dist/utils/gitignore-updater.js +0 -158
  329. package/dist/utils/ide-detection.js +0 -133
  330. package/dist/utils/lifecycle-events.js +0 -94
  331. package/dist/utils/project-analysis.js +0 -367
  332. package/dist/utils/promise-utils.js +0 -72
  333. package/dist/utils/quality-gates-errors.js +0 -520
  334. package/dist/utils/quality-gates-utils.js +0 -387
  335. package/dist/utils/schema-validator.js +0 -50
  336. package/dist/utils/spec-resolver.js +0 -711
  337. package/dist/utils/typescript-detector.js +0 -369
  338. package/dist/utils/working-state.js +0 -530
  339. package/dist/utils/yaml-validation.js +0 -156
  340. package/dist/validation/spec-validation.js +0 -924
  341. package/dist/waivers-manager.js +0 -732
  342. package/dist/worktree/worktree-manager.js +0 -1735
  343. package/templates/.caws/schemas/policy.schema.json +0 -117
  344. package/templates/.caws/schemas/scope.schema.json +0 -52
  345. package/templates/.caws/schemas/waivers.schema.json +0 -106
  346. package/templates/.caws/schemas/working-spec.schema.json +0 -340
  347. package/templates/.caws/schemas/worktrees.schema.json +0 -38
  348. package/templates/.caws/templates/working-spec.template.yml +0 -80
  349. package/templates/.caws/tools/README.md +0 -18
  350. package/templates/.caws/tools/scope-guard.js +0 -203
  351. package/templates/.caws/tools-allow.json +0 -331
  352. package/templates/.caws/waivers.yml +0 -19
  353. package/templates/.claude/README.md +0 -190
  354. package/templates/.claude/hooks/audit.sh +0 -121
  355. package/templates/.claude/hooks/block-dangerous.sh +0 -203
  356. package/templates/.claude/hooks/classify_command.py +0 -592
  357. package/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
  358. package/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
  359. package/templates/.claude/hooks/naming-check.sh +0 -100
  360. package/templates/.claude/hooks/protected-paths.sh +0 -39
  361. package/templates/.claude/hooks/quality-check.sh +0 -81
  362. package/templates/.claude/hooks/scan-secrets.sh +0 -85
  363. package/templates/.claude/hooks/scope-guard.sh +0 -381
  364. package/templates/.claude/hooks/session-caws-status.sh +0 -117
  365. package/templates/.claude/hooks/session-log.sh +0 -634
  366. package/templates/.claude/hooks/simplification-guard.sh +0 -92
  367. package/templates/.claude/hooks/stop-worktree-check.sh +0 -46
  368. package/templates/.claude/hooks/test_classify_command.py +0 -370
  369. package/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
  370. package/templates/.claude/hooks/validate-spec.sh +0 -76
  371. package/templates/.claude/hooks/worktree-guard.sh +0 -220
  372. package/templates/.claude/hooks/worktree-write-guard.sh +0 -190
  373. package/templates/.claude/rules/git-safety.md +0 -26
  374. package/templates/.claude/rules/worktree-isolation.md +0 -101
  375. package/templates/.claude/settings.json +0 -141
  376. package/templates/.cursor/README.md +0 -299
  377. package/templates/.cursor/hooks/audit.sh +0 -55
  378. package/templates/.cursor/hooks/block-dangerous.sh +0 -84
  379. package/templates/.cursor/hooks/caws-quality-check.sh +0 -52
  380. package/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
  381. package/templates/.cursor/hooks/format.sh +0 -38
  382. package/templates/.cursor/hooks/naming-check.sh +0 -64
  383. package/templates/.cursor/hooks/scan-secrets.sh +0 -51
  384. package/templates/.cursor/hooks/scope-guard.sh +0 -52
  385. package/templates/.cursor/hooks/session-log.sh +0 -924
  386. package/templates/.cursor/hooks/validate-spec.sh +0 -83
  387. package/templates/.cursor/hooks.json +0 -76
  388. package/templates/.cursor/rules/00-claims-verification.mdc +0 -144
  389. package/templates/.cursor/rules/01-working-style.mdc +0 -50
  390. package/templates/.cursor/rules/02-quality-gates.mdc +0 -368
  391. package/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
  392. package/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
  393. package/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
  394. package/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
  395. package/templates/.cursor/rules/07-process-ops.mdc +0 -20
  396. package/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
  397. package/templates/.cursor/rules/09-docstrings.mdc +0 -89
  398. package/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
  399. package/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
  400. package/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
  401. package/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
  402. package/templates/.cursor/rules/README.md +0 -148
  403. package/templates/.github/copilot-instructions.md +0 -82
  404. package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
  405. package/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
  406. package/templates/.junie/guidelines.md +0 -73
  407. package/templates/.vscode/launch.json +0 -17
  408. package/templates/.vscode/settings.json +0 -95
  409. package/templates/.windsurf/rules/caws-quality-standards.md +0 -54
  410. package/templates/.windsurf/workflows/caws-guided-development.md +0 -92
  411. package/templates/CLAUDE.md +0 -196
  412. package/templates/COMMIT_CONVENTIONS.md +0 -86
  413. package/templates/OIDC_SETUP.md +0 -300
  414. package/templates/agents.md +0 -171
  415. package/templates/codemod/README.md +0 -1
  416. package/templates/codemod/test.js +0 -93
  417. package/templates/docs/README.md +0 -151
  418. package/templates/scripts/new_feature.sh +0 -80
  419. package/templates/scripts/quality-gates/check-god-objects.js +0 -146
  420. package/templates/scripts/quality-gates/run-quality-gates.js +0 -50
  421. package/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
@@ -1,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
- };