@paths.design/caws-cli 10.2.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -374
- package/dist/index.js +43 -785
- 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/agents.js +0 -124
- 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 -1656
- package/dist/commands/status.js +0 -1172
- 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 -502
- 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 -112
- 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 -470
- 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 -117
- 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 -101
- 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 -196
- package/dist/templates/COMMIT_CONVENTIONS.md +0 -86
- package/dist/templates/OIDC_SETUP.md +0 -300
- package/dist/templates/agents.md +0 -171
- 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-display.js +0 -210
- package/dist/utils/agent-session.js +0 -344
- 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 -924
- package/dist/waivers-manager.js +0 -732
- package/dist/worktree/worktree-manager.js +0 -1735
- package/templates/.caws/schemas/policy.schema.json +0 -117
- 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 -101
- 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 -196
- package/templates/COMMIT_CONVENTIONS.md +0 -86
- package/templates/OIDC_SETUP.md +0 -300
- package/templates/agents.md +0 -171
- 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,220 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# CAWS Worktree Safety Guard for Claude Code
|
|
3
|
-
# Blocks dangerous operations when parallel worktrees are active
|
|
4
|
-
# @author @darianrosebrook
|
|
5
|
-
|
|
6
|
-
set -euo pipefail
|
|
7
|
-
|
|
8
|
-
# Read JSON input from Claude Code
|
|
9
|
-
INPUT=$(cat)
|
|
10
|
-
|
|
11
|
-
# Extract tool info
|
|
12
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
|
|
13
|
-
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
|
|
14
|
-
HOOK_CWD=$(echo "$INPUT" | jq -r '.cwd // ""')
|
|
15
|
-
|
|
16
|
-
# Only check Bash tool
|
|
17
|
-
if [[ "$TOOL_NAME" != "Bash" ]] || [[ -z "$COMMAND" ]]; then
|
|
18
|
-
exit 0
|
|
19
|
-
fi
|
|
20
|
-
|
|
21
|
-
# --- Resolve main repo root ---
|
|
22
|
-
# When running inside a worktree, CLAUDE_PROJECT_DIR points to the
|
|
23
|
-
# worktree directory, but .caws/worktrees.json only exists in the main
|
|
24
|
-
# repo. Use git's common dir to find the true repo root.
|
|
25
|
-
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
26
|
-
|
|
27
|
-
if command -v git >/dev/null 2>&1; then
|
|
28
|
-
GIT_COMMON_DIR=$(cd "$PROJECT_DIR" && git rev-parse --git-common-dir 2>/dev/null || echo "")
|
|
29
|
-
if [[ -n "$GIT_COMMON_DIR" ]] && [[ "$GIT_COMMON_DIR" != ".git" ]]; then
|
|
30
|
-
# Inside a worktree: --git-common-dir returns the main repo's .git path
|
|
31
|
-
# (e.g., /path/to/repo/.git or /path/to/repo/.git/worktrees/<name>/..)
|
|
32
|
-
CANDIDATE=$(cd "$PROJECT_DIR" && cd "$GIT_COMMON_DIR/.." 2>/dev/null && pwd || echo "")
|
|
33
|
-
if [[ -n "$CANDIDATE" ]] && [[ -d "$CANDIDATE/.caws" ]]; then
|
|
34
|
-
PROJECT_DIR="$CANDIDATE"
|
|
35
|
-
fi
|
|
36
|
-
fi
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
# --- Gap 2: Block sparse checkout before the git-only filter ---
|
|
40
|
-
# This must run before the "only check git commands" early-exit
|
|
41
|
-
if echo "$COMMAND" | grep -qE 'caws\s+(worktree\s+create|parallel\s+setup).*--scope'; then
|
|
42
|
-
echo "BLOCKED: --scope (sparse checkout) is not allowed." >&2
|
|
43
|
-
echo "Sparse checkout breaks cross-module imports in most projects." >&2
|
|
44
|
-
echo "Use full worktrees without --scope. Scope enforcement comes from" >&2
|
|
45
|
-
echo "CAWS feature specs and lane discipline, not from hiding files." >&2
|
|
46
|
-
exit 2
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
# --- Gap 5: Block cross-boundary file copies ---
|
|
50
|
-
# Only block copies FROM a worktree back to the main repo (defeats isolation).
|
|
51
|
-
# Copies INTO a worktree are fine — the agent is working there and the files
|
|
52
|
-
# live on the worktree branch, disappearing on merge.
|
|
53
|
-
WORKTREE_BASE="$PROJECT_DIR/.caws/worktrees"
|
|
54
|
-
if [[ -d "$WORKTREE_BASE" ]]; then
|
|
55
|
-
if echo "$COMMAND" | grep -qE '\b(cp|mv)\b'; then
|
|
56
|
-
# If the agent is working inside a worktree, allow all copies — they're
|
|
57
|
-
# in their own workspace
|
|
58
|
-
AGENT_IN_WORKTREE=false
|
|
59
|
-
if [[ -n "$HOOK_CWD" ]] && [[ "$HOOK_CWD" == "$WORKTREE_BASE"/* ]]; then
|
|
60
|
-
AGENT_IN_WORKTREE=true
|
|
61
|
-
fi
|
|
62
|
-
|
|
63
|
-
if [[ "$AGENT_IN_WORKTREE" != "true" ]]; then
|
|
64
|
-
if echo "$COMMAND" | grep -qF ".caws/worktrees/" || echo "$COMMAND" | grep -qF "$WORKTREE_BASE"; then
|
|
65
|
-
# Check if the command references both a worktree path and the main repo
|
|
66
|
-
HAS_WT_PATH=false
|
|
67
|
-
HAS_MAIN_PATH=false
|
|
68
|
-
if echo "$COMMAND" | grep -qE '\.caws/worktrees/|'"$(echo "$WORKTREE_BASE" | sed 's/[\/&]/\\&/g')"''; then
|
|
69
|
-
HAS_WT_PATH=true
|
|
70
|
-
fi
|
|
71
|
-
# Check if destination/source is outside the worktree
|
|
72
|
-
if echo "$COMMAND" | grep -qE "(^|\s)$PROJECT_DIR/[^.]|core/|src/|tests/|packages/" && [[ "$HAS_WT_PATH" == "true" ]]; then
|
|
73
|
-
HAS_MAIN_PATH=true
|
|
74
|
-
fi
|
|
75
|
-
if [[ "$HAS_WT_PATH" == "true" ]] && [[ "$HAS_MAIN_PATH" == "true" ]]; then
|
|
76
|
-
echo "BLOCKED: Copying files from a worktree to the main repo is forbidden." >&2
|
|
77
|
-
echo "This bypasses worktree isolation. Work entirely within your worktree." >&2
|
|
78
|
-
echo "If tests need the main repo's venv, activate it with:" >&2
|
|
79
|
-
echo " source $PROJECT_DIR/.venv/bin/activate" >&2
|
|
80
|
-
exit 2
|
|
81
|
-
fi
|
|
82
|
-
fi
|
|
83
|
-
fi
|
|
84
|
-
fi
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
# Only check git commands from here on
|
|
88
|
-
if ! echo "$COMMAND" | grep -qE '(^|\s|&&|\|)git\s'; then
|
|
89
|
-
exit 0
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
# --- Determine if worktrees are active ---
|
|
93
|
-
WORKTREES_ACTIVE=false
|
|
94
|
-
PARALLEL_BASE=""
|
|
95
|
-
|
|
96
|
-
# Check .caws/parallel.json
|
|
97
|
-
if [[ -f "$PROJECT_DIR/.caws/parallel.json" ]] && command -v node >/dev/null 2>&1; then
|
|
98
|
-
PARALLEL_INFO=$(node -e "
|
|
99
|
-
try {
|
|
100
|
-
var reg = JSON.parse(require('fs').readFileSync('$PROJECT_DIR/.caws/parallel.json', 'utf8'));
|
|
101
|
-
var agents = (reg.agents || []).length;
|
|
102
|
-
console.log(agents + ':' + (reg.baseBranch || ''));
|
|
103
|
-
} catch(e) { console.log('0:'); }
|
|
104
|
-
" 2>/dev/null || echo "0:")
|
|
105
|
-
|
|
106
|
-
AGENT_COUNT=$(echo "$PARALLEL_INFO" | cut -d: -f1)
|
|
107
|
-
PARALLEL_BASE=$(echo "$PARALLEL_INFO" | cut -d: -f2)
|
|
108
|
-
|
|
109
|
-
if [[ "$AGENT_COUNT" -gt 0 ]] 2>/dev/null; then
|
|
110
|
-
WORKTREES_ACTIVE=true
|
|
111
|
-
fi
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
# Check .caws/worktrees.json
|
|
115
|
-
if [[ "$WORKTREES_ACTIVE" != "true" ]] && [[ -f "$PROJECT_DIR/.caws/worktrees.json" ]] && command -v node >/dev/null 2>&1; then
|
|
116
|
-
ACTIVE_COUNT=$(node -e "
|
|
117
|
-
try {
|
|
118
|
-
var reg = JSON.parse(require('fs').readFileSync('$PROJECT_DIR/.caws/worktrees.json', 'utf8'));
|
|
119
|
-
var active = Object.values(reg.worktrees || {}).filter(function(w) { return w.status === 'active' || w.status === 'fresh' || w.status === 'merged'; });
|
|
120
|
-
console.log(active.length);
|
|
121
|
-
} catch(e) { console.log('0'); }
|
|
122
|
-
" 2>/dev/null || echo "0")
|
|
123
|
-
|
|
124
|
-
if [[ "$ACTIVE_COUNT" -gt 0 ]] 2>/dev/null; then
|
|
125
|
-
WORKTREES_ACTIVE=true
|
|
126
|
-
fi
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
# If no worktrees are active, allow everything
|
|
130
|
-
if [[ "$WORKTREES_ACTIVE" != "true" ]]; then
|
|
131
|
-
exit 0
|
|
132
|
-
fi
|
|
133
|
-
|
|
134
|
-
# --- Block dangerous git operations when worktrees are active ---
|
|
135
|
-
|
|
136
|
-
# Block git commit --amend
|
|
137
|
-
if echo "$COMMAND" | grep -qE 'git\s+commit\s+.*--amend'; then
|
|
138
|
-
echo "BLOCKED: git commit --amend is not allowed while worktrees are active." >&2
|
|
139
|
-
echo "Amending commits risks rewriting another agent's work." >&2
|
|
140
|
-
echo "Create a new commit instead." >&2
|
|
141
|
-
exit 2
|
|
142
|
-
fi
|
|
143
|
-
|
|
144
|
-
# Block git stash (shared across worktrees)
|
|
145
|
-
if echo "$COMMAND" | grep -qE 'git\s+stash' && ! echo "$COMMAND" | grep -qE 'git\s+stash\s+list'; then
|
|
146
|
-
echo "BLOCKED: git stash is not allowed while worktrees are active." >&2
|
|
147
|
-
echo "Stash is shared across all worktrees and can capture or destroy another agent's work." >&2
|
|
148
|
-
echo "Commit your changes to your branch instead." >&2
|
|
149
|
-
exit 2
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
# Block git reset --hard
|
|
153
|
-
if echo "$COMMAND" | grep -qE 'git\s+reset\s+--hard'; then
|
|
154
|
-
echo "BLOCKED: git reset --hard is not allowed while worktrees are active." >&2
|
|
155
|
-
echo "This could discard work that other agents depend on." >&2
|
|
156
|
-
exit 2
|
|
157
|
-
fi
|
|
158
|
-
|
|
159
|
-
# Block git push --force
|
|
160
|
-
if echo "$COMMAND" | grep -qE 'git\s+push\s+.*(--force|-f\s)'; then
|
|
161
|
-
echo "BLOCKED: Force push is not allowed while worktrees are active." >&2
|
|
162
|
-
echo "This could rewrite history that other agents have based work on." >&2
|
|
163
|
-
exit 2
|
|
164
|
-
fi
|
|
165
|
-
|
|
166
|
-
# --- Base branch protections ---
|
|
167
|
-
# Use the hook input's cwd (where the git command will actually execute), not
|
|
168
|
-
# CLAUDE_PROJECT_DIR (which always points to the main repo root, even when the
|
|
169
|
-
# agent has cd'd into a worktree at .caws/worktrees/<name>/).
|
|
170
|
-
AGENT_DIR="${HOOK_CWD:-${CLAUDE_PROJECT_DIR:-.}}"
|
|
171
|
-
CURRENT_BRANCH=$(cd "$AGENT_DIR" && git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
172
|
-
|
|
173
|
-
# Determine the base branch to protect
|
|
174
|
-
BASE_BRANCH="$PARALLEL_BASE"
|
|
175
|
-
if [[ -z "$BASE_BRANCH" ]] && [[ -f "$PROJECT_DIR/.caws/worktrees.json" ]] && command -v node >/dev/null 2>&1; then
|
|
176
|
-
BASE_BRANCH=$(node -e "
|
|
177
|
-
try {
|
|
178
|
-
var reg = JSON.parse(require('fs').readFileSync('$PROJECT_DIR/.caws/worktrees.json', 'utf8'));
|
|
179
|
-
var active = Object.values(reg.worktrees || {}).filter(function(w) { return w.status === 'active' || w.status === 'fresh' || w.status === 'merged'; });
|
|
180
|
-
if (active.length > 0) console.log(active[0].baseBranch || '');
|
|
181
|
-
else console.log('');
|
|
182
|
-
} catch(e) { console.log(''); }
|
|
183
|
-
" 2>/dev/null || echo "")
|
|
184
|
-
fi
|
|
185
|
-
|
|
186
|
-
if [[ -n "$BASE_BRANCH" ]] && [[ "$CURRENT_BRANCH" == "$BASE_BRANCH" ]]; then
|
|
187
|
-
# Block push from base branch
|
|
188
|
-
if echo "$COMMAND" | grep -qE 'git\s+push'; then
|
|
189
|
-
echo "BLOCKED: Pushing from the base branch ($BASE_BRANCH) while worktrees are active." >&2
|
|
190
|
-
echo "You should be working in a worktree, not on the base branch." >&2
|
|
191
|
-
echo "Use: cd .caws/worktrees/<name>/" >&2
|
|
192
|
-
exit 2
|
|
193
|
-
fi
|
|
194
|
-
|
|
195
|
-
# Allow git merge into base branch (merging completed worktree branches back)
|
|
196
|
-
# The commit-msg hook enforces the merge(worktree): message format
|
|
197
|
-
if echo "$COMMAND" | grep -qE 'git\s+merge\b'; then
|
|
198
|
-
echo '{
|
|
199
|
-
"hookSpecificOutput": {
|
|
200
|
-
"hookEventName": "PreToolUse",
|
|
201
|
-
"additionalContext": "Merging into base branch ('"$BASE_BRANCH"') while worktrees are active. The commit-msg hook will enforce the merge(worktree): message format. Make sure the worktree for this branch has been destroyed first."
|
|
202
|
-
}
|
|
203
|
-
}'
|
|
204
|
-
exit 0
|
|
205
|
-
fi
|
|
206
|
-
|
|
207
|
-
# Warn (but don't block) commits on base branch — the pre-commit + commit-msg hooks handle blocking
|
|
208
|
-
if echo "$COMMAND" | grep -qE 'git\s+commit\b' && ! echo "$COMMAND" | grep -qE '--amend'; then
|
|
209
|
-
echo '{
|
|
210
|
-
"hookSpecificOutput": {
|
|
211
|
-
"hookEventName": "PreToolUse",
|
|
212
|
-
"additionalContext": "WARNING: You are committing to the base branch ('"$BASE_BRANCH"') while worktrees are active. Only merge commits with the format merge(worktree): <description> are allowed. The pre-commit hook will block direct commits."
|
|
213
|
-
}
|
|
214
|
-
}'
|
|
215
|
-
exit 0
|
|
216
|
-
fi
|
|
217
|
-
fi
|
|
218
|
-
|
|
219
|
-
# Allow the command
|
|
220
|
-
exit 0
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# CAWS Worktree Write Guard for Claude Code
|
|
3
|
-
# Blocks Write/Edit on the base branch while worktrees are active.
|
|
4
|
-
# This prevents agents from modifying files on main and then trying to
|
|
5
|
-
# create worktrees retroactively to commit them.
|
|
6
|
-
# @author @darianrosebrook
|
|
7
|
-
|
|
8
|
-
set -euo pipefail
|
|
9
|
-
|
|
10
|
-
# Read JSON input from Claude Code
|
|
11
|
-
INPUT=$(cat)
|
|
12
|
-
|
|
13
|
-
# Extract tool info
|
|
14
|
-
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
|
|
15
|
-
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
|
|
16
|
-
HOOK_CWD=$(echo "$INPUT" | jq -r '.cwd // ""')
|
|
17
|
-
|
|
18
|
-
# Only check Write and Edit tools
|
|
19
|
-
case "$TOOL_NAME" in
|
|
20
|
-
Write|Edit) ;;
|
|
21
|
-
*) exit 0 ;;
|
|
22
|
-
esac
|
|
23
|
-
|
|
24
|
-
# --- Resolve main repo root ---
|
|
25
|
-
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
26
|
-
|
|
27
|
-
if command -v git >/dev/null 2>&1; then
|
|
28
|
-
GIT_COMMON_DIR=$(cd "$PROJECT_DIR" && git rev-parse --git-common-dir 2>/dev/null || echo "")
|
|
29
|
-
if [[ -n "$GIT_COMMON_DIR" ]] && [[ "$GIT_COMMON_DIR" != ".git" ]]; then
|
|
30
|
-
CANDIDATE=$(cd "$PROJECT_DIR" && cd "$GIT_COMMON_DIR/.." 2>/dev/null && pwd || echo "")
|
|
31
|
-
if [[ -n "$CANDIDATE" ]] && [[ -d "$CANDIDATE/.caws" ]]; then
|
|
32
|
-
PROJECT_DIR="$CANDIDATE"
|
|
33
|
-
fi
|
|
34
|
-
fi
|
|
35
|
-
fi
|
|
36
|
-
|
|
37
|
-
# --- Check for active worktrees ---
|
|
38
|
-
if [[ ! -f "$PROJECT_DIR/.caws/worktrees.json" ]]; then
|
|
39
|
-
exit 0
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
if ! command -v node >/dev/null 2>&1; then
|
|
43
|
-
exit 0
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
# Use the hook input's cwd (where the agent is actually working), not
|
|
47
|
-
# CLAUDE_PROJECT_DIR (which always points to the main repo root, even when the
|
|
48
|
-
# agent has cd'd into a worktree at .caws/worktrees/<name>/).
|
|
49
|
-
AGENT_DIR="${HOOK_CWD:-${CLAUDE_PROJECT_DIR:-.}}"
|
|
50
|
-
CURRENT_BRANCH=$(cd "$AGENT_DIR" && git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
51
|
-
|
|
52
|
-
WT_INFO=$(node -e "
|
|
53
|
-
try {
|
|
54
|
-
var reg = JSON.parse(require('fs').readFileSync('$PROJECT_DIR/.caws/worktrees.json', 'utf8'));
|
|
55
|
-
var active = Object.values(reg.worktrees || {}).filter(function(w) {
|
|
56
|
-
return (w.status === 'active' || w.status === 'fresh' || w.status === 'merged') && w.baseBranch === '$CURRENT_BRANCH';
|
|
57
|
-
});
|
|
58
|
-
console.log(active.length + ':' + active.map(function(w) { return w.name; }).join(', '));
|
|
59
|
-
} catch(e) { console.log('0:'); }
|
|
60
|
-
" 2>/dev/null || echo "0:")
|
|
61
|
-
|
|
62
|
-
WT_COUNT=$(echo "$WT_INFO" | cut -d: -f1)
|
|
63
|
-
WT_NAMES=$(echo "$WT_INFO" | cut -d: -f2)
|
|
64
|
-
|
|
65
|
-
if [[ "$WT_COUNT" -le 0 ]] 2>/dev/null; then
|
|
66
|
-
exit 0
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
# Main is blocked during active worktree work because shared unstaged state makes
|
|
70
|
-
# agents stash, checkpoint, or explain each other's edits. Keep direct main edits
|
|
71
|
-
# limited to coordination/docs/scratch paths, then use active spec scope below to
|
|
72
|
-
# permit only files no worktree claims.
|
|
73
|
-
if [[ -n "$FILE_PATH" ]]; then
|
|
74
|
-
case "$FILE_PATH" in
|
|
75
|
-
.caws/*|*/.caws/*) exit 0 ;;
|
|
76
|
-
.claude/*|*/.claude/*) exit 0 ;;
|
|
77
|
-
.gitignore|*/.gitignore) exit 0 ;;
|
|
78
|
-
.tmp/*|*/.tmp/*) exit 0 ;;
|
|
79
|
-
tmp/*|*/tmp/*) exit 0 ;;
|
|
80
|
-
.archive/*|*/.archive/*) exit 0 ;;
|
|
81
|
-
.githooks/*|*/.githooks/*) exit 0 ;;
|
|
82
|
-
.github/*|*/.github/*) exit 0 ;;
|
|
83
|
-
docs/*|*/docs/*) exit 0 ;;
|
|
84
|
-
esac
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
if [[ -n "$FILE_PATH" ]]; then
|
|
88
|
-
REL_PATH="$FILE_PATH"
|
|
89
|
-
if [[ "$FILE_PATH" == "$PROJECT_DIR"/* ]]; then
|
|
90
|
-
REL_PATH="${FILE_PATH#$PROJECT_DIR/}"
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
SPEC_CONTENTION_CHECK=$(PROJECT_DIR="$PROJECT_DIR" CURRENT_BRANCH="$CURRENT_BRANCH" REL_PATH="$REL_PATH" node -e "
|
|
94
|
-
var fs = require('fs');
|
|
95
|
-
var path = require('path');
|
|
96
|
-
var yaml;
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
yaml = require('js-yaml');
|
|
100
|
-
} catch (_) {
|
|
101
|
-
console.log('unknown:no-js-yaml');
|
|
102
|
-
process.exit(0);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function globToRegExp(pattern) {
|
|
106
|
-
return new RegExp(String(pattern).replace(/\\*/g, '.*').replace(/\\?/g, '.'));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
var projectDir = process.env.PROJECT_DIR;
|
|
111
|
-
var currentBranch = process.env.CURRENT_BRANCH;
|
|
112
|
-
var relPath = process.env.REL_PATH;
|
|
113
|
-
var registryPath = path.join(projectDir, '.caws', 'worktrees.json');
|
|
114
|
-
var registry = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
|
|
115
|
-
var worktrees = Object.values(registry.worktrees || {}).filter(function(w) {
|
|
116
|
-
return (w.status === 'active' || w.status === 'fresh' || w.status === 'merged') && w.baseBranch === currentBranch;
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
if (worktrees.length === 0) {
|
|
120
|
-
console.log('unknown:no-registry-worktrees');
|
|
121
|
-
process.exit(0);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
for (var wi = 0; wi < worktrees.length; wi++) {
|
|
125
|
-
var wt = worktrees[wi];
|
|
126
|
-
if (!wt.specId) {
|
|
127
|
-
console.log('unknown:missing-specId:' + (wt.name || 'unnamed'));
|
|
128
|
-
process.exit(0);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
var specPath = path.join(projectDir, '.caws', 'specs', wt.specId + '.yaml');
|
|
132
|
-
if (!fs.existsSync(specPath)) {
|
|
133
|
-
specPath = path.join(projectDir, '.caws', 'specs', wt.specId + '.yml');
|
|
134
|
-
}
|
|
135
|
-
if (!fs.existsSync(specPath)) {
|
|
136
|
-
console.log('unknown:missing-spec:' + wt.specId);
|
|
137
|
-
process.exit(0);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
var spec = yaml.load(fs.readFileSync(specPath, 'utf8')) || {};
|
|
141
|
-
var scope = spec.scope || {};
|
|
142
|
-
var patterns = []
|
|
143
|
-
.concat(Array.isArray(scope.in) ? scope.in : [])
|
|
144
|
-
.concat(Array.isArray(scope.out) ? scope.out : []);
|
|
145
|
-
|
|
146
|
-
if (patterns.length === 0) {
|
|
147
|
-
console.log('unknown:missing-scope:' + wt.specId);
|
|
148
|
-
process.exit(0);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
for (var pi = 0; pi < patterns.length; pi++) {
|
|
152
|
-
if (globToRegExp(patterns[pi]).test(relPath)) {
|
|
153
|
-
console.log('claimed:' + (wt.name || wt.specId) + ':' + patterns[pi]);
|
|
154
|
-
process.exit(0);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
console.log('clear');
|
|
160
|
-
} catch (error) {
|
|
161
|
-
console.log('unknown:' + error.message);
|
|
162
|
-
}
|
|
163
|
-
" 2>/dev/null || echo "unknown:node-error")
|
|
164
|
-
|
|
165
|
-
if [[ "$SPEC_CONTENTION_CHECK" == "clear" ]]; then
|
|
166
|
-
exit 0
|
|
167
|
-
fi
|
|
168
|
-
fi
|
|
169
|
-
|
|
170
|
-
# Allow edits during an active merge (conflict resolution).
|
|
171
|
-
# The worktree-isolation rules explicitly permit merge commits on the base branch.
|
|
172
|
-
# Conflict resolution requires Write/Edit on the conflicted files.
|
|
173
|
-
MERGE_HEAD_PATH=$(cd "$AGENT_DIR" && git rev-parse --git-dir 2>/dev/null || echo ".git")
|
|
174
|
-
if [[ -f "$MERGE_HEAD_PATH/MERGE_HEAD" ]]; then
|
|
175
|
-
exit 0
|
|
176
|
-
fi
|
|
177
|
-
|
|
178
|
-
# Block: we're on the base branch with active worktrees
|
|
179
|
-
echo "BLOCKED: Cannot write/edit files on '$CURRENT_BRANCH' while $WT_COUNT worktree(s) are active: $WT_NAMES" >&2
|
|
180
|
-
echo "" >&2
|
|
181
|
-
echo "You MUST work in a worktree, not on the base branch." >&2
|
|
182
|
-
echo " To use an existing worktree: cd $PROJECT_DIR/.caws/worktrees/<name>/" >&2
|
|
183
|
-
echo " To create a new worktree: caws worktree create <name>" >&2
|
|
184
|
-
echo "" >&2
|
|
185
|
-
echo "Do NOT make changes on main and create a worktree retroactively." >&2
|
|
186
|
-
echo "The worktree must exist BEFORE you start making changes." >&2
|
|
187
|
-
echo "" >&2
|
|
188
|
-
echo "If you are merging a worktree branch, use: caws worktree merge <name>" >&2
|
|
189
|
-
echo "Or start the merge first (git merge --no-ff <branch>), then resolve conflicts." >&2
|
|
190
|
-
exit 2
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Git safety rules for all agents
|
|
3
|
-
globs:
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Git Safety
|
|
7
|
-
|
|
8
|
-
## Commit discipline
|
|
9
|
-
|
|
10
|
-
- Commit after each logical unit of work (a module + its tests, a bugfix, a refactor pass)
|
|
11
|
-
- Use conventional commits: `feat:`, `fix:`, `refactor:`, `docs:`, `chore:`, `test:`, `perf:`
|
|
12
|
-
- Never accumulate uncommitted changes across multiple unrelated concerns
|
|
13
|
-
- Never leave uncommitted changes at session end; commit as `wip(<scope>): <description>` if incomplete
|
|
14
|
-
|
|
15
|
-
## Forbidden operations
|
|
16
|
-
|
|
17
|
-
- `git push --force` or `git push -f` -- never rewrite remote history
|
|
18
|
-
- `git reset --hard` -- use `git stash` or `git checkout -- <file>` for targeted reverts (but not during parallel work)
|
|
19
|
-
- `git clean -f` -- may delete another agent's untracked files
|
|
20
|
-
- `git checkout .` or `git restore .` -- bulk discard is dangerous
|
|
21
|
-
|
|
22
|
-
## Branch hygiene
|
|
23
|
-
|
|
24
|
-
- Work on feature branches, not directly on main/master
|
|
25
|
-
- One concern per branch
|
|
26
|
-
- Delete branches after merging
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Rules for safe multi-agent git worktree isolation
|
|
3
|
-
globs:
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Multi-Agent Worktree Safety
|
|
7
|
-
|
|
8
|
-
When multiple agents are working on this project, each agent MUST work in its own git worktree. Never have two agents committing to the same branch.
|
|
9
|
-
|
|
10
|
-
## Before starting work
|
|
11
|
-
|
|
12
|
-
1. Check if worktrees exist: `caws worktree list` shows all active worktrees with last commit time and owner
|
|
13
|
-
2. Check who's actually working: `caws agents list` shows registered sessions and their bound worktree/spec, formatted as `<sessionId>:<platform>`
|
|
14
|
-
3. If you're inside a worktree, run `caws status` — the Claim panel shows the current owner, last heartbeat, and any session-log path under `tmp/<sessionId>/`
|
|
15
|
-
4. If worktrees are active and you are on the base branch, switch to your assigned worktree
|
|
16
|
-
5. If no worktree exists for you, create one with `caws worktree create <name>` or `caws parallel setup <plan-file>`
|
|
17
|
-
6. **Never touch a worktree you did not create.** Do not destroy, prune, stash, or "clean up" another agent's worktree — even if it looks stale. Another agent may be actively working in it. If you think a worktree is abandoned, leave it alone and let the user decide.
|
|
18
|
-
|
|
19
|
-
## Foreign-claim soft-block
|
|
20
|
-
|
|
21
|
-
`caws worktree bind`, `merge`, and `claim` refuse to mutate a worktree whose `worktrees.json:owner` is a session id different from the current session — unless `--takeover` is supplied. The refusal prints a structured warning naming the claimer, the heartbeat age, any session-log pointer under `tmp/<sessionId>/`, and the exact `--takeover` command:
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
Worktree 'wt-foo' is claimed by 8be65780-...:claude-code
|
|
25
|
-
Last heartbeat: 2026-04-27T17:04:00Z (23 min ago)
|
|
26
|
-
Session log: tmp/8be65780-72e0-4fc7-a989-4ebac148c18d
|
|
27
|
-
15 turns, last turn 2026-04-27T17:26:49Z
|
|
28
|
-
To proceed: caws worktree claim wt-foo --takeover
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
**Decision-gating uses session-id equality only.** A stale heartbeat is NOT authorization to take over — paused sessions are not ended sessions. Read the session log under `tmp/<sessionId>/` for context first. Take over only when you have explicit user authorization.
|
|
32
|
-
|
|
33
|
-
`--takeover` writes a durable `prior_owners` audit on the worktree entry (sessionId, platform, lastSeen-at-takeover, takenOver_at) so the handoff is traceable in `worktrees.json`, not just in agent memory.
|
|
34
|
-
|
|
35
|
-
## Forbidden operations when worktrees are active
|
|
36
|
-
|
|
37
|
-
- `git commit --amend` -- rewrites history that other agents depend on
|
|
38
|
-
- `git rebase` -- rewrites branch history; the hook blocks this automatically while worktrees are active. If you need code from main, create a new worktree from current main instead
|
|
39
|
-
- `git cherry-pick` -- replays commits across branches; blocked while worktrees are active to prevent cross-boundary contamination
|
|
40
|
-
- `git stash` / `git stash pop` -- stash is shared across all worktrees; using it can destroy another agent's uncommitted work
|
|
41
|
-
- `git reset --hard` -- discards work that other agents may depend on
|
|
42
|
-
- `git push --force` -- rewrites remote history
|
|
43
|
-
- Direct commits to the base branch -- only `merge(worktree):` and `wip(checkpoint):` formats are allowed
|
|
44
|
-
- Copying files between your worktree and the main repo directory -- defeats isolation
|
|
45
|
-
- Destroying another agent's worktree -- even with `--force`. If you did not create it, do not destroy it. Period.
|
|
46
|
-
|
|
47
|
-
## Merging worktree branches back to base
|
|
48
|
-
|
|
49
|
-
Merge commits ARE allowed on the base branch while other worktrees are active. This lets you incrementally merge completed work without waiting for all agents to finish.
|
|
50
|
-
|
|
51
|
-
### Recommended: use `caws worktree merge`
|
|
52
|
-
|
|
53
|
-
The `merge` command handles the full sequence (conflict check, destroy, merge, cleanup):
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
# Preview conflicts before merging
|
|
57
|
-
caws worktree merge <name> --dry-run
|
|
58
|
-
|
|
59
|
-
# Merge (destroys worktree, merges branch, deletes branch)
|
|
60
|
-
caws worktree merge <name>
|
|
61
|
-
|
|
62
|
-
# Merge with custom commit message
|
|
63
|
-
caws worktree merge <name> --message "merge(worktree): description of changes"
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Manual merge (if you need more control)
|
|
67
|
-
|
|
68
|
-
1. Destroy the worktree first: `caws worktree destroy <name>`
|
|
69
|
-
2. Switch to the base branch: `git checkout main`
|
|
70
|
-
3. Merge with: `git merge --no-ff <worktree-branch>`
|
|
71
|
-
4. The commit-msg hook enforces the `merge(worktree): <description>` format for non-FF merges
|
|
72
|
-
5. For manual merge commits: `git commit -m "merge(worktree): integrate scenarios work"`
|
|
73
|
-
|
|
74
|
-
### Conflict resolution during merge
|
|
75
|
-
|
|
76
|
-
The write guard allows edits on the base branch while a merge is in progress (MERGE_HEAD exists). This lets you resolve merge conflicts without needing to abort and retry. After resolving, commit with the `merge(worktree):` format.
|
|
77
|
-
|
|
78
|
-
## What the write guard allows on the base branch
|
|
79
|
-
|
|
80
|
-
Even when worktrees are active, the following edits are allowed on the base branch:
|
|
81
|
-
|
|
82
|
-
- `.claude/` and `.caws/` configuration files
|
|
83
|
-
- `docs/` directory (documentation changes are benign)
|
|
84
|
-
- Any file while a merge is in progress (conflict resolution)
|
|
85
|
-
|
|
86
|
-
## Virtual environment in worktrees
|
|
87
|
-
|
|
88
|
-
Do NOT create a new virtual environment in your worktree. Use the main repo's venv:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
source <main-repo-path>/.venv/bin/activate
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
If your project uses `.caws/scope.json`, the `designatedVenvPath` field specifies the correct venv location.
|
|
95
|
-
|
|
96
|
-
## When your work is done
|
|
97
|
-
|
|
98
|
-
1. Commit all changes to your worktree branch
|
|
99
|
-
2. Run tests in your worktree to verify
|
|
100
|
-
3. Merge: `caws worktree merge <name>` (handles destroy + merge + branch cleanup)
|
|
101
|
-
4. Or manually: destroy worktree, then `git merge --no-ff <branch>`, then delete branch
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"PreToolUse": [
|
|
4
|
-
{
|
|
5
|
-
"matcher": "Bash",
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "command",
|
|
9
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous.sh",
|
|
10
|
-
"timeout": 10
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"type": "command",
|
|
14
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/worktree-guard.sh",
|
|
15
|
-
"timeout": 10
|
|
16
|
-
}
|
|
17
|
-
]
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"matcher": "Read",
|
|
21
|
-
"hooks": [
|
|
22
|
-
{
|
|
23
|
-
"type": "command",
|
|
24
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/scan-secrets.sh",
|
|
25
|
-
"timeout": 10
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"matcher": "Write|Edit",
|
|
31
|
-
"hooks": [
|
|
32
|
-
{
|
|
33
|
-
"type": "command",
|
|
34
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protected-paths.sh",
|
|
35
|
-
"timeout": 5
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"type": "command",
|
|
39
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/worktree-write-guard.sh",
|
|
40
|
-
"timeout": 10
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"type": "command",
|
|
44
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/scope-guard.sh",
|
|
45
|
-
"timeout": 10
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
"PostToolUse": [
|
|
51
|
-
{
|
|
52
|
-
"matcher": "Write|Edit",
|
|
53
|
-
"hooks": [
|
|
54
|
-
{
|
|
55
|
-
"type": "command",
|
|
56
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/quality-check.sh",
|
|
57
|
-
"timeout": 30
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"type": "command",
|
|
61
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate-spec.sh",
|
|
62
|
-
"timeout": 15
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"type": "command",
|
|
66
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/naming-check.sh",
|
|
67
|
-
"timeout": 10
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"type": "command",
|
|
71
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/doc-frontmatter-check.sh",
|
|
72
|
-
"timeout": 10
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"type": "command",
|
|
76
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/audit.sh tool-use",
|
|
77
|
-
"timeout": 5
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"matcher": "Bash",
|
|
83
|
-
"hooks": [
|
|
84
|
-
{
|
|
85
|
-
"type": "command",
|
|
86
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/audit.sh tool-use",
|
|
87
|
-
"timeout": 5
|
|
88
|
-
}
|
|
89
|
-
]
|
|
90
|
-
}
|
|
91
|
-
],
|
|
92
|
-
"SessionStart": [
|
|
93
|
-
{
|
|
94
|
-
"hooks": [
|
|
95
|
-
{
|
|
96
|
-
"type": "command",
|
|
97
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/audit.sh session-start",
|
|
98
|
-
"timeout": 5
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
"type": "command",
|
|
102
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-log.sh",
|
|
103
|
-
"timeout": 5
|
|
104
|
-
}
|
|
105
|
-
]
|
|
106
|
-
}
|
|
107
|
-
],
|
|
108
|
-
"Stop": [
|
|
109
|
-
{
|
|
110
|
-
"hooks": [
|
|
111
|
-
{
|
|
112
|
-
"type": "command",
|
|
113
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/audit.sh stop",
|
|
114
|
-
"timeout": 5
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"type": "command",
|
|
118
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-worktree-check.sh",
|
|
119
|
-
"timeout": 10
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
"type": "command",
|
|
123
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-log.sh",
|
|
124
|
-
"timeout": 5
|
|
125
|
-
}
|
|
126
|
-
]
|
|
127
|
-
}
|
|
128
|
-
],
|
|
129
|
-
"PreCompact": [
|
|
130
|
-
{
|
|
131
|
-
"hooks": [
|
|
132
|
-
{
|
|
133
|
-
"type": "command",
|
|
134
|
-
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-log.sh",
|
|
135
|
-
"timeout": 10
|
|
136
|
-
}
|
|
137
|
-
]
|
|
138
|
-
}
|
|
139
|
-
]
|
|
140
|
-
}
|
|
141
|
-
}
|