@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
|
@@ -1,530 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Working-State Layer
|
|
3
|
-
*
|
|
4
|
-
* Runtime companion to specs that tracks what an agent is currently doing.
|
|
5
|
-
* Persists current phase, touched files, gate results, blockers, and
|
|
6
|
-
* next actions to `.caws/state/<spec-id>.json`.
|
|
7
|
-
*
|
|
8
|
-
* All writes are non-fatal — if state cannot be persisted the calling
|
|
9
|
-
* command continues normally.
|
|
10
|
-
*
|
|
11
|
-
* @author @darianrosebrook
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const fs = require('fs');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const { lifecycle, EVENTS } = require('./lifecycle-events');
|
|
17
|
-
|
|
18
|
-
const STATE_DIR = '.caws/state';
|
|
19
|
-
const STATE_SCHEMA_VERSION = 'caws.state.v1';
|
|
20
|
-
const MAX_HISTORY = 20;
|
|
21
|
-
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
// Helpers
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Find the project root by walking up to the nearest .caws/ directory.
|
|
28
|
-
* Falls back to cwd if nothing found.
|
|
29
|
-
* @param {string} [startDir]
|
|
30
|
-
* @returns {string}
|
|
31
|
-
*/
|
|
32
|
-
function findRoot(startDir) {
|
|
33
|
-
let dir = startDir || process.cwd();
|
|
34
|
-
while (dir !== path.dirname(dir)) {
|
|
35
|
-
if (fs.existsSync(path.join(dir, '.caws'))) return dir;
|
|
36
|
-
dir = path.dirname(dir);
|
|
37
|
-
}
|
|
38
|
-
return startDir || process.cwd();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Resolve the absolute path for a spec's state file.
|
|
43
|
-
*
|
|
44
|
-
* **Fail-loud contract (CAWSFIX-02)**: throws if `specId` is undefined,
|
|
45
|
-
* null, empty, non-string, or whitespace-only. This fence prevents the
|
|
46
|
-
* `.caws/state/undefined.json` bug class — a historical source of
|
|
47
|
-
* silent data corruption where legacy callers passed `spec.id` without
|
|
48
|
-
* checking whether `spec` was a valid resolved spec.
|
|
49
|
-
*
|
|
50
|
-
* Symmetric with the `REQUIRES_SPEC_ID` fence in `event-log.js` from
|
|
51
|
-
* EVLOG-001: both state-layer and event-log writes now refuse to
|
|
52
|
-
* proceed with an undefined spec id. Callers that legitimately lack a
|
|
53
|
-
* spec id (e.g. legacy working-specs, failed resolveSpec) must guard
|
|
54
|
-
* their calls with `if (spec && spec.id)` — the pattern `gates.js`
|
|
55
|
-
* already uses and which `validate.js`/`evaluate.js`/`verify-acs.js`
|
|
56
|
-
* are updated to use in the same tranche.
|
|
57
|
-
*
|
|
58
|
-
* @param {string} specId
|
|
59
|
-
* @param {string} [projectRoot]
|
|
60
|
-
* @returns {string}
|
|
61
|
-
* @throws {Error} if specId is not a non-empty string
|
|
62
|
-
*/
|
|
63
|
-
function getStatePath(specId, projectRoot) {
|
|
64
|
-
if (!specId || typeof specId !== 'string' || specId.trim() === '') {
|
|
65
|
-
throw new Error(
|
|
66
|
-
`working-state.getStatePath: specId must be a non-empty string ` +
|
|
67
|
-
`(got ${JSON.stringify(specId)}). This is the fence that prevents ` +
|
|
68
|
-
`the .caws/state/undefined.json bug class — callers without a ` +
|
|
69
|
-
`resolved spec id must guard with \`if (spec && spec.id)\` before ` +
|
|
70
|
-
`invoking saveState/updateState/recordValidation/etc.`
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
const root = projectRoot || findRoot();
|
|
74
|
-
return path.join(root, STATE_DIR, `${specId}.json`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// ---------------------------------------------------------------------------
|
|
78
|
-
// Core CRUD
|
|
79
|
-
// ---------------------------------------------------------------------------
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Build an empty default state for a new spec.
|
|
83
|
-
* @param {string} specId
|
|
84
|
-
* @returns {object}
|
|
85
|
-
*/
|
|
86
|
-
function initializeState(specId) {
|
|
87
|
-
return {
|
|
88
|
-
schema: STATE_SCHEMA_VERSION,
|
|
89
|
-
spec_id: specId,
|
|
90
|
-
updated_at: new Date().toISOString(),
|
|
91
|
-
phase: 'not-started',
|
|
92
|
-
files_touched: [],
|
|
93
|
-
validation: null,
|
|
94
|
-
evaluation: null,
|
|
95
|
-
gates: null,
|
|
96
|
-
acceptance_criteria: null,
|
|
97
|
-
blockers: [],
|
|
98
|
-
next_actions: [],
|
|
99
|
-
history: [],
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Load state from disk. Returns null if file does not exist.
|
|
105
|
-
* @param {string} specId
|
|
106
|
-
* @param {string} [projectRoot]
|
|
107
|
-
* @returns {object|null}
|
|
108
|
-
*/
|
|
109
|
-
function loadState(specId, projectRoot) {
|
|
110
|
-
const filePath = getStatePath(specId, projectRoot);
|
|
111
|
-
if (!fs.existsSync(filePath)) return null;
|
|
112
|
-
try {
|
|
113
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
114
|
-
} catch {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Save state atomically (write-then-rename).
|
|
121
|
-
* @param {string} specId
|
|
122
|
-
* @param {object} state
|
|
123
|
-
* @param {string} [projectRoot]
|
|
124
|
-
*/
|
|
125
|
-
function saveState(specId, state, projectRoot) {
|
|
126
|
-
const filePath = getStatePath(specId, projectRoot);
|
|
127
|
-
const dir = path.dirname(filePath);
|
|
128
|
-
if (!fs.existsSync(dir)) {
|
|
129
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
130
|
-
}
|
|
131
|
-
const tmpPath = filePath + '.tmp.' + process.pid;
|
|
132
|
-
fs.writeFileSync(tmpPath, JSON.stringify(state, null, 2));
|
|
133
|
-
fs.renameSync(tmpPath, filePath);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Delete state file for a spec.
|
|
138
|
-
* @param {string} specId
|
|
139
|
-
* @param {string} [projectRoot]
|
|
140
|
-
*/
|
|
141
|
-
function deleteState(specId, projectRoot) {
|
|
142
|
-
const filePath = getStatePath(specId, projectRoot);
|
|
143
|
-
if (fs.existsSync(filePath)) {
|
|
144
|
-
fs.unlinkSync(filePath);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Load → patch → recompute derived fields → save.
|
|
150
|
-
* @param {string} specId
|
|
151
|
-
* @param {object} patch - Partial state to merge
|
|
152
|
-
* @param {object} [options]
|
|
153
|
-
* @param {string} [options.projectRoot]
|
|
154
|
-
* @param {object} [options.spec] - Spec object for derived-field computation
|
|
155
|
-
* @param {string} [options.command] - Command name for history entry
|
|
156
|
-
* @param {string} [options.summary] - Summary for history entry
|
|
157
|
-
* @returns {object} Updated state
|
|
158
|
-
*/
|
|
159
|
-
function updateState(specId, patch, options = {}) {
|
|
160
|
-
const { projectRoot, spec, command, summary } = options;
|
|
161
|
-
let state = loadState(specId, projectRoot) || initializeState(specId);
|
|
162
|
-
|
|
163
|
-
// Merge top-level sections (replace, not deep-merge)
|
|
164
|
-
for (const [key, value] of Object.entries(patch)) {
|
|
165
|
-
if (key === 'files_touched' && Array.isArray(value)) {
|
|
166
|
-
// Merge file lists with dedup
|
|
167
|
-
const merged = new Set([...(state.files_touched || []), ...value]);
|
|
168
|
-
state.files_touched = [...merged];
|
|
169
|
-
} else {
|
|
170
|
-
state[key] = value;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Append history
|
|
175
|
-
if (command) {
|
|
176
|
-
state.history = state.history || [];
|
|
177
|
-
state.history.push({
|
|
178
|
-
timestamp: new Date().toISOString(),
|
|
179
|
-
command,
|
|
180
|
-
summary: summary || '',
|
|
181
|
-
});
|
|
182
|
-
// Cap at MAX_HISTORY
|
|
183
|
-
if (state.history.length > MAX_HISTORY) {
|
|
184
|
-
state.history = state.history.slice(-MAX_HISTORY);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Recompute derived fields
|
|
189
|
-
state.blockers = computeBlockers(state);
|
|
190
|
-
state.next_actions = computeNextActions(state, spec);
|
|
191
|
-
const oldPhase = state.phase;
|
|
192
|
-
state.phase = computePhase(state, spec);
|
|
193
|
-
state.updated_at = new Date().toISOString();
|
|
194
|
-
|
|
195
|
-
// Emit phase transition event
|
|
196
|
-
if (oldPhase && oldPhase !== state.phase) {
|
|
197
|
-
try {
|
|
198
|
-
lifecycle.emit(EVENTS.PHASE_TRANSITION, {
|
|
199
|
-
specId, oldPhase, newPhase: state.phase,
|
|
200
|
-
timestamp: state.updated_at,
|
|
201
|
-
});
|
|
202
|
-
} catch { /* non-fatal */ }
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
saveState(specId, state, projectRoot);
|
|
206
|
-
return state;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// ---------------------------------------------------------------------------
|
|
210
|
-
// Record helpers — called by individual commands
|
|
211
|
-
// ---------------------------------------------------------------------------
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Record validation result.
|
|
215
|
-
* @param {string} specId
|
|
216
|
-
* @param {object} result
|
|
217
|
-
* @param {boolean} result.passed
|
|
218
|
-
* @param {number} [result.compliance_score]
|
|
219
|
-
* @param {string} [result.grade]
|
|
220
|
-
* @param {number} [result.error_count]
|
|
221
|
-
* @param {number} [result.warning_count]
|
|
222
|
-
* @param {string} [projectRoot]
|
|
223
|
-
*/
|
|
224
|
-
function recordValidation(specId, result, projectRoot) {
|
|
225
|
-
const validation = {
|
|
226
|
-
last_run: new Date().toISOString(),
|
|
227
|
-
passed: result.passed,
|
|
228
|
-
compliance_score: result.compliance_score ?? null,
|
|
229
|
-
grade: result.grade ?? null,
|
|
230
|
-
error_count: result.error_count ?? 0,
|
|
231
|
-
warning_count: result.warning_count ?? 0,
|
|
232
|
-
};
|
|
233
|
-
const summaryText = result.passed
|
|
234
|
-
? `Passed (Grade ${validation.grade || '?'})`
|
|
235
|
-
: `Failed — ${validation.error_count} error(s)`;
|
|
236
|
-
updateState(specId, { validation }, {
|
|
237
|
-
projectRoot,
|
|
238
|
-
command: 'validate',
|
|
239
|
-
summary: summaryText,
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Record evaluation result.
|
|
245
|
-
* @param {string} specId
|
|
246
|
-
* @param {object} result
|
|
247
|
-
* @param {number} result.score
|
|
248
|
-
* @param {number} result.max_score
|
|
249
|
-
* @param {number} result.percentage
|
|
250
|
-
* @param {string} result.grade
|
|
251
|
-
* @param {number} result.checks_passed
|
|
252
|
-
* @param {number} result.checks_total
|
|
253
|
-
* @param {string} [projectRoot]
|
|
254
|
-
*/
|
|
255
|
-
function recordEvaluation(specId, result, projectRoot) {
|
|
256
|
-
const evaluation = {
|
|
257
|
-
last_run: new Date().toISOString(),
|
|
258
|
-
score: result.score,
|
|
259
|
-
max_score: result.max_score,
|
|
260
|
-
percentage: result.percentage,
|
|
261
|
-
grade: result.grade,
|
|
262
|
-
checks_passed: result.checks_passed,
|
|
263
|
-
checks_total: result.checks_total,
|
|
264
|
-
};
|
|
265
|
-
updateState(specId, { evaluation }, {
|
|
266
|
-
projectRoot,
|
|
267
|
-
command: 'evaluate',
|
|
268
|
-
summary: `${result.score}/${result.max_score} (${result.percentage}%) Grade ${result.grade}`,
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Record gate evaluation results.
|
|
274
|
-
* @param {string} specId
|
|
275
|
-
* @param {object} report - Report from evaluateGates()
|
|
276
|
-
* @param {boolean} report.passed
|
|
277
|
-
* @param {object} report.summary
|
|
278
|
-
* @param {object[]} report.gates - Individual gate results
|
|
279
|
-
* @param {string} [context] - Execution context (cli, commit, edit)
|
|
280
|
-
* @param {string} [projectRoot]
|
|
281
|
-
*/
|
|
282
|
-
function recordGates(specId, report, context, projectRoot) {
|
|
283
|
-
const gates = {
|
|
284
|
-
last_run: new Date().toISOString(),
|
|
285
|
-
context: context || 'cli',
|
|
286
|
-
passed: report.passed,
|
|
287
|
-
summary: report.summary,
|
|
288
|
-
results: (report.gates || []).map(g => ({
|
|
289
|
-
name: g.name,
|
|
290
|
-
status: g.status,
|
|
291
|
-
mode: g.mode,
|
|
292
|
-
})),
|
|
293
|
-
};
|
|
294
|
-
const { blocked, warned, passed } = report.summary || {};
|
|
295
|
-
const summaryText = `${passed || 0} passed, ${blocked || 0} blocked, ${warned || 0} warned`;
|
|
296
|
-
updateState(specId, { gates }, {
|
|
297
|
-
projectRoot,
|
|
298
|
-
command: 'gates',
|
|
299
|
-
summary: summaryText,
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Record acceptance-criteria verification results.
|
|
305
|
-
* @param {string} specId
|
|
306
|
-
* @param {object} result
|
|
307
|
-
* @param {number} result.total
|
|
308
|
-
* @param {number} result.pass
|
|
309
|
-
* @param {number} result.fail
|
|
310
|
-
* @param {number} result.unchecked
|
|
311
|
-
* @param {object[]} [result.results] - Per-AC results
|
|
312
|
-
* @param {string} [projectRoot]
|
|
313
|
-
*/
|
|
314
|
-
function recordACVerification(specId, result, projectRoot) {
|
|
315
|
-
const acceptance_criteria = {
|
|
316
|
-
last_run: new Date().toISOString(),
|
|
317
|
-
total: result.total,
|
|
318
|
-
pass: result.pass,
|
|
319
|
-
fail: result.fail,
|
|
320
|
-
unchecked: result.unchecked,
|
|
321
|
-
results: (result.results || []).map(r => ({
|
|
322
|
-
id: r.id,
|
|
323
|
-
status: r.status,
|
|
324
|
-
})),
|
|
325
|
-
};
|
|
326
|
-
const summaryText = `${result.pass}/${result.total} pass, ${result.fail} fail, ${result.unchecked} unchecked`;
|
|
327
|
-
updateState(specId, { acceptance_criteria }, {
|
|
328
|
-
projectRoot,
|
|
329
|
-
command: 'verify-acs',
|
|
330
|
-
summary: summaryText,
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Merge touched files into state (additive, deduped).
|
|
336
|
-
* @param {string} specId
|
|
337
|
-
* @param {string[]} files
|
|
338
|
-
* @param {string} [projectRoot]
|
|
339
|
-
*/
|
|
340
|
-
function mergeFilesTouched(specId, files, projectRoot) {
|
|
341
|
-
if (!files || files.length === 0) return;
|
|
342
|
-
updateState(specId, { files_touched: files }, {
|
|
343
|
-
projectRoot,
|
|
344
|
-
command: 'session',
|
|
345
|
-
summary: `+${files.length} file(s) touched`,
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// ---------------------------------------------------------------------------
|
|
350
|
-
// Derived-field computation
|
|
351
|
-
// ---------------------------------------------------------------------------
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Derive the current workflow phase from state evidence.
|
|
355
|
-
* @param {object} state
|
|
356
|
-
* @param {object} [spec] - Spec object (for AC count)
|
|
357
|
-
* @returns {string}
|
|
358
|
-
*/
|
|
359
|
-
function computePhase(state, _spec) {
|
|
360
|
-
const v = state.validation;
|
|
361
|
-
const e = state.evaluation;
|
|
362
|
-
const g = state.gates;
|
|
363
|
-
const ac = state.acceptance_criteria;
|
|
364
|
-
|
|
365
|
-
// Nothing has run yet
|
|
366
|
-
if (!v && !e && !g && !ac) return 'not-started';
|
|
367
|
-
|
|
368
|
-
// Validation failed or evaluation below 70% → still authoring the spec
|
|
369
|
-
if (v && !v.passed) return 'spec-authoring';
|
|
370
|
-
if (e && e.percentage < 70) return 'spec-authoring';
|
|
371
|
-
|
|
372
|
-
// All ACs pass, all gates pass, evaluation >= 90% → complete
|
|
373
|
-
if (ac && ac.total > 0 && ac.fail === 0 && ac.unchecked === 0
|
|
374
|
-
&& g && g.passed
|
|
375
|
-
&& e && e.percentage >= 90) {
|
|
376
|
-
return 'complete';
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// All ACs pass, gates have been run → verification phase
|
|
380
|
-
if (ac && ac.total > 0 && ac.fail === 0 && ac.unchecked === 0 && g) {
|
|
381
|
-
return 'verification';
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// Otherwise: implementation
|
|
385
|
-
return 'implementation';
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Extract active blockers from state.
|
|
390
|
-
* @param {object} state
|
|
391
|
-
* @returns {object[]}
|
|
392
|
-
*/
|
|
393
|
-
function computeBlockers(state) {
|
|
394
|
-
const blockers = [];
|
|
395
|
-
const now = new Date().toISOString();
|
|
396
|
-
|
|
397
|
-
// Validation failure
|
|
398
|
-
if (state.validation && !state.validation.passed) {
|
|
399
|
-
blockers.push({
|
|
400
|
-
type: 'validation_failure',
|
|
401
|
-
message: `Validation failed with ${state.validation.error_count} error(s)`,
|
|
402
|
-
since: state.validation.last_run || now,
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// Gate failures (block-mode only)
|
|
407
|
-
if (state.gates && state.gates.results) {
|
|
408
|
-
for (const g of state.gates.results) {
|
|
409
|
-
if (g.status === 'fail' && g.mode === 'block') {
|
|
410
|
-
blockers.push({
|
|
411
|
-
type: 'gate_failure',
|
|
412
|
-
gate: g.name,
|
|
413
|
-
message: `Gate "${g.name}" is blocking`,
|
|
414
|
-
since: state.gates.last_run || now,
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
// AC failures
|
|
421
|
-
if (state.acceptance_criteria && state.acceptance_criteria.fail > 0) {
|
|
422
|
-
const failingIds = (state.acceptance_criteria.results || [])
|
|
423
|
-
.filter(r => r.status === 'FAIL')
|
|
424
|
-
.map(r => r.id);
|
|
425
|
-
blockers.push({
|
|
426
|
-
type: 'ac_failure',
|
|
427
|
-
message: `${state.acceptance_criteria.fail} acceptance criteria failing${failingIds.length ? ': ' + failingIds.join(', ') : ''}`,
|
|
428
|
-
since: state.acceptance_criteria.last_run || new Date().toISOString(),
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
return blockers;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Compute ordered next actions based on current state.
|
|
437
|
-
* @param {object} state
|
|
438
|
-
* @param {object} [spec]
|
|
439
|
-
* @returns {string[]}
|
|
440
|
-
*/
|
|
441
|
-
function computeNextActions(state, _spec) {
|
|
442
|
-
const actions = [];
|
|
443
|
-
|
|
444
|
-
// Validation failed → fix first
|
|
445
|
-
if (state.validation && !state.validation.passed) {
|
|
446
|
-
actions.push('Fix validation errors, then run: caws validate');
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// Gate blockers
|
|
450
|
-
if (state.gates && state.gates.results) {
|
|
451
|
-
for (const g of state.gates.results) {
|
|
452
|
-
if (g.status === 'fail' && g.mode === 'block') {
|
|
453
|
-
actions.push(`Fix gate violation: ${g.name}`);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// Failing ACs
|
|
459
|
-
if (state.acceptance_criteria) {
|
|
460
|
-
const failing = (state.acceptance_criteria.results || [])
|
|
461
|
-
.filter(r => r.status === 'FAIL')
|
|
462
|
-
.map(r => r.id);
|
|
463
|
-
if (failing.length > 0) {
|
|
464
|
-
actions.push(`Fix failing acceptance criteria: ${failing.join(', ')}`);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
const unchecked = state.acceptance_criteria.unchecked || 0;
|
|
468
|
-
if (unchecked > 0) {
|
|
469
|
-
actions.push(`Add tests for ${unchecked} unchecked acceptance criteria`);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// Low evaluation
|
|
474
|
-
if (state.evaluation && state.evaluation.percentage < 80) {
|
|
475
|
-
actions.push(`Improve spec quality (currently ${state.evaluation.percentage}%), run: caws evaluate`);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// No validation yet
|
|
479
|
-
if (!state.validation) {
|
|
480
|
-
actions.push('Run: caws validate');
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// No evaluation yet
|
|
484
|
-
if (!state.evaluation) {
|
|
485
|
-
actions.push('Run: caws evaluate');
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// No AC verification yet
|
|
489
|
-
if (!state.acceptance_criteria) {
|
|
490
|
-
actions.push('Run: caws verify-acs');
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Everything green
|
|
494
|
-
if (actions.length === 0) {
|
|
495
|
-
actions.push('All checks passing. Ready for merge. Run: caws verify-acs --run for final verification.');
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
return actions;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// ---------------------------------------------------------------------------
|
|
502
|
-
// Exports
|
|
503
|
-
// ---------------------------------------------------------------------------
|
|
504
|
-
|
|
505
|
-
module.exports = {
|
|
506
|
-
// Core
|
|
507
|
-
loadState,
|
|
508
|
-
saveState,
|
|
509
|
-
deleteState,
|
|
510
|
-
updateState,
|
|
511
|
-
initializeState,
|
|
512
|
-
getStatePath,
|
|
513
|
-
|
|
514
|
-
// Recorders
|
|
515
|
-
recordValidation,
|
|
516
|
-
recordEvaluation,
|
|
517
|
-
recordGates,
|
|
518
|
-
recordACVerification,
|
|
519
|
-
mergeFilesTouched,
|
|
520
|
-
|
|
521
|
-
// Derived fields
|
|
522
|
-
computePhase,
|
|
523
|
-
computeBlockers,
|
|
524
|
-
computeNextActions,
|
|
525
|
-
|
|
526
|
-
// Constants
|
|
527
|
-
STATE_DIR,
|
|
528
|
-
STATE_SCHEMA_VERSION,
|
|
529
|
-
MAX_HISTORY,
|
|
530
|
-
};
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview YAML Validation Utilities
|
|
3
|
-
* Functions for validating YAML syntax and structure
|
|
4
|
-
* @author @darianrosebrook
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const yaml = require('js-yaml');
|
|
8
|
-
const fs = require('fs-extra');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Validate YAML syntax for a file
|
|
13
|
-
* @param {string} filePath - Path to YAML file
|
|
14
|
-
* @returns {Object} Validation result with valid flag and error details
|
|
15
|
-
*/
|
|
16
|
-
function validateYamlSyntax(filePath) {
|
|
17
|
-
try {
|
|
18
|
-
if (!fs.existsSync(filePath)) {
|
|
19
|
-
return {
|
|
20
|
-
valid: false,
|
|
21
|
-
error: `File not found: ${filePath}`,
|
|
22
|
-
line: null,
|
|
23
|
-
column: null,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
28
|
-
yaml.load(content); // Will throw if invalid
|
|
29
|
-
|
|
30
|
-
return { valid: true };
|
|
31
|
-
} catch (error) {
|
|
32
|
-
return {
|
|
33
|
-
valid: false,
|
|
34
|
-
error: error.message,
|
|
35
|
-
line: error.mark?.line ? error.mark.line + 1 : null, // Convert to 1-based
|
|
36
|
-
column: error.mark?.column ? error.mark.column + 1 : null, // Convert to 1-based
|
|
37
|
-
snippet: error.mark?.snippet || null,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Validate YAML syntax for multiple files
|
|
44
|
-
* @param {string[]} filePaths - Array of file paths to validate
|
|
45
|
-
* @returns {Object} Validation results with summary
|
|
46
|
-
*/
|
|
47
|
-
function validateYamlFiles(filePaths) {
|
|
48
|
-
const results = {
|
|
49
|
-
valid: true,
|
|
50
|
-
files: [],
|
|
51
|
-
errors: [],
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
for (const filePath of filePaths) {
|
|
55
|
-
const validation = validateYamlSyntax(filePath);
|
|
56
|
-
const relativePath = path.relative(process.cwd(), filePath);
|
|
57
|
-
|
|
58
|
-
results.files.push({
|
|
59
|
-
path: relativePath,
|
|
60
|
-
...validation,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
if (!validation.valid) {
|
|
64
|
-
results.valid = false;
|
|
65
|
-
results.errors.push({
|
|
66
|
-
file: relativePath,
|
|
67
|
-
error: validation.error,
|
|
68
|
-
line: validation.line,
|
|
69
|
-
column: validation.column,
|
|
70
|
-
snippet: validation.snippet,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return results;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Find all YAML files in .caws directory
|
|
80
|
-
* @param {string} projectRoot - Project root directory
|
|
81
|
-
* @returns {string[]} Array of YAML file paths
|
|
82
|
-
*/
|
|
83
|
-
function findCawsYamlFiles(projectRoot) {
|
|
84
|
-
const cawsDir = path.join(projectRoot, '.caws');
|
|
85
|
-
const yamlFiles = [];
|
|
86
|
-
|
|
87
|
-
if (!fs.existsSync(cawsDir)) {
|
|
88
|
-
return yamlFiles;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function walkDir(dir) {
|
|
92
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
93
|
-
|
|
94
|
-
for (const entry of entries) {
|
|
95
|
-
const fullPath = path.join(dir, entry.name);
|
|
96
|
-
|
|
97
|
-
if (entry.isDirectory()) {
|
|
98
|
-
walkDir(fullPath);
|
|
99
|
-
} else if (
|
|
100
|
-
entry.isFile() &&
|
|
101
|
-
(entry.name.endsWith('.yaml') || entry.name.endsWith('.yml'))
|
|
102
|
-
) {
|
|
103
|
-
yamlFiles.push(fullPath);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
walkDir(cawsDir);
|
|
109
|
-
return yamlFiles;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Validate all CAWS YAML files in project
|
|
114
|
-
* @param {string} projectRoot - Project root directory
|
|
115
|
-
* @returns {Object} Validation results
|
|
116
|
-
*/
|
|
117
|
-
function validateAllCawsYamlFiles(projectRoot) {
|
|
118
|
-
const yamlFiles = findCawsYamlFiles(projectRoot);
|
|
119
|
-
return validateYamlFiles(yamlFiles);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Format validation error for display
|
|
124
|
-
* @param {Object} error - Error object from validateYamlSyntax
|
|
125
|
-
* @param {string} filePath - File path
|
|
126
|
-
* @returns {string} Formatted error message
|
|
127
|
-
*/
|
|
128
|
-
function formatYamlError(error, filePath) {
|
|
129
|
-
const relativePath = path.relative(process.cwd(), filePath);
|
|
130
|
-
let message = `Invalid YAML in ${relativePath}\n`;
|
|
131
|
-
message += ` Error: ${error.error}\n`;
|
|
132
|
-
|
|
133
|
-
if (error.line !== null) {
|
|
134
|
-
message += ` Line: ${error.line}`;
|
|
135
|
-
if (error.column !== null) {
|
|
136
|
-
message += `, Column: ${error.column}`;
|
|
137
|
-
}
|
|
138
|
-
message += '\n';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (error.snippet) {
|
|
142
|
-
message += ` ${error.snippet}\n`;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return message;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
module.exports = {
|
|
149
|
-
validateYamlSyntax,
|
|
150
|
-
validateYamlFiles,
|
|
151
|
-
findCawsYamlFiles,
|
|
152
|
-
validateAllCawsYamlFiles,
|
|
153
|
-
formatYamlError,
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
|