@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,381 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# CAWS Scope Guard Hook for Claude Code
|
|
3
|
-
# Validates file edits against scope boundaries from working-spec + feature specs
|
|
4
|
-
# Specs with terminal status (completed, closed, archived) are skipped
|
|
5
|
-
# @author @darianrosebrook
|
|
6
|
-
|
|
7
|
-
set -euo pipefail
|
|
8
|
-
|
|
9
|
-
# Read JSON input from Claude Code
|
|
10
|
-
INPUT=$(cat)
|
|
11
|
-
|
|
12
|
-
# Extract file path from PreToolUse input
|
|
13
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
|
|
14
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
|
|
15
|
-
|
|
16
|
-
# Only check Write/Edit operations
|
|
17
|
-
if [[ "$TOOL_NAME" != "Write" ]] && [[ "$TOOL_NAME" != "Edit" ]]; then
|
|
18
|
-
exit 0
|
|
19
|
-
fi
|
|
20
|
-
|
|
21
|
-
if [[ -z "$FILE_PATH" ]]; then
|
|
22
|
-
exit 0
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
|
-
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
26
|
-
SPEC_FILE="$PROJECT_DIR/.caws/working-spec.yaml"
|
|
27
|
-
SCOPE_FILE="$PROJECT_DIR/.caws/scope.json"
|
|
28
|
-
|
|
29
|
-
# Check if any spec infrastructure exists
|
|
30
|
-
if [[ ! -f "$SPEC_FILE" ]] && [[ ! -f "$SCOPE_FILE" ]] && [[ ! -d "$PROJECT_DIR/.caws/specs" ]]; then
|
|
31
|
-
exit 0
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
# Get relative path from project root (portable — macOS realpath lacks --relative-to)
|
|
35
|
-
if [[ "$FILE_PATH" == "$PROJECT_DIR"/* ]]; then
|
|
36
|
-
REL_PATH="${FILE_PATH#$PROJECT_DIR/}"
|
|
37
|
-
else
|
|
38
|
-
REL_PATH="$FILE_PATH"
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# Lite mode: check scope.json if no working-spec.yaml
|
|
42
|
-
if [[ ! -f "$SPEC_FILE" ]] && [[ -f "$SCOPE_FILE" ]]; then
|
|
43
|
-
if command -v node >/dev/null 2>&1; then
|
|
44
|
-
LITE_CHECK=$(node -e "
|
|
45
|
-
const fs = require('fs');
|
|
46
|
-
const path = require('path');
|
|
47
|
-
|
|
48
|
-
function globToRegex(pattern) {
|
|
49
|
-
let i = 0, re = '';
|
|
50
|
-
while (i < pattern.length) {
|
|
51
|
-
const c = pattern[i];
|
|
52
|
-
if (c === '*' && pattern[i+1] === '*') {
|
|
53
|
-
re += '.*'; i += 2;
|
|
54
|
-
if (pattern[i] === '/') i++;
|
|
55
|
-
} else if (c === '*') {
|
|
56
|
-
re += '[^/]*'; i++;
|
|
57
|
-
} else if (c === '?') {
|
|
58
|
-
re += '[^/]'; i++;
|
|
59
|
-
} else if (c === '[') {
|
|
60
|
-
const end = pattern.indexOf(']', i);
|
|
61
|
-
if (end > i) { re += pattern.slice(i, end + 1); i = end + 1; }
|
|
62
|
-
else { re += '\\\\['; i++; }
|
|
63
|
-
} else if (c === '{') {
|
|
64
|
-
const end = pattern.indexOf('}', i);
|
|
65
|
-
if (end > i) {
|
|
66
|
-
const alts = pattern.slice(i + 1, end).split(',').map(a => a.trim());
|
|
67
|
-
re += '(?:' + alts.join('|') + ')'; i = end + 1;
|
|
68
|
-
} else { re += '\\\\{'; i++; }
|
|
69
|
-
} else if ('.+^$|()'.includes(c)) {
|
|
70
|
-
re += '\\\\' + c; i++;
|
|
71
|
-
} else {
|
|
72
|
-
re += c; i++;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return new RegExp(re);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
const scope = JSON.parse(fs.readFileSync('$SCOPE_FILE', 'utf8'));
|
|
80
|
-
const filePath = '$REL_PATH';
|
|
81
|
-
const dirs = scope.allowedDirectories || [];
|
|
82
|
-
const banned = scope.bannedPatterns || {};
|
|
83
|
-
|
|
84
|
-
// Check banned file patterns
|
|
85
|
-
const basename = path.basename(filePath);
|
|
86
|
-
const bannedFiles = banned.files || [];
|
|
87
|
-
for (const pattern of bannedFiles) {
|
|
88
|
-
const regex = globToRegex(pattern);
|
|
89
|
-
if (regex.test(basename)) {
|
|
90
|
-
console.log('banned:' + pattern);
|
|
91
|
-
process.exit(0);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Check banned doc patterns
|
|
96
|
-
const bannedDocs = banned.docs || [];
|
|
97
|
-
for (const pattern of bannedDocs) {
|
|
98
|
-
const regex = globToRegex(pattern);
|
|
99
|
-
if (regex.test(basename)) {
|
|
100
|
-
console.log('banned:' + pattern);
|
|
101
|
-
process.exit(0);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Check allowed directories
|
|
106
|
-
if (dirs.length > 0) {
|
|
107
|
-
const normalized = filePath.replace(/\\\\\\\\/g, '/');
|
|
108
|
-
let found = false;
|
|
109
|
-
for (const dir of dirs) {
|
|
110
|
-
const d = dir.replace(/\\/$/, '');
|
|
111
|
-
if (normalized.startsWith(d + '/') || normalized === d) { found = true; break; }
|
|
112
|
-
}
|
|
113
|
-
// Allow root-level files and .caws/ directory
|
|
114
|
-
if (!normalized.includes('/') || normalized.startsWith('.caws/')) found = true;
|
|
115
|
-
if (!found) {
|
|
116
|
-
console.log('not_allowed');
|
|
117
|
-
process.exit(0);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
console.log('allowed');
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.log('error:' + error.message);
|
|
123
|
-
}
|
|
124
|
-
" 2>&1)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if [[ "$LITE_CHECK" == error:* ]]; then
|
|
128
|
-
ERROR_MSG="${LITE_CHECK#error:}"
|
|
129
|
-
echo "BLOCKED: Scope check failed — cannot verify file is in scope" >&2
|
|
130
|
-
echo " Error: $ERROR_MSG" >&2
|
|
131
|
-
exit 2
|
|
132
|
-
fi
|
|
133
|
-
|
|
134
|
-
if [[ "$LITE_CHECK" == banned:* ]]; then
|
|
135
|
-
PATTERN="${LITE_CHECK#banned:}"
|
|
136
|
-
echo "BLOCKED: $REL_PATH matches banned pattern ($PATTERN) in .caws/scope.json"
|
|
137
|
-
echo " Scope allows: files not matching banned patterns"
|
|
138
|
-
echo " To modify scope, update bannedPatterns in .caws/scope.json"
|
|
139
|
-
exit 2
|
|
140
|
-
fi
|
|
141
|
-
|
|
142
|
-
if [[ "$LITE_CHECK" == "not_allowed" ]]; then
|
|
143
|
-
ALLOWED_DIRS=$(node -e "const s=JSON.parse(require('fs').readFileSync('$SCOPE_FILE','utf8')); console.log((s.allowedDirectories||[]).join(', '))" 2>/dev/null || echo "unknown")
|
|
144
|
-
echo "BLOCKED: $REL_PATH is outside allowed directories"
|
|
145
|
-
echo " Scope allows: $ALLOWED_DIRS"
|
|
146
|
-
echo " To modify scope, update allowedDirectories in .caws/scope.json"
|
|
147
|
-
exit 2
|
|
148
|
-
fi
|
|
149
|
-
|
|
150
|
-
# File is allowed - exit normally
|
|
151
|
-
exit 0
|
|
152
|
-
fi
|
|
153
|
-
fi
|
|
154
|
-
|
|
155
|
-
# Use Node.js to parse YAML and check scope across working spec + active feature specs
|
|
156
|
-
SPECS_DIR="$PROJECT_DIR/.caws/specs"
|
|
157
|
-
|
|
158
|
-
if command -v node >/dev/null 2>&1; then
|
|
159
|
-
SCOPE_CHECK=$(node -e "
|
|
160
|
-
const yaml = require('js-yaml');
|
|
161
|
-
const fs = require('fs');
|
|
162
|
-
const path = require('path');
|
|
163
|
-
|
|
164
|
-
// Convert glob pattern to regex, handling **, *, ?, [abc], {a,b}
|
|
165
|
-
function globToRegex(pattern) {
|
|
166
|
-
let i = 0, re = '';
|
|
167
|
-
while (i < pattern.length) {
|
|
168
|
-
const c = pattern[i];
|
|
169
|
-
if (c === '*' && pattern[i+1] === '*') {
|
|
170
|
-
re += '.*'; i += 2;
|
|
171
|
-
if (pattern[i] === '/') i++; // skip trailing slash after **
|
|
172
|
-
} else if (c === '*') {
|
|
173
|
-
re += '[^/]*'; i++;
|
|
174
|
-
} else if (c === '?') {
|
|
175
|
-
re += '[^/]'; i++;
|
|
176
|
-
} else if (c === '[') {
|
|
177
|
-
const end = pattern.indexOf(']', i);
|
|
178
|
-
if (end > i) { re += pattern.slice(i, end + 1); i = end + 1; }
|
|
179
|
-
else { re += '\\\\['; i++; }
|
|
180
|
-
} else if (c === '{') {
|
|
181
|
-
const end = pattern.indexOf('}', i);
|
|
182
|
-
if (end > i) {
|
|
183
|
-
const alts = pattern.slice(i + 1, end).split(',').map(a => a.trim());
|
|
184
|
-
re += '(?:' + alts.join('|') + ')'; i = end + 1;
|
|
185
|
-
} else { re += '\\\\{'; i++; }
|
|
186
|
-
} else if ('.+^$|()'.includes(c)) {
|
|
187
|
-
re += '\\\\' + c; i++;
|
|
188
|
-
} else {
|
|
189
|
-
re += c; i++;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return new RegExp(re);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
const filePath = '$REL_PATH';
|
|
197
|
-
|
|
198
|
-
// Terminal statuses: specs that are done — scope no longer enforced
|
|
199
|
-
const TERMINAL = new Set(['completed', 'closed', 'archived']);
|
|
200
|
-
|
|
201
|
-
// Smart allowlist: root-level files, .caws/, .claude/ always pass
|
|
202
|
-
if (!filePath.includes('/') || filePath.startsWith('.caws/') || filePath.startsWith('.claude/')) {
|
|
203
|
-
console.log('in_scope');
|
|
204
|
-
process.exit(0);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const projectDir = '$PROJECT_DIR';
|
|
208
|
-
|
|
209
|
-
// --- Authoritative spec detection ---
|
|
210
|
-
// If we are inside a worktree with a bound specId, ONLY check that spec.
|
|
211
|
-
// This prevents unrelated specs from blocking writes via broad scope.out.
|
|
212
|
-
let authoritativeSpec = null;
|
|
213
|
-
let mode = 'union';
|
|
214
|
-
|
|
215
|
-
const registryPath = path.join(projectDir, '.caws', 'worktrees.json');
|
|
216
|
-
const cwd = process.cwd();
|
|
217
|
-
const worktreesBase = path.join(projectDir, '.caws', 'worktrees');
|
|
218
|
-
|
|
219
|
-
if (cwd.startsWith(worktreesBase + '/')) {
|
|
220
|
-
const relative = cwd.slice(worktreesBase.length + 1);
|
|
221
|
-
const worktreeName = relative.split('/')[0];
|
|
222
|
-
|
|
223
|
-
if (worktreeName && fs.existsSync(registryPath)) {
|
|
224
|
-
try {
|
|
225
|
-
const reg = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
|
|
226
|
-
const entry = reg.worktrees && reg.worktrees[worktreeName];
|
|
227
|
-
|
|
228
|
-
if (entry && entry.specId) {
|
|
229
|
-
// Try to load the bound spec
|
|
230
|
-
const specsDir = '$SPECS_DIR';
|
|
231
|
-
const specCandidates = [
|
|
232
|
-
path.join(specsDir, entry.specId + '.yaml'),
|
|
233
|
-
path.join(specsDir, entry.specId + '.yml'),
|
|
234
|
-
];
|
|
235
|
-
for (const candidate of specCandidates) {
|
|
236
|
-
if (fs.existsSync(candidate)) {
|
|
237
|
-
try {
|
|
238
|
-
const s = yaml.load(fs.readFileSync(candidate, 'utf8'));
|
|
239
|
-
if (s && !TERMINAL.has(s.status)) {
|
|
240
|
-
// Verify mutual binding: spec must also reference this worktree
|
|
241
|
-
if (s.worktree === worktreeName) {
|
|
242
|
-
authoritativeSpec = { source: path.basename(candidate), spec: s };
|
|
243
|
-
mode = 'authoritative';
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
} catch (_) {}
|
|
247
|
-
break;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
} catch (_) {}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// --- Collect specs based on mode ---
|
|
256
|
-
const specs = [];
|
|
257
|
-
|
|
258
|
-
if (authoritativeSpec) {
|
|
259
|
-
// Authoritative: only the bound spec matters
|
|
260
|
-
specs.push(authoritativeSpec);
|
|
261
|
-
} else {
|
|
262
|
-
// Union: load all active specs
|
|
263
|
-
const mainSpec = '$SPEC_FILE';
|
|
264
|
-
if (fs.existsSync(mainSpec)) {
|
|
265
|
-
try {
|
|
266
|
-
const s = yaml.load(fs.readFileSync(mainSpec, 'utf8'));
|
|
267
|
-
if (s && !TERMINAL.has(s.status)) {
|
|
268
|
-
specs.push({ source: 'working-spec', spec: s });
|
|
269
|
-
}
|
|
270
|
-
} catch (_) {}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const specsDir = '$SPECS_DIR';
|
|
274
|
-
if (fs.existsSync(specsDir)) {
|
|
275
|
-
for (const f of fs.readdirSync(specsDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'))) {
|
|
276
|
-
try {
|
|
277
|
-
const s = yaml.load(fs.readFileSync(path.join(specsDir, f), 'utf8'));
|
|
278
|
-
if (s && !TERMINAL.has(s.status)) {
|
|
279
|
-
specs.push({ source: f, spec: s });
|
|
280
|
-
}
|
|
281
|
-
} catch (_) {}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// No active specs — allow everything
|
|
287
|
-
if (specs.length === 0) {
|
|
288
|
-
console.log('in_scope');
|
|
289
|
-
process.exit(0);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Check scope.out — any match blocks
|
|
293
|
-
for (const { source, spec } of specs) {
|
|
294
|
-
for (const pattern of (spec.scope?.out || [])) {
|
|
295
|
-
const regex = globToRegex(pattern);
|
|
296
|
-
if (regex.test(filePath)) {
|
|
297
|
-
console.log('out_of_scope:' + mode + ':' + source + ':' + pattern);
|
|
298
|
-
process.exit(0);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// scope.in — file must match at least one pattern
|
|
304
|
-
const allInScope = specs.flatMap(({ spec }) => spec.scope?.in || []);
|
|
305
|
-
if (allInScope.length > 0) {
|
|
306
|
-
let found = false;
|
|
307
|
-
for (const pattern of allInScope) {
|
|
308
|
-
const regex = globToRegex(pattern);
|
|
309
|
-
if (regex.test(filePath)) {
|
|
310
|
-
found = true;
|
|
311
|
-
break;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
if (!found) {
|
|
315
|
-
console.log('not_in_scope:' + mode);
|
|
316
|
-
process.exit(0);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
console.log('in_scope');
|
|
321
|
-
} catch (error) {
|
|
322
|
-
console.log('error:' + error.message);
|
|
323
|
-
}
|
|
324
|
-
" 2>&1)
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if [[ "$SCOPE_CHECK" == error:* ]]; then
|
|
328
|
-
ERROR_MSG="${SCOPE_CHECK#error:}"
|
|
329
|
-
echo "BLOCKED: Scope check failed — cannot verify file is in scope" >&2
|
|
330
|
-
echo " Error: $ERROR_MSG" >&2
|
|
331
|
-
echo " Fix the spec file or scope configuration before editing files" >&2
|
|
332
|
-
exit 2
|
|
333
|
-
fi
|
|
334
|
-
|
|
335
|
-
if [[ "$SCOPE_CHECK" == out_of_scope:* ]]; then
|
|
336
|
-
DETAIL="${SCOPE_CHECK#out_of_scope:}"
|
|
337
|
-
# Format: mode:source:pattern
|
|
338
|
-
MODE="${DETAIL%%:*}"
|
|
339
|
-
REST="${DETAIL#*:}"
|
|
340
|
-
SOURCE="${REST%%:*}"
|
|
341
|
-
PATTERN="${REST#*:}"
|
|
342
|
-
echo "BLOCKED: $REL_PATH is excluded by scope.out in $SOURCE (pattern: $PATTERN)"
|
|
343
|
-
if [[ "$MODE" == "union" ]]; then
|
|
344
|
-
echo " Mode: union (no authoritative spec bound to this worktree)"
|
|
345
|
-
echo " The scope guard is checking ALL active specs because the worktree<->spec"
|
|
346
|
-
echo " binding is missing. An unrelated spec may be blocking this edit."
|
|
347
|
-
echo " Fix: caws worktree bind <your-spec-id>"
|
|
348
|
-
echo " Diagnose: caws scope show"
|
|
349
|
-
else
|
|
350
|
-
echo " Mode: authoritative (checking only your bound spec)"
|
|
351
|
-
echo " To modify scope, update the spec's scope.out field"
|
|
352
|
-
fi
|
|
353
|
-
exit 2
|
|
354
|
-
fi
|
|
355
|
-
|
|
356
|
-
if [[ "$SCOPE_CHECK" == not_in_scope:* ]]; then
|
|
357
|
-
MODE="${SCOPE_CHECK#not_in_scope:}"
|
|
358
|
-
echo "BLOCKED: $REL_PATH is not in the defined scope.in of any active spec"
|
|
359
|
-
if [[ "$MODE" == "union" ]]; then
|
|
360
|
-
echo " Mode: union (no authoritative spec bound to this worktree)"
|
|
361
|
-
echo " The scope guard is checking ALL active specs because the worktree<->spec"
|
|
362
|
-
echo " binding is missing. Your file may be in a scope that no spec covers."
|
|
363
|
-
echo " Fix: caws worktree bind <your-spec-id>"
|
|
364
|
-
echo " Diagnose: caws scope show"
|
|
365
|
-
else
|
|
366
|
-
echo " Mode: authoritative (checking only your bound spec)"
|
|
367
|
-
echo " To modify scope, update the spec's scope.in field"
|
|
368
|
-
fi
|
|
369
|
-
exit 2
|
|
370
|
-
fi
|
|
371
|
-
|
|
372
|
-
# Legacy fallback for unqualified not_in_scope (shouldn't happen with updated logic)
|
|
373
|
-
if [[ "$SCOPE_CHECK" == "not_in_scope" ]]; then
|
|
374
|
-
echo "BLOCKED: $REL_PATH is not in the defined scope.in of any active spec"
|
|
375
|
-
echo " Diagnose: caws scope show"
|
|
376
|
-
exit 2
|
|
377
|
-
fi
|
|
378
|
-
fi
|
|
379
|
-
|
|
380
|
-
# File is in scope or scope couldn't be checked - allow
|
|
381
|
-
exit 0
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# CAWS Session Status Hook for Claude Code
|
|
3
|
-
# Reports project state at session start with worktree warnings
|
|
4
|
-
# @author @darianrosebrook
|
|
5
|
-
|
|
6
|
-
set -euo pipefail
|
|
7
|
-
|
|
8
|
-
# Read stdin (required by hook protocol)
|
|
9
|
-
INPUT=$(cat)
|
|
10
|
-
|
|
11
|
-
# Only run for session-start events
|
|
12
|
-
EVENT_TYPE="${1:-}"
|
|
13
|
-
if [ "$EVENT_TYPE" != "session-start" ]; then
|
|
14
|
-
exit 0
|
|
15
|
-
fi
|
|
16
|
-
|
|
17
|
-
# Check if this is a CAWS project
|
|
18
|
-
if [ ! -d "${CLAUDE_PROJECT_DIR:-.}/.caws" ]; then
|
|
19
|
-
exit 0
|
|
20
|
-
fi
|
|
21
|
-
|
|
22
|
-
cd "${CLAUDE_PROJECT_DIR:-.}"
|
|
23
|
-
|
|
24
|
-
# --- Resolve main repo root ---
|
|
25
|
-
CAWS_ROOT="."
|
|
26
|
-
if command -v git >/dev/null 2>&1; then
|
|
27
|
-
_GIT_COMMON=$(git rev-parse --git-common-dir 2>/dev/null || echo ".git")
|
|
28
|
-
if [ "$_GIT_COMMON" != ".git" ]; then
|
|
29
|
-
_CANDIDATE=$(cd "$_GIT_COMMON/.." 2>/dev/null && pwd || echo "")
|
|
30
|
-
if [ -n "$_CANDIDATE" ] && [ -d "$_CANDIDATE/.caws" ]; then
|
|
31
|
-
CAWS_ROOT="$_CANDIDATE"
|
|
32
|
-
fi
|
|
33
|
-
fi
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
# --- Active worktree warning ---
|
|
37
|
-
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
38
|
-
|
|
39
|
-
if [ -f "$CAWS_ROOT/.caws/worktrees.json" ] && command -v node >/dev/null 2>&1; then
|
|
40
|
-
WT_INFO=$(node -e "
|
|
41
|
-
try {
|
|
42
|
-
var reg = JSON.parse(require('fs').readFileSync('$CAWS_ROOT/.caws/worktrees.json', 'utf8'));
|
|
43
|
-
var active = Object.values(reg.worktrees || {}).filter(function(w) { return w.status === 'active' || w.status === 'fresh' || w.status === 'merged'; });
|
|
44
|
-
if (active.length > 0) {
|
|
45
|
-
var names = active.map(function(w) { return w.name + ' (' + w.branch + ')'; });
|
|
46
|
-
console.log(active.length + ':' + names.join(', '));
|
|
47
|
-
} else {
|
|
48
|
-
console.log('0:');
|
|
49
|
-
}
|
|
50
|
-
} catch(e) { console.log('0:'); }
|
|
51
|
-
" 2>/dev/null || echo "0:")
|
|
52
|
-
|
|
53
|
-
WT_COUNT=$(echo "$WT_INFO" | cut -d: -f1)
|
|
54
|
-
WT_NAMES=$(echo "$WT_INFO" | cut -d: -f2)
|
|
55
|
-
|
|
56
|
-
if [ "$WT_COUNT" -gt 0 ] 2>/dev/null; then
|
|
57
|
-
# Check if the agent is already in a worktree (not on the base branch)
|
|
58
|
-
BASE_BRANCH=$(node -e "
|
|
59
|
-
try {
|
|
60
|
-
var reg = JSON.parse(require('fs').readFileSync('$CAWS_ROOT/.caws/worktrees.json', 'utf8'));
|
|
61
|
-
var active = Object.values(reg.worktrees || {}).filter(function(w) { return w.status === 'active' || w.status === 'fresh' || w.status === 'merged'; });
|
|
62
|
-
if (active.length > 0) console.log(active[0].baseBranch || '');
|
|
63
|
-
else console.log('');
|
|
64
|
-
} catch(e) { console.log(''); }
|
|
65
|
-
" 2>/dev/null || echo "")
|
|
66
|
-
|
|
67
|
-
echo ""
|
|
68
|
-
echo "================================================================"
|
|
69
|
-
echo " ACTIVE WORKTREES DETECTED: $WT_COUNT worktree(s)"
|
|
70
|
-
echo " $WT_NAMES"
|
|
71
|
-
echo "================================================================"
|
|
72
|
-
|
|
73
|
-
if [ -n "$BASE_BRANCH" ] && [ "$CURRENT_BRANCH" = "$BASE_BRANCH" ]; then
|
|
74
|
-
echo ""
|
|
75
|
-
echo " You MUST work in a worktree, not on $CURRENT_BRANCH."
|
|
76
|
-
echo ""
|
|
77
|
-
echo " If a worktree was created for your task:"
|
|
78
|
-
echo " cd $CAWS_ROOT/.caws/worktrees/<name>/"
|
|
79
|
-
echo ""
|
|
80
|
-
echo " If you need a new worktree:"
|
|
81
|
-
echo " caws worktree create <name>"
|
|
82
|
-
echo ""
|
|
83
|
-
echo " The only operations allowed on $CURRENT_BRANCH are:"
|
|
84
|
-
echo " - git merge --no-ff <branch> (merge completed worktree work)"
|
|
85
|
-
echo " - Commits with message: merge(worktree): <description>"
|
|
86
|
-
echo " - Commits with message: wip(checkpoint): <description>"
|
|
87
|
-
echo " (for committing prior-session dirty files)"
|
|
88
|
-
echo ""
|
|
89
|
-
echo " Writing or editing files on $CURRENT_BRANCH will be BLOCKED"
|
|
90
|
-
echo " by the PreToolUse hook while worktrees are active."
|
|
91
|
-
else
|
|
92
|
-
echo ""
|
|
93
|
-
echo " You are on branch '$CURRENT_BRANCH' (worktree). Good."
|
|
94
|
-
echo " Other active worktrees: $WT_NAMES"
|
|
95
|
-
fi
|
|
96
|
-
echo "================================================================"
|
|
97
|
-
echo ""
|
|
98
|
-
fi
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
# Use caws session briefing for structured output
|
|
102
|
-
if command -v caws &>/dev/null; then
|
|
103
|
-
caws session briefing 2>/dev/null || {
|
|
104
|
-
echo "--- CAWS Session Briefing (fallback) ---"
|
|
105
|
-
HEAD_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
106
|
-
BRANCH=$(git branch --show-current 2>/dev/null || echo "detached")
|
|
107
|
-
DIRTY_COUNT=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
|
|
108
|
-
echo "Git: ${BRANCH} @ ${HEAD_SHA} (${DIRTY_COUNT} dirty files)"
|
|
109
|
-
if [ "$DIRTY_COUNT" -gt 0 ]; then
|
|
110
|
-
echo "WARNING: Working tree has uncommitted changes from a prior session."
|
|
111
|
-
echo "Classify and commit or stash them before starting new work."
|
|
112
|
-
fi
|
|
113
|
-
echo "--- End CAWS Briefing ---"
|
|
114
|
-
}
|
|
115
|
-
fi
|
|
116
|
-
|
|
117
|
-
exit 0
|