@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.
- package/README.md +125 -374
- package/dist/index.js +43 -756
- package/dist/shell/binding/resolve-binding.d.ts +4 -0
- package/dist/shell/binding/resolve-binding.d.ts.map +1 -0
- package/dist/shell/binding/resolve-binding.js +228 -0
- package/dist/shell/binding/resolve-binding.js.map +1 -0
- package/dist/shell/binding/types.d.ts +42 -0
- package/dist/shell/binding/types.d.ts.map +1 -0
- package/dist/shell/binding/types.js +21 -0
- package/dist/shell/binding/types.js.map +1 -0
- package/dist/shell/commands/claim.d.ts +14 -0
- package/dist/shell/commands/claim.d.ts.map +1 -0
- package/dist/shell/commands/claim.js +197 -0
- package/dist/shell/commands/claim.js.map +1 -0
- package/dist/shell/commands/doctor.d.ts +13 -0
- package/dist/shell/commands/doctor.d.ts.map +1 -0
- package/dist/shell/commands/doctor.js +97 -0
- package/dist/shell/commands/doctor.js.map +1 -0
- package/dist/shell/commands/evidence.d.ts +28 -0
- package/dist/shell/commands/evidence.d.ts.map +1 -0
- package/dist/shell/commands/evidence.js +166 -0
- package/dist/shell/commands/evidence.js.map +1 -0
- package/dist/shell/commands/gates.d.ts +19 -0
- package/dist/shell/commands/gates.d.ts.map +1 -0
- package/dist/shell/commands/gates.js +181 -0
- package/dist/shell/commands/gates.js.map +1 -0
- package/dist/shell/commands/init.d.ts +8 -0
- package/dist/shell/commands/init.d.ts.map +1 -0
- package/dist/shell/commands/init.js +64 -0
- package/dist/shell/commands/init.js.map +1 -0
- package/dist/shell/commands/scope.d.ts +11 -0
- package/dist/shell/commands/scope.d.ts.map +1 -0
- package/dist/shell/commands/scope.js +92 -0
- package/dist/shell/commands/scope.js.map +1 -0
- package/dist/shell/commands/status.d.ts +15 -0
- package/dist/shell/commands/status.d.ts.map +1 -0
- package/dist/shell/commands/status.js +106 -0
- package/dist/shell/commands/status.js.map +1 -0
- package/dist/shell/commands/waiver.d.ts +38 -0
- package/dist/shell/commands/waiver.d.ts.map +1 -0
- package/dist/shell/commands/waiver.js +240 -0
- package/dist/shell/commands/waiver.js.map +1 -0
- package/dist/shell/gates/disposition.d.ts +23 -0
- package/dist/shell/gates/disposition.d.ts.map +1 -0
- package/dist/shell/gates/disposition.js +87 -0
- package/dist/shell/gates/disposition.js.map +1 -0
- package/dist/shell/gates/gate-result-contract.d.ts +39 -0
- package/dist/shell/gates/gate-result-contract.d.ts.map +1 -0
- package/dist/shell/gates/gate-result-contract.js +150 -0
- package/dist/shell/gates/gate-result-contract.js.map +1 -0
- package/dist/shell/gates/quality-gates-adapter.d.ts +55 -0
- package/dist/shell/gates/quality-gates-adapter.d.ts.map +1 -0
- package/dist/shell/gates/quality-gates-adapter.js +161 -0
- package/dist/shell/gates/quality-gates-adapter.js.map +1 -0
- package/dist/shell/gates/waiver-filter.d.ts +58 -0
- package/dist/shell/gates/waiver-filter.d.ts.map +1 -0
- package/dist/shell/gates/waiver-filter.js +119 -0
- package/dist/shell/gates/waiver-filter.js.map +1 -0
- package/dist/shell/index.d.ts +50 -0
- package/dist/shell/index.d.ts.map +1 -0
- package/dist/shell/index.js +73 -0
- package/dist/shell/index.js.map +1 -0
- package/dist/shell/register.d.ts +11 -0
- package/dist/shell/register.d.ts.map +1 -0
- package/dist/shell/register.js +274 -0
- package/dist/shell/register.js.map +1 -0
- package/dist/shell/render/claim.d.ts +22 -0
- package/dist/shell/render/claim.d.ts.map +1 -0
- package/dist/shell/render/claim.js +75 -0
- package/dist/shell/render/claim.js.map +1 -0
- package/dist/shell/render/decision.d.ts +15 -0
- package/dist/shell/render/decision.d.ts.map +1 -0
- package/dist/shell/render/decision.js +66 -0
- package/dist/shell/render/decision.js.map +1 -0
- package/dist/shell/render/diagnostic.d.ts +19 -0
- package/dist/shell/render/diagnostic.d.ts.map +1 -0
- package/dist/shell/render/diagnostic.js +76 -0
- package/dist/shell/render/diagnostic.js.map +1 -0
- package/dist/shell/render/finding.d.ts +15 -0
- package/dist/shell/render/finding.d.ts.map +1 -0
- package/dist/shell/render/finding.js +57 -0
- package/dist/shell/render/finding.js.map +1 -0
- package/dist/shell/render/gates.d.ts +3 -0
- package/dist/shell/render/gates.d.ts.map +1 -0
- package/dist/shell/render/gates.js +56 -0
- package/dist/shell/render/gates.js.map +1 -0
- package/dist/shell/render/init.d.ts +11 -0
- package/dist/shell/render/init.d.ts.map +1 -0
- package/dist/shell/render/init.js +32 -0
- package/dist/shell/render/init.js.map +1 -0
- package/dist/shell/render/status.d.ts +26 -0
- package/dist/shell/render/status.d.ts.map +1 -0
- package/dist/shell/render/status.js +143 -0
- package/dist/shell/render/status.js.map +1 -0
- package/dist/shell/render/waiver.d.ts +21 -0
- package/dist/shell/render/waiver.d.ts.map +1 -0
- package/dist/shell/render/waiver.js +94 -0
- package/dist/shell/render/waiver.js.map +1 -0
- package/dist/shell/rules.d.ts +37 -0
- package/dist/shell/rules.d.ts.map +1 -0
- package/dist/shell/rules.js +51 -0
- package/dist/shell/rules.js.map +1 -0
- package/dist/shell/session/actor.d.ts +14 -0
- package/dist/shell/session/actor.d.ts.map +1 -0
- package/dist/shell/session/actor.js +34 -0
- package/dist/shell/session/actor.js.map +1 -0
- package/dist/shell/session/resolve-session.d.ts +5 -0
- package/dist/shell/session/resolve-session.d.ts.map +1 -0
- package/dist/shell/session/resolve-session.js +239 -0
- package/dist/shell/session/resolve-session.js.map +1 -0
- package/dist/shell/session/types.d.ts +56 -0
- package/dist/shell/session/types.d.ts.map +1 -0
- package/dist/shell/session/types.js +15 -0
- package/dist/shell/session/types.js.map +1 -0
- package/dist/store/agents-store.d.ts +3 -0
- package/dist/store/agents-store.d.ts.map +1 -0
- package/dist/store/agents-store.js +63 -0
- package/dist/store/agents-store.js.map +1 -0
- package/dist/store/apply-patch.d.ts +16 -0
- package/dist/store/apply-patch.d.ts.map +1 -0
- package/dist/store/apply-patch.js +191 -0
- package/dist/store/apply-patch.js.map +1 -0
- package/dist/store/atomic-write.d.ts +16 -0
- package/dist/store/atomic-write.d.ts.map +1 -0
- package/dist/store/atomic-write.js +132 -0
- package/dist/store/atomic-write.js.map +1 -0
- package/dist/store/doctor-snapshot.d.ts +20 -0
- package/dist/store/doctor-snapshot.d.ts.map +1 -0
- package/dist/store/doctor-snapshot.js +176 -0
- package/dist/store/doctor-snapshot.js.map +1 -0
- package/dist/store/events-store.d.ts +33 -0
- package/dist/store/events-store.d.ts.map +1 -0
- package/dist/store/events-store.js +297 -0
- package/dist/store/events-store.js.map +1 -0
- package/dist/store/index.d.ts +21 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +47 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/init-store.d.ts +21 -0
- package/dist/store/init-store.d.ts.map +1 -0
- package/dist/store/init-store.js +295 -0
- package/dist/store/init-store.js.map +1 -0
- package/dist/store/json-store.d.ts +3 -0
- package/dist/store/json-store.d.ts.map +1 -0
- package/dist/store/json-store.js +65 -0
- package/dist/store/json-store.js.map +1 -0
- package/dist/store/policy-store.d.ts +3 -0
- package/dist/store/policy-store.d.ts.map +1 -0
- package/dist/store/policy-store.js +65 -0
- package/dist/store/policy-store.js.map +1 -0
- package/dist/store/repo-root.d.ts +46 -0
- package/dist/store/repo-root.d.ts.map +1 -0
- package/dist/store/repo-root.js +145 -0
- package/dist/store/repo-root.js.map +1 -0
- package/dist/store/rules.d.ts +53 -0
- package/dist/store/rules.d.ts.map +1 -0
- package/dist/store/rules.js +78 -0
- package/dist/store/rules.js.map +1 -0
- package/dist/store/specs-store.d.ts +3 -0
- package/dist/store/specs-store.d.ts.map +1 -0
- package/dist/store/specs-store.js +131 -0
- package/dist/store/specs-store.js.map +1 -0
- package/dist/store/types.d.ts +84 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +14 -0
- package/dist/store/types.js.map +1 -0
- package/dist/store/waivers-store.d.ts +25 -0
- package/dist/store/waivers-store.d.ts.map +1 -0
- package/dist/store/waivers-store.js +232 -0
- package/dist/store/waivers-store.js.map +1 -0
- package/dist/store/worktrees-store.d.ts +3 -0
- package/dist/store/worktrees-store.d.ts.map +1 -0
- package/dist/store/worktrees-store.js +62 -0
- package/dist/store/worktrees-store.js.map +1 -0
- package/dist/store/yaml-store.d.ts +9 -0
- package/dist/store/yaml-store.d.ts.map +1 -0
- package/dist/store/yaml-store.js +121 -0
- package/dist/store/yaml-store.js.map +1 -0
- package/package.json +15 -13
- package/dist/budget-derivation.js +0 -751
- package/dist/cicd-optimizer.js +0 -504
- package/dist/commands/archive.js +0 -500
- package/dist/commands/burnup.js +0 -198
- package/dist/commands/diagnose.js +0 -525
- package/dist/commands/evaluate.js +0 -314
- package/dist/commands/gates.js +0 -149
- package/dist/commands/init.js +0 -857
- package/dist/commands/iterate.js +0 -417
- package/dist/commands/mode.js +0 -269
- package/dist/commands/parallel.js +0 -242
- package/dist/commands/plan.js +0 -438
- package/dist/commands/provenance.js +0 -1143
- package/dist/commands/quality-monitor.js +0 -284
- package/dist/commands/scope.js +0 -264
- package/dist/commands/session.js +0 -312
- package/dist/commands/sidecar.js +0 -74
- package/dist/commands/specs.js +0 -1448
- package/dist/commands/status.js +0 -1151
- package/dist/commands/templates.js +0 -237
- package/dist/commands/tool.js +0 -136
- package/dist/commands/tutorial.js +0 -480
- package/dist/commands/validate.js +0 -357
- package/dist/commands/verify-acs.js +0 -443
- package/dist/commands/waivers.js +0 -599
- package/dist/commands/workflow.js +0 -243
- package/dist/commands/worktree.js +0 -386
- package/dist/config/lite-scope.js +0 -158
- package/dist/config/modes.js +0 -347
- package/dist/constants/spec-types.js +0 -65
- package/dist/gates/budget-limit.js +0 -121
- package/dist/gates/feedback.js +0 -260
- package/dist/gates/format.js +0 -179
- package/dist/gates/god-object.js +0 -117
- package/dist/gates/pipeline.js +0 -167
- package/dist/gates/scope-boundary.js +0 -93
- package/dist/gates/spec-completeness.js +0 -109
- package/dist/gates/todo-detection.js +0 -205
- package/dist/generators/jest-config-generator.js +0 -242
- package/dist/generators/working-spec.js +0 -237
- package/dist/minimal-cli.js +0 -88
- package/dist/parallel/parallel-manager.js +0 -433
- package/dist/policy/PolicyManager.js +0 -465
- package/dist/scaffold/claude-hooks.js +0 -443
- package/dist/scaffold/cursor-hooks.js +0 -177
- package/dist/scaffold/git-hooks.js +0 -928
- package/dist/scaffold/index.js +0 -794
- package/dist/session/session-manager.js +0 -653
- package/dist/sidecars/index.js +0 -33
- package/dist/sidecars/listeners.js +0 -40
- package/dist/sidecars/provenance-summary.js +0 -238
- package/dist/sidecars/quality-gaps.js +0 -258
- package/dist/sidecars/schema.js +0 -149
- package/dist/sidecars/spec-drift.js +0 -151
- package/dist/sidecars/waiver-draft.js +0 -176
- package/dist/spec/SpecFileManager.js +0 -419
- package/dist/templates/.caws/schemas/policy.schema.json +0 -112
- package/dist/templates/.caws/schemas/scope.schema.json +0 -52
- package/dist/templates/.caws/schemas/waivers.schema.json +0 -106
- package/dist/templates/.caws/schemas/working-spec.schema.json +0 -340
- package/dist/templates/.caws/schemas/worktrees.schema.json +0 -38
- package/dist/templates/.caws/templates/working-spec.template.yml +0 -80
- package/dist/templates/.caws/tools/README.md +0 -18
- package/dist/templates/.caws/tools/scope-guard.js +0 -203
- package/dist/templates/.caws/tools-allow.json +0 -331
- package/dist/templates/.caws/waivers.yml +0 -19
- package/dist/templates/.claude/README.md +0 -190
- package/dist/templates/.claude/hooks/audit.sh +0 -121
- package/dist/templates/.claude/hooks/block-dangerous.sh +0 -203
- package/dist/templates/.claude/hooks/classify_command.py +0 -592
- package/dist/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
- package/dist/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
- package/dist/templates/.claude/hooks/naming-check.sh +0 -100
- package/dist/templates/.claude/hooks/protected-paths.sh +0 -39
- package/dist/templates/.claude/hooks/quality-check.sh +0 -81
- package/dist/templates/.claude/hooks/scan-secrets.sh +0 -85
- package/dist/templates/.claude/hooks/scope-guard.sh +0 -381
- package/dist/templates/.claude/hooks/session-caws-status.sh +0 -117
- package/dist/templates/.claude/hooks/session-log.sh +0 -634
- package/dist/templates/.claude/hooks/simplification-guard.sh +0 -92
- package/dist/templates/.claude/hooks/stop-worktree-check.sh +0 -46
- package/dist/templates/.claude/hooks/test_classify_command.py +0 -370
- package/dist/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
- package/dist/templates/.claude/hooks/validate-spec.sh +0 -76
- package/dist/templates/.claude/hooks/worktree-guard.sh +0 -220
- package/dist/templates/.claude/hooks/worktree-write-guard.sh +0 -190
- package/dist/templates/.claude/rules/git-safety.md +0 -26
- package/dist/templates/.claude/rules/worktree-isolation.md +0 -83
- package/dist/templates/.claude/settings.json +0 -141
- package/dist/templates/.cursor/README.md +0 -299
- package/dist/templates/.cursor/hooks/audit.sh +0 -55
- package/dist/templates/.cursor/hooks/block-dangerous.sh +0 -84
- package/dist/templates/.cursor/hooks/caws-quality-check.sh +0 -52
- package/dist/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
- package/dist/templates/.cursor/hooks/format.sh +0 -38
- package/dist/templates/.cursor/hooks/naming-check.sh +0 -64
- package/dist/templates/.cursor/hooks/scan-secrets.sh +0 -51
- package/dist/templates/.cursor/hooks/scope-guard.sh +0 -52
- package/dist/templates/.cursor/hooks/session-log.sh +0 -924
- package/dist/templates/.cursor/hooks/validate-spec.sh +0 -83
- package/dist/templates/.cursor/hooks.json +0 -76
- package/dist/templates/.cursor/rules/00-claims-verification.mdc +0 -144
- package/dist/templates/.cursor/rules/01-working-style.mdc +0 -50
- package/dist/templates/.cursor/rules/02-quality-gates.mdc +0 -368
- package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
- package/dist/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
- package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
- package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
- package/dist/templates/.cursor/rules/07-process-ops.mdc +0 -20
- package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
- package/dist/templates/.cursor/rules/09-docstrings.mdc +0 -89
- package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
- package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
- package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
- package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
- package/dist/templates/.cursor/rules/README.md +0 -148
- package/dist/templates/.github/copilot-instructions.md +0 -82
- package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
- package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
- package/dist/templates/.junie/guidelines.md +0 -73
- package/dist/templates/.vscode/launch.json +0 -17
- package/dist/templates/.vscode/settings.json +0 -95
- package/dist/templates/.windsurf/rules/caws-quality-standards.md +0 -54
- package/dist/templates/.windsurf/workflows/caws-guided-development.md +0 -92
- package/dist/templates/CLAUDE.md +0 -174
- package/dist/templates/COMMIT_CONVENTIONS.md +0 -86
- package/dist/templates/OIDC_SETUP.md +0 -300
- package/dist/templates/agents.md +0 -145
- package/dist/templates/codemod/README.md +0 -1
- package/dist/templates/codemod/test.js +0 -93
- package/dist/templates/docs/README.md +0 -151
- package/dist/templates/scripts/new_feature.sh +0 -80
- package/dist/templates/scripts/quality-gates/check-god-objects.js +0 -146
- package/dist/templates/scripts/quality-gates/run-quality-gates.js +0 -50
- package/dist/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
- package/dist/test-analysis.js +0 -786
- package/dist/tool-interface.js +0 -314
- package/dist/tool-loader.js +0 -303
- package/dist/tool-validator.js +0 -393
- package/dist/utils/agent-session.js +0 -202
- package/dist/utils/async-utils.js +0 -188
- package/dist/utils/command-wrapper.js +0 -200
- package/dist/utils/event-log.js +0 -584
- package/dist/utils/event-renderer.js +0 -521
- package/dist/utils/finalization.js +0 -230
- package/dist/utils/git-lock.js +0 -119
- package/dist/utils/gitignore-updater.js +0 -158
- package/dist/utils/ide-detection.js +0 -133
- package/dist/utils/lifecycle-events.js +0 -94
- package/dist/utils/project-analysis.js +0 -367
- package/dist/utils/promise-utils.js +0 -72
- package/dist/utils/quality-gates-errors.js +0 -520
- package/dist/utils/quality-gates-utils.js +0 -387
- package/dist/utils/schema-validator.js +0 -50
- package/dist/utils/spec-resolver.js +0 -711
- package/dist/utils/typescript-detector.js +0 -369
- package/dist/utils/working-state.js +0 -530
- package/dist/utils/yaml-validation.js +0 -156
- package/dist/validation/spec-validation.js +0 -921
- package/dist/waivers-manager.js +0 -732
- package/dist/worktree/worktree-manager.js +0 -1374
- package/templates/.caws/schemas/policy.schema.json +0 -112
- package/templates/.caws/schemas/scope.schema.json +0 -52
- package/templates/.caws/schemas/waivers.schema.json +0 -106
- package/templates/.caws/schemas/working-spec.schema.json +0 -340
- package/templates/.caws/schemas/worktrees.schema.json +0 -38
- package/templates/.caws/templates/working-spec.template.yml +0 -80
- package/templates/.caws/tools/README.md +0 -18
- package/templates/.caws/tools/scope-guard.js +0 -203
- package/templates/.caws/tools-allow.json +0 -331
- package/templates/.caws/waivers.yml +0 -19
- package/templates/.claude/README.md +0 -190
- package/templates/.claude/hooks/audit.sh +0 -121
- package/templates/.claude/hooks/block-dangerous.sh +0 -203
- package/templates/.claude/hooks/classify_command.py +0 -592
- package/templates/.claude/hooks/doc-frontmatter-check.sh +0 -173
- package/templates/.claude/hooks/lite-sprawl-check.sh +0 -145
- package/templates/.claude/hooks/naming-check.sh +0 -100
- package/templates/.claude/hooks/protected-paths.sh +0 -39
- package/templates/.claude/hooks/quality-check.sh +0 -81
- package/templates/.claude/hooks/scan-secrets.sh +0 -85
- package/templates/.claude/hooks/scope-guard.sh +0 -381
- package/templates/.claude/hooks/session-caws-status.sh +0 -117
- package/templates/.claude/hooks/session-log.sh +0 -634
- package/templates/.claude/hooks/simplification-guard.sh +0 -92
- package/templates/.claude/hooks/stop-worktree-check.sh +0 -46
- package/templates/.claude/hooks/test_classify_command.py +0 -370
- package/templates/.claude/hooks/test_wrapper_smoke.sh +0 -96
- package/templates/.claude/hooks/validate-spec.sh +0 -76
- package/templates/.claude/hooks/worktree-guard.sh +0 -220
- package/templates/.claude/hooks/worktree-write-guard.sh +0 -190
- package/templates/.claude/rules/git-safety.md +0 -26
- package/templates/.claude/rules/worktree-isolation.md +0 -83
- package/templates/.claude/settings.json +0 -141
- package/templates/.cursor/README.md +0 -299
- package/templates/.cursor/hooks/audit.sh +0 -55
- package/templates/.cursor/hooks/block-dangerous.sh +0 -84
- package/templates/.cursor/hooks/caws-quality-check.sh +0 -52
- package/templates/.cursor/hooks/caws-scope-guard.sh +0 -130
- package/templates/.cursor/hooks/format.sh +0 -38
- package/templates/.cursor/hooks/naming-check.sh +0 -64
- package/templates/.cursor/hooks/scan-secrets.sh +0 -51
- package/templates/.cursor/hooks/scope-guard.sh +0 -52
- package/templates/.cursor/hooks/session-log.sh +0 -924
- package/templates/.cursor/hooks/validate-spec.sh +0 -83
- package/templates/.cursor/hooks.json +0 -76
- package/templates/.cursor/rules/00-claims-verification.mdc +0 -144
- package/templates/.cursor/rules/01-working-style.mdc +0 -50
- package/templates/.cursor/rules/02-quality-gates.mdc +0 -368
- package/templates/.cursor/rules/03-naming-and-refactor.mdc +0 -33
- package/templates/.cursor/rules/04-logging-language-style.mdc +0 -23
- package/templates/.cursor/rules/05-safe-defaults-guards.mdc +0 -23
- package/templates/.cursor/rules/06-typescript-conventions.mdc +0 -36
- package/templates/.cursor/rules/07-process-ops.mdc +0 -20
- package/templates/.cursor/rules/08-solid-and-architecture.mdc +0 -16
- package/templates/.cursor/rules/09-docstrings.mdc +0 -89
- package/templates/.cursor/rules/10-documentation-quality-standards.mdc +0 -385
- package/templates/.cursor/rules/11-scope-management-waivers.mdc +0 -381
- package/templates/.cursor/rules/12-implementation-completeness.mdc +0 -516
- package/templates/.cursor/rules/13-language-agnostic-standards.mdc +0 -578
- package/templates/.cursor/rules/README.md +0 -148
- package/templates/.github/copilot-instructions.md +0 -82
- package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +0 -5
- package/templates/.idea/runConfigurations/CAWS_Validate.xml +0 -5
- package/templates/.junie/guidelines.md +0 -73
- package/templates/.vscode/launch.json +0 -17
- package/templates/.vscode/settings.json +0 -95
- package/templates/.windsurf/rules/caws-quality-standards.md +0 -54
- package/templates/.windsurf/workflows/caws-guided-development.md +0 -92
- package/templates/CLAUDE.md +0 -174
- package/templates/COMMIT_CONVENTIONS.md +0 -86
- package/templates/OIDC_SETUP.md +0 -300
- package/templates/agents.md +0 -145
- package/templates/codemod/README.md +0 -1
- package/templates/codemod/test.js +0 -93
- package/templates/docs/README.md +0 -151
- package/templates/scripts/new_feature.sh +0 -80
- package/templates/scripts/quality-gates/check-god-objects.js +0 -146
- package/templates/scripts/quality-gates/run-quality-gates.js +0 -50
- package/templates/scripts/v3/analysis/todo_analyzer.py +0 -1997
package/dist/commands/archive.js
DELETED
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview CAWS Archive Command
|
|
3
|
-
* Archive completed changes with lifecycle management (multi-spec aware)
|
|
4
|
-
* @author @darianrosebrook
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs-extra');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const yaml = require('js-yaml');
|
|
10
|
-
const chalk = require('chalk');
|
|
11
|
-
const { execSync } = require('child_process');
|
|
12
|
-
const { safeAsync, outputResult } = require('../error-handler');
|
|
13
|
-
const { findProjectRoot } = require('../utils/detection');
|
|
14
|
-
|
|
15
|
-
// Import spec resolution system
|
|
16
|
-
const { resolveSpec } = require('../utils/spec-resolver');
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Load change folder structure
|
|
20
|
-
* @param {string} changeId - Change identifier
|
|
21
|
-
* @returns {Promise<Object|null>} Change data or null
|
|
22
|
-
*/
|
|
23
|
-
async function loadChange(changeId) {
|
|
24
|
-
const projectRoot = findProjectRoot();
|
|
25
|
-
const changesDir = path.join(projectRoot, '.caws/changes');
|
|
26
|
-
const changePath = path.join(changesDir, changeId);
|
|
27
|
-
|
|
28
|
-
if (!(await fs.pathExists(changePath))) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
const metadataPath = path.join(changePath, 'metadata.yaml');
|
|
34
|
-
const workingSpecPath = path.join(changePath, 'working-spec.yaml');
|
|
35
|
-
|
|
36
|
-
const metadata = (await fs.pathExists(metadataPath))
|
|
37
|
-
? yaml.load(await fs.readFile(metadataPath, 'utf8'))
|
|
38
|
-
: {};
|
|
39
|
-
|
|
40
|
-
const workingSpec = (await fs.pathExists(workingSpecPath))
|
|
41
|
-
? yaml.load(await fs.readFile(workingSpecPath, 'utf8'))
|
|
42
|
-
: null;
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
id: changeId,
|
|
46
|
-
path: changePath,
|
|
47
|
-
metadata,
|
|
48
|
-
workingSpec,
|
|
49
|
-
workingSpecPath: (await fs.pathExists(workingSpecPath)) ? workingSpecPath : null,
|
|
50
|
-
exists: true,
|
|
51
|
-
};
|
|
52
|
-
} catch (error) {
|
|
53
|
-
throw new Error(`Failed to load change '${changeId}': ${error.message}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Validate all acceptance criteria are met
|
|
59
|
-
* @param {Object} workingSpec - Working specification
|
|
60
|
-
* @returns {Promise<Object>} Validation result
|
|
61
|
-
*/
|
|
62
|
-
async function validateAcceptanceCriteria(workingSpec) {
|
|
63
|
-
const criteria = Array.isArray(workingSpec?.acceptance_criteria)
|
|
64
|
-
? workingSpec.acceptance_criteria
|
|
65
|
-
: Array.isArray(workingSpec?.acceptance)
|
|
66
|
-
? workingSpec.acceptance
|
|
67
|
-
: [];
|
|
68
|
-
|
|
69
|
-
if (!workingSpec || criteria.length === 0) {
|
|
70
|
-
return {
|
|
71
|
-
valid: false,
|
|
72
|
-
message: 'No acceptance criteria found in working spec',
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const hasCompletionTracking = criteria.some((criterion) => criterion.completed !== undefined);
|
|
77
|
-
const incomplete = [];
|
|
78
|
-
|
|
79
|
-
for (const criterion of criteria) {
|
|
80
|
-
if (criterion.completed === false) {
|
|
81
|
-
incomplete.push(criterion.id || 'unknown');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (incomplete.length > 0) {
|
|
86
|
-
return {
|
|
87
|
-
valid: false,
|
|
88
|
-
message: `Incomplete acceptance criteria: ${incomplete.join(', ')}`,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!hasCompletionTracking) {
|
|
93
|
-
return {
|
|
94
|
-
valid: true,
|
|
95
|
-
message: `Acceptance criteria present (${criteria.length}); no explicit completion flags found`,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
valid: true,
|
|
101
|
-
message: `All ${criteria.length} acceptance criteria completed`,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Validate change meets quality gates
|
|
107
|
-
* Runs the actual quality gates runner and checks for violations
|
|
108
|
-
* @param {string} changeId - Change identifier
|
|
109
|
-
* @returns {Promise<Object>} Quality gate result
|
|
110
|
-
*/
|
|
111
|
-
async function validateQualityGates(_changeId) {
|
|
112
|
-
const gates = [];
|
|
113
|
-
const violations = [];
|
|
114
|
-
const warnings = [];
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
// Try to run the quality gates runner
|
|
118
|
-
const qualityGatesPath = path.join(
|
|
119
|
-
__dirname,
|
|
120
|
-
'..',
|
|
121
|
-
'..',
|
|
122
|
-
'..',
|
|
123
|
-
'quality-gates',
|
|
124
|
-
'run-quality-gates.mjs'
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
// Check if quality gates runner exists
|
|
128
|
-
if (await fs.pathExists(qualityGatesPath)) {
|
|
129
|
-
try {
|
|
130
|
-
// Run quality gates in CI mode (checks all files, not just staged)
|
|
131
|
-
const result = execSync(`node "${qualityGatesPath}" --context=ci --json 2>&1`, {
|
|
132
|
-
encoding: 'utf8',
|
|
133
|
-
timeout: 60000, // 60 second timeout
|
|
134
|
-
cwd: process.cwd(),
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// Try to parse JSON output
|
|
138
|
-
try {
|
|
139
|
-
const jsonMatch = result.match(/\{[\s\S]*\}$/);
|
|
140
|
-
if (jsonMatch) {
|
|
141
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
142
|
-
if (parsed.violations) {
|
|
143
|
-
violations.push(...parsed.violations);
|
|
144
|
-
}
|
|
145
|
-
if (parsed.warnings) {
|
|
146
|
-
warnings.push(...parsed.warnings);
|
|
147
|
-
}
|
|
148
|
-
gates.push(...(parsed.gates || []));
|
|
149
|
-
}
|
|
150
|
-
} catch {
|
|
151
|
-
// JSON parsing failed, check for error indicators in output
|
|
152
|
-
if (result.includes('') || result.includes('FAIL')) {
|
|
153
|
-
violations.push({ message: 'Quality gates reported failures', output: result });
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
} catch (execError) {
|
|
157
|
-
// Command failed - check exit code and output
|
|
158
|
-
if (execError.status !== 0) {
|
|
159
|
-
const output = execError.stdout || execError.message;
|
|
160
|
-
if (output.includes('violations') || output.includes('')) {
|
|
161
|
-
violations.push({ message: 'Quality gates failed', output: output.substring(0, 500) });
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Also check for active waivers that might cover violations
|
|
168
|
-
const waiversPath = path.join(process.cwd(), '.caws', 'waivers', 'active-waivers.yaml');
|
|
169
|
-
let hasActiveWaivers = false;
|
|
170
|
-
if (await fs.pathExists(waiversPath)) {
|
|
171
|
-
const waiversContent = await fs.readFile(waiversPath, 'utf8');
|
|
172
|
-
const waivers = yaml.load(waiversContent);
|
|
173
|
-
if (waivers && waivers.waivers) {
|
|
174
|
-
const activeWaiverCount = Object.keys(waivers.waivers).length;
|
|
175
|
-
if (activeWaiverCount > 0) {
|
|
176
|
-
hasActiveWaivers = true;
|
|
177
|
-
gates.push(`${activeWaiverCount} active waiver(s)`);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Determine overall validity
|
|
183
|
-
const hasBlockingViolations = violations.some(
|
|
184
|
-
(v) => v.severity === 'block' || v.severity === 'fail'
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
if (violations.length === 0) {
|
|
188
|
-
return {
|
|
189
|
-
valid: true,
|
|
190
|
-
message: 'All quality gates passed',
|
|
191
|
-
gates: gates.length > 0 ? gates : ['naming', 'duplication', 'god-objects', 'hidden-todo'],
|
|
192
|
-
violations: [],
|
|
193
|
-
warnings,
|
|
194
|
-
};
|
|
195
|
-
} else if (hasActiveWaivers && !hasBlockingViolations) {
|
|
196
|
-
return {
|
|
197
|
-
valid: true,
|
|
198
|
-
message: `Quality gates passed with ${violations.length} waived violation(s)`,
|
|
199
|
-
gates,
|
|
200
|
-
violations,
|
|
201
|
-
warnings,
|
|
202
|
-
waived: true,
|
|
203
|
-
};
|
|
204
|
-
} else {
|
|
205
|
-
return {
|
|
206
|
-
valid: false,
|
|
207
|
-
message: `${violations.length} quality gate violation(s) found`,
|
|
208
|
-
gates,
|
|
209
|
-
violations,
|
|
210
|
-
warnings,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
// If quality gates can't be run, warn but don't block
|
|
215
|
-
return {
|
|
216
|
-
valid: true,
|
|
217
|
-
message: `Quality gates check skipped: ${error.message}`,
|
|
218
|
-
gates: [],
|
|
219
|
-
violations: [],
|
|
220
|
-
warnings: [{ message: `Could not run quality gates: ${error.message}` }],
|
|
221
|
-
skipped: true,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Generate change summary for archival
|
|
228
|
-
* @param {Object} change - Change data
|
|
229
|
-
* @returns {Promise<string>} Summary text
|
|
230
|
-
*/
|
|
231
|
-
async function generateChangeSummary(change, workingSpec) {
|
|
232
|
-
const { metadata } = change;
|
|
233
|
-
|
|
234
|
-
let summary = `# Change Summary: ${change.id}\n\n`;
|
|
235
|
-
|
|
236
|
-
if (workingSpec) {
|
|
237
|
-
summary += `**Title**: ${workingSpec.title || 'Untitled'}\n`;
|
|
238
|
-
summary += `**Risk Tier**: ${workingSpec.risk_tier || 'Unknown'}\n`;
|
|
239
|
-
summary += `**Mode**: ${workingSpec.mode || 'Unknown'}\n\n`;
|
|
240
|
-
|
|
241
|
-
if (workingSpec.acceptance_criteria) {
|
|
242
|
-
const total = workingSpec.acceptance_criteria.length;
|
|
243
|
-
const completed = workingSpec.acceptance_criteria.filter((c) => c.completed).length;
|
|
244
|
-
summary += `**Acceptance Criteria**: ${completed}/${total} completed\n\n`;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (metadata.created_at) {
|
|
249
|
-
summary += `**Created**: ${new Date(metadata.created_at).toISOString()}\n`;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (metadata.completed_at) {
|
|
253
|
-
summary += `**Completed**: ${new Date(metadata.completed_at).toISOString()}\n`;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
summary += `\n**Files Changed**: ${metadata.files_changed || 0}\n`;
|
|
257
|
-
summary += `**Lines Added**: ${metadata.lines_added || 0}\n`;
|
|
258
|
-
summary += `**Lines Removed**: ${metadata.lines_removed || 0}\n`;
|
|
259
|
-
|
|
260
|
-
return summary;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Archive change folder to archive directory
|
|
265
|
-
* @param {Object} change - Change data
|
|
266
|
-
* @returns {Promise<void>}
|
|
267
|
-
*/
|
|
268
|
-
async function archiveChange(change) {
|
|
269
|
-
const archiveDir = '.caws/archive';
|
|
270
|
-
const archivePath = path.join(archiveDir, change.id);
|
|
271
|
-
|
|
272
|
-
// Ensure archive directory exists
|
|
273
|
-
await fs.ensureDir(archiveDir);
|
|
274
|
-
|
|
275
|
-
// Move change folder to archive
|
|
276
|
-
await fs.move(change.path, archivePath);
|
|
277
|
-
|
|
278
|
-
console.log(chalk.green(` Moved to: ${archivePath}`));
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Update provenance with completion
|
|
283
|
-
* @param {Object} change - Change data
|
|
284
|
-
* @returns {Promise<void>}
|
|
285
|
-
*/
|
|
286
|
-
async function updateProvenance(change, specSelection) {
|
|
287
|
-
const provenanceDir = '.caws/provenance';
|
|
288
|
-
const chainPath = path.join(provenanceDir, 'chain.json');
|
|
289
|
-
|
|
290
|
-
try {
|
|
291
|
-
let chain = [];
|
|
292
|
-
|
|
293
|
-
if (await fs.pathExists(chainPath)) {
|
|
294
|
-
chain = JSON.parse(await fs.readFile(chainPath, 'utf8'));
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Add completion entry
|
|
298
|
-
const completionEntry = {
|
|
299
|
-
timestamp: new Date().toISOString(),
|
|
300
|
-
action: 'change_completed',
|
|
301
|
-
change_id: change.id,
|
|
302
|
-
metadata: {
|
|
303
|
-
title: specSelection?.spec?.title || change.workingSpec?.title,
|
|
304
|
-
risk_tier: specSelection?.spec?.risk_tier || change.workingSpec?.risk_tier,
|
|
305
|
-
spec_id: specSelection?.spec?.id || change.workingSpec?.id || null,
|
|
306
|
-
spec_path: specSelection?.path || change.workingSpecPath || null,
|
|
307
|
-
spec_type: specSelection?.type || (change.workingSpecPath ? 'change-snapshot' : null),
|
|
308
|
-
files_changed: change.metadata?.files_changed || 0,
|
|
309
|
-
lines_added: change.metadata?.lines_added || 0,
|
|
310
|
-
lines_removed: change.metadata?.lines_removed || 0,
|
|
311
|
-
},
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
chain.push(completionEntry);
|
|
315
|
-
|
|
316
|
-
await fs.ensureDir(provenanceDir);
|
|
317
|
-
await fs.writeFile(chainPath, JSON.stringify(chain, null, 2));
|
|
318
|
-
|
|
319
|
-
console.log(chalk.green(` Provenance updated: ${chain.length} total entries`));
|
|
320
|
-
} catch (error) {
|
|
321
|
-
console.log(chalk.yellow(` Could not update provenance: ${error.message}`));
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Display archive results
|
|
327
|
-
* @param {Object} change - Change data
|
|
328
|
-
* @param {Object} validation - Validation result
|
|
329
|
-
* @param {Object} qualityGates - Quality gates result
|
|
330
|
-
*/
|
|
331
|
-
function displayArchiveResults(change, validation, qualityGates, specSelection) {
|
|
332
|
-
console.log(chalk.bold.cyan(`\nArchiving Change: ${change.id}`));
|
|
333
|
-
console.log(chalk.cyan('==============================================\n'));
|
|
334
|
-
|
|
335
|
-
if (specSelection?.spec) {
|
|
336
|
-
console.log(chalk.blue('Spec Context:'));
|
|
337
|
-
console.log(
|
|
338
|
-
chalk.gray(
|
|
339
|
-
` ${specSelection.spec.id || 'unknown'} (${specSelection.type}) -> ${specSelection.path}`
|
|
340
|
-
)
|
|
341
|
-
);
|
|
342
|
-
console.log('');
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Validation status
|
|
346
|
-
if (validation.valid) {
|
|
347
|
-
console.log(chalk.green('Acceptance Criteria'));
|
|
348
|
-
console.log(chalk.gray(` ${validation.message}`));
|
|
349
|
-
} else {
|
|
350
|
-
console.log(chalk.red('Acceptance Criteria'));
|
|
351
|
-
console.log(chalk.gray(` ${validation.message}`));
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
console.log('');
|
|
355
|
-
|
|
356
|
-
// Quality gates status
|
|
357
|
-
if (qualityGates.valid) {
|
|
358
|
-
console.log(chalk.green('Quality Gates'));
|
|
359
|
-
console.log(chalk.gray(` ${qualityGates.message}`));
|
|
360
|
-
} else {
|
|
361
|
-
console.log(chalk.red('Quality Gates'));
|
|
362
|
-
console.log(chalk.gray(` ${qualityGates.message}`));
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
console.log('');
|
|
366
|
-
|
|
367
|
-
// Archive action
|
|
368
|
-
console.log(chalk.blue('Archive Actions:'));
|
|
369
|
-
console.log(chalk.gray(' - Moving change folder to archive'));
|
|
370
|
-
console.log(chalk.gray(' - Updating provenance chain'));
|
|
371
|
-
console.log(chalk.gray(' - Generating change summary'));
|
|
372
|
-
|
|
373
|
-
console.log('');
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Archive command handler
|
|
378
|
-
* @param {string} changeId - Change identifier to archive
|
|
379
|
-
* @param {Object} options - Command options
|
|
380
|
-
*/
|
|
381
|
-
async function archiveCommand(changeId, options = {}) {
|
|
382
|
-
return safeAsync(
|
|
383
|
-
async () => {
|
|
384
|
-
if (!changeId) {
|
|
385
|
-
throw new Error('Change ID is required. Usage: caws archive <change-id>');
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// Load change data
|
|
389
|
-
const change = await loadChange(changeId);
|
|
390
|
-
if (!change) {
|
|
391
|
-
throw new Error(`Change '${changeId}' not found in .caws/changes/`);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// Resolve spec using priority system
|
|
395
|
-
let specSelection = null;
|
|
396
|
-
if (options.specId || options.specFile) {
|
|
397
|
-
specSelection = await resolveSpec({
|
|
398
|
-
specId: options.specId,
|
|
399
|
-
specFile: options.specFile,
|
|
400
|
-
warnLegacy: false,
|
|
401
|
-
});
|
|
402
|
-
} else if (change.workingSpec) {
|
|
403
|
-
specSelection = {
|
|
404
|
-
path: change.workingSpecPath || path.join(change.path, 'working-spec.yaml'),
|
|
405
|
-
type: 'change-snapshot',
|
|
406
|
-
spec: change.workingSpec,
|
|
407
|
-
};
|
|
408
|
-
} else {
|
|
409
|
-
specSelection = await resolveSpec({
|
|
410
|
-
warnLegacy: false,
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
const workingSpec = specSelection.spec;
|
|
415
|
-
|
|
416
|
-
// Validate acceptance criteria
|
|
417
|
-
const validation = await validateAcceptanceCriteria(workingSpec);
|
|
418
|
-
|
|
419
|
-
// Validate quality gates
|
|
420
|
-
const qualityGates = await validateQualityGates(changeId);
|
|
421
|
-
|
|
422
|
-
// Display results
|
|
423
|
-
displayArchiveResults(change, validation, qualityGates, specSelection);
|
|
424
|
-
|
|
425
|
-
// Check if we should proceed with archival
|
|
426
|
-
if (!validation.valid) {
|
|
427
|
-
console.log(chalk.yellow('Cannot archive: Incomplete acceptance criteria'));
|
|
428
|
-
if (!options.force) {
|
|
429
|
-
console.log(chalk.yellow('Use --force to archive anyway'));
|
|
430
|
-
return outputResult({
|
|
431
|
-
command: 'archive',
|
|
432
|
-
change: changeId,
|
|
433
|
-
archived: false,
|
|
434
|
-
reason: 'incomplete_criteria',
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
if (!qualityGates.valid) {
|
|
440
|
-
console.log(chalk.yellow('Cannot archive: Quality gates not met'));
|
|
441
|
-
if (!options.force) {
|
|
442
|
-
console.log(chalk.yellow('Use --force to archive anyway'));
|
|
443
|
-
return outputResult({
|
|
444
|
-
command: 'archive',
|
|
445
|
-
change: changeId,
|
|
446
|
-
archived: false,
|
|
447
|
-
reason: 'quality_gates_failed',
|
|
448
|
-
});
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Perform archival
|
|
453
|
-
console.log(chalk.blue('Performing archival...'));
|
|
454
|
-
|
|
455
|
-
// Update metadata with completion timestamp
|
|
456
|
-
change.metadata.completed_at = new Date().toISOString();
|
|
457
|
-
change.metadata.archived = true;
|
|
458
|
-
|
|
459
|
-
// Generate and save summary
|
|
460
|
-
const summary = await generateChangeSummary(change, workingSpec);
|
|
461
|
-
const summaryPath = path.join(change.path, 'archive-summary.md');
|
|
462
|
-
await fs.writeFile(summaryPath, summary);
|
|
463
|
-
|
|
464
|
-
// Archive the change
|
|
465
|
-
await archiveChange(change);
|
|
466
|
-
|
|
467
|
-
// Update provenance
|
|
468
|
-
await updateProvenance(change, specSelection);
|
|
469
|
-
|
|
470
|
-
console.log(chalk.green(`\nSuccessfully archived change: ${changeId}`));
|
|
471
|
-
|
|
472
|
-
return outputResult({
|
|
473
|
-
command: 'archive',
|
|
474
|
-
change: changeId,
|
|
475
|
-
archived: true,
|
|
476
|
-
specSelection: {
|
|
477
|
-
id: workingSpec?.id || null,
|
|
478
|
-
path: specSelection?.path || null,
|
|
479
|
-
type: specSelection?.type || null,
|
|
480
|
-
},
|
|
481
|
-
validation: validation.valid,
|
|
482
|
-
qualityGates: qualityGates.valid,
|
|
483
|
-
summary: summary,
|
|
484
|
-
});
|
|
485
|
-
},
|
|
486
|
-
'archive change',
|
|
487
|
-
true
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
module.exports = {
|
|
492
|
-
archiveCommand,
|
|
493
|
-
loadChange,
|
|
494
|
-
validateAcceptanceCriteria,
|
|
495
|
-
validateQualityGates,
|
|
496
|
-
generateChangeSummary,
|
|
497
|
-
archiveChange,
|
|
498
|
-
updateProvenance,
|
|
499
|
-
displayArchiveResults,
|
|
500
|
-
};
|
package/dist/commands/burnup.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Burn-up Command Handler
|
|
3
|
-
* Generates budget burn-up reports for scope visibility
|
|
4
|
-
* @author @darianrosebrook
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs-extra');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const yaml = require('js-yaml');
|
|
10
|
-
const chalk = require('chalk');
|
|
11
|
-
const { execSync } = require('child_process');
|
|
12
|
-
|
|
13
|
-
const { deriveBudget, generateBurnupReport } = require('../budget-derivation');
|
|
14
|
-
const { resolveSpec } = require('../utils/spec-resolver');
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Get actual git change statistics from the repository
|
|
18
|
-
* Analyzes changes since the last tag or initial commit
|
|
19
|
-
* @param {string} specDir - Directory containing the spec file
|
|
20
|
-
* @returns {Object} Stats with files_changed, lines_added, lines_removed, lines_changed
|
|
21
|
-
*/
|
|
22
|
-
function getGitChangeStats(specDir) {
|
|
23
|
-
try {
|
|
24
|
-
const cwd = specDir || process.cwd();
|
|
25
|
-
|
|
26
|
-
// Find the base reference - prefer last tag, fall back to first commit
|
|
27
|
-
let baseRef;
|
|
28
|
-
try {
|
|
29
|
-
baseRef = execSync('git describe --tags --abbrev=0 2>/dev/null', {
|
|
30
|
-
cwd,
|
|
31
|
-
encoding: 'utf8',
|
|
32
|
-
}).trim();
|
|
33
|
-
} catch {
|
|
34
|
-
// No tags, use first commit
|
|
35
|
-
try {
|
|
36
|
-
baseRef = execSync('git rev-list --max-parents=0 HEAD', {
|
|
37
|
-
cwd,
|
|
38
|
-
encoding: 'utf8',
|
|
39
|
-
}).trim();
|
|
40
|
-
} catch {
|
|
41
|
-
// Not a git repo or no commits
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Get file change count
|
|
47
|
-
const filesOutput = execSync(`git diff --name-only ${baseRef}..HEAD`, {
|
|
48
|
-
cwd,
|
|
49
|
-
encoding: 'utf8',
|
|
50
|
-
});
|
|
51
|
-
const filesChanged = filesOutput.trim().split('\n').filter(Boolean).length;
|
|
52
|
-
|
|
53
|
-
// Get line statistics using --numstat
|
|
54
|
-
const numstatOutput = execSync(`git diff --numstat ${baseRef}..HEAD`, {
|
|
55
|
-
cwd,
|
|
56
|
-
encoding: 'utf8',
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
let linesAdded = 0;
|
|
60
|
-
let linesRemoved = 0;
|
|
61
|
-
|
|
62
|
-
numstatOutput
|
|
63
|
-
.trim()
|
|
64
|
-
.split('\n')
|
|
65
|
-
.filter(Boolean)
|
|
66
|
-
.forEach((line) => {
|
|
67
|
-
const [added, removed] = line.split('\t');
|
|
68
|
-
// Skip binary files (shown as '-')
|
|
69
|
-
if (added !== '-' && removed !== '-') {
|
|
70
|
-
linesAdded += parseInt(added, 10) || 0;
|
|
71
|
-
linesRemoved += parseInt(removed, 10) || 0;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
files_changed: filesChanged,
|
|
77
|
-
lines_added: linesAdded,
|
|
78
|
-
lines_removed: linesRemoved,
|
|
79
|
-
lines_changed: linesAdded + linesRemoved,
|
|
80
|
-
base_ref: baseRef,
|
|
81
|
-
};
|
|
82
|
-
} catch (error) {
|
|
83
|
-
// Return null if git analysis fails
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Burn-up command handler
|
|
90
|
-
* @param {string} specFile - Path to spec file (positional, optional)
|
|
91
|
-
* @param {object} options - Command options including --spec-id
|
|
92
|
-
*/
|
|
93
|
-
async function burnupCommand(specFile, options = {}) {
|
|
94
|
-
try {
|
|
95
|
-
let specPath;
|
|
96
|
-
let spec;
|
|
97
|
-
|
|
98
|
-
// Resolve spec: explicit file > --spec-id > resolver default
|
|
99
|
-
if (specFile) {
|
|
100
|
-
specPath = specFile;
|
|
101
|
-
if (!fs.existsSync(specPath)) {
|
|
102
|
-
console.error(chalk.red(`Spec file not found: ${specPath}`));
|
|
103
|
-
process.exit(1);
|
|
104
|
-
}
|
|
105
|
-
spec = yaml.load(fs.readFileSync(specPath, 'utf8'));
|
|
106
|
-
} else {
|
|
107
|
-
const resolved = await resolveSpec({ specId: options.specId });
|
|
108
|
-
specPath = resolved.path;
|
|
109
|
-
spec = resolved.spec;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
console.log(chalk.cyan('Generating CAWS budget burn-up report...'));
|
|
113
|
-
|
|
114
|
-
// Derive budget
|
|
115
|
-
const derivedBudget = await deriveBudget(spec, path.dirname(specPath));
|
|
116
|
-
|
|
117
|
-
// Get actual git change statistics
|
|
118
|
-
const gitStats = getGitChangeStats(path.dirname(specPath));
|
|
119
|
-
|
|
120
|
-
let currentStats;
|
|
121
|
-
if (gitStats) {
|
|
122
|
-
currentStats = {
|
|
123
|
-
files_changed: gitStats.files_changed,
|
|
124
|
-
lines_changed: gitStats.lines_changed,
|
|
125
|
-
lines_added: gitStats.lines_added,
|
|
126
|
-
lines_removed: gitStats.lines_removed,
|
|
127
|
-
risk_tier: spec.risk_tier,
|
|
128
|
-
base_ref: gitStats.base_ref,
|
|
129
|
-
};
|
|
130
|
-
console.log(chalk.gray(` Analyzing changes since: ${gitStats.base_ref}`));
|
|
131
|
-
} else {
|
|
132
|
-
// Fallback if git analysis fails (not in a repo or no commits)
|
|
133
|
-
console.log(chalk.yellow(' Could not analyze git history, using zero values'));
|
|
134
|
-
currentStats = {
|
|
135
|
-
files_changed: 0,
|
|
136
|
-
lines_changed: 0,
|
|
137
|
-
lines_added: 0,
|
|
138
|
-
lines_removed: 0,
|
|
139
|
-
risk_tier: spec.risk_tier,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Generate report
|
|
144
|
-
const report = generateBurnupReport(derivedBudget, currentStats);
|
|
145
|
-
|
|
146
|
-
console.log(report);
|
|
147
|
-
|
|
148
|
-
// Show detailed breakdown
|
|
149
|
-
console.log(chalk.gray('\nDetailed Budget Analysis:'));
|
|
150
|
-
console.log(
|
|
151
|
-
chalk.gray(
|
|
152
|
-
` Baseline (Tier ${spec.risk_tier}): ${derivedBudget.baseline.max_files} files, ${derivedBudget.baseline.max_loc} LOC`
|
|
153
|
-
)
|
|
154
|
-
);
|
|
155
|
-
console.log(
|
|
156
|
-
chalk.gray(
|
|
157
|
-
` Effective Budget: ${derivedBudget.effective.max_files} files, ${derivedBudget.effective.max_loc} LOC`
|
|
158
|
-
)
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
if (derivedBudget.waivers_applied.length > 0) {
|
|
162
|
-
console.log(chalk.yellow(` Waivers Applied: ${derivedBudget.waivers_applied.join(', ')}`));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
console.log(
|
|
166
|
-
chalk.gray(
|
|
167
|
-
` Current Usage: ${currentStats.files_changed} files, ${currentStats.lines_changed} LOC`
|
|
168
|
-
)
|
|
169
|
-
);
|
|
170
|
-
if (currentStats.lines_added !== undefined) {
|
|
171
|
-
console.log(
|
|
172
|
-
chalk.gray(
|
|
173
|
-
` Breakdown: +${currentStats.lines_added} added, -${currentStats.lines_removed} removed`
|
|
174
|
-
)
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const filePercent = Math.round(
|
|
179
|
-
(currentStats.files_changed / derivedBudget.effective.max_files) * 100
|
|
180
|
-
);
|
|
181
|
-
const locPercent = Math.round(
|
|
182
|
-
(currentStats.lines_changed / derivedBudget.effective.max_loc) * 100
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
if (filePercent > 90 || locPercent > 90) {
|
|
186
|
-
console.log(chalk.yellow('\nWARNING: Approaching budget limits'));
|
|
187
|
-
} else {
|
|
188
|
-
console.log(chalk.green('\nWithin budget limits'));
|
|
189
|
-
}
|
|
190
|
-
} catch (error) {
|
|
191
|
-
console.error(chalk.red('Error generating burn-up report:'), error.message);
|
|
192
|
-
process.exit(1);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
module.exports = {
|
|
197
|
-
burnupCommand,
|
|
198
|
-
};
|