@paths.design/caws-cli 9.3.2 → 10.0.1
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 +58 -27
- package/dist/commands/archive.js +67 -28
- package/dist/commands/burnup.js +20 -11
- package/dist/commands/diagnose.js +34 -22
- package/dist/commands/evaluate.js +27 -15
- package/dist/commands/gates.js +122 -0
- package/dist/commands/init.js +143 -15
- package/dist/commands/iterate.js +77 -4
- package/dist/commands/parallel.js +4 -0
- package/dist/commands/plan.js +9 -19
- package/dist/commands/provenance.js +53 -17
- package/dist/commands/quality-monitor.js +64 -45
- package/dist/commands/sidecar.js +71 -0
- package/dist/commands/specs.js +233 -44
- package/dist/commands/status.js +113 -9
- package/dist/commands/tutorial.js +10 -9
- package/dist/commands/validate.js +49 -6
- package/dist/commands/verify-acs.js +35 -78
- package/dist/commands/waivers.js +69 -12
- package/dist/commands/worktree.js +50 -25
- package/dist/error-handler.js +2 -13
- package/dist/gates/budget-limit.js +116 -0
- package/dist/gates/feedback.js +260 -0
- package/dist/gates/format.js +179 -0
- package/dist/gates/god-object.js +117 -0
- package/dist/gates/pipeline.js +167 -0
- package/dist/gates/scope-boundary.js +93 -0
- package/dist/gates/spec-completeness.js +102 -0
- package/dist/gates/todo-detection.js +205 -0
- package/dist/index.js +130 -151
- package/dist/parallel/parallel-manager.js +3 -3
- package/dist/policy/PolicyManager.js +42 -10
- package/dist/scaffold/claude-hooks.js +24 -1
- package/dist/scaffold/git-hooks.js +45 -102
- package/dist/scaffold/index.js +4 -3
- package/dist/session/session-manager.js +71 -14
- package/dist/sidecars/index.js +33 -0
- package/dist/sidecars/listeners.js +40 -0
- package/dist/sidecars/provenance-summary.js +238 -0
- package/dist/sidecars/quality-gaps.js +258 -0
- package/dist/sidecars/schema.js +149 -0
- package/dist/sidecars/spec-drift.js +151 -0
- package/dist/sidecars/waiver-draft.js +176 -0
- package/dist/templates/.caws/schemas/policy.schema.json +50 -0
- package/dist/templates/.caws/schemas/waivers.schema.json +30 -24
- package/dist/templates/.caws/schemas/working-spec.schema.json +51 -8
- package/dist/templates/.caws/schemas/worktrees.schema.json +3 -1
- package/dist/templates/.caws/templates/working-spec.template.yml +7 -3
- package/dist/templates/.claude/hooks/audit.sh +0 -0
- package/dist/templates/.claude/hooks/block-dangerous.sh +52 -11
- package/dist/templates/.claude/hooks/classify_command.py +592 -0
- package/dist/templates/.claude/hooks/doc-frontmatter-check.sh +173 -0
- package/dist/templates/.claude/hooks/quality-check.sh +23 -10
- package/dist/templates/.claude/hooks/scope-guard.sh +34 -32
- package/dist/templates/.claude/hooks/session-caws-status.sh +2 -2
- package/dist/templates/.claude/hooks/session-log.sh +76 -3
- package/dist/templates/.claude/hooks/stop-worktree-check.sh +1 -1
- package/dist/templates/.claude/hooks/test_classify_command.py +370 -0
- package/dist/templates/.claude/hooks/test_wrapper_smoke.sh +96 -0
- package/dist/templates/.claude/hooks/worktree-guard.sh +2 -2
- package/dist/templates/.claude/hooks/worktree-write-guard.sh +1 -1
- package/dist/templates/.claude/settings.json +26 -0
- package/dist/templates/.cursor/hooks/caws-quality-check.sh +4 -4
- package/dist/templates/.cursor/hooks/caws-scope-guard.sh +1 -1
- package/dist/templates/.cursor/hooks/session-log.sh +924 -0
- package/dist/templates/.cursor/hooks.json +25 -0
- package/dist/templates/.cursor/rules/02-quality-gates.mdc +3 -5
- package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +6 -11
- package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +14 -18
- package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +4 -4
- package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +3 -13
- package/dist/templates/.github/copilot-instructions.md +5 -5
- package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +1 -1
- package/dist/templates/.junie/guidelines.md +2 -2
- package/dist/templates/.vscode/settings.json +3 -1
- package/dist/templates/.windsurf/rules/caws-quality-standards.md +2 -2
- package/dist/templates/.windsurf/workflows/caws-guided-development.md +3 -3
- package/dist/templates/CLAUDE.md +43 -8
- package/dist/templates/agents.md +29 -9
- package/dist/templates/docs/README.md +8 -7
- package/dist/templates/scripts/new_feature.sh +80 -0
- package/dist/test-analysis.js +43 -30
- package/dist/tool-loader.js +1 -1
- package/dist/utils/agent-session.js +202 -0
- package/dist/utils/detection.js +8 -2
- package/dist/utils/finalization.js +7 -6
- package/dist/utils/gitignore-updater.js +3 -0
- package/dist/utils/lifecycle-events.js +94 -0
- package/dist/utils/quality-gates-utils.js +29 -44
- package/dist/utils/schema-validator.js +42 -0
- package/dist/utils/spec-resolver.js +93 -21
- package/dist/utils/working-state.js +505 -0
- package/dist/validation/spec-validation.js +92 -22
- package/dist/waivers-manager.js +60 -6
- package/dist/worktree/worktree-manager.js +390 -93
- package/package.json +6 -6
- package/templates/.caws/schemas/policy.schema.json +50 -0
- package/templates/.caws/schemas/waivers.schema.json +30 -24
- package/templates/.caws/schemas/working-spec.schema.json +51 -8
- package/templates/.caws/schemas/worktrees.schema.json +3 -1
- package/templates/.caws/templates/working-spec.template.yml +7 -3
- package/templates/.claude/hooks/block-dangerous.sh +52 -11
- package/templates/.claude/hooks/classify_command.py +592 -0
- package/templates/.claude/hooks/doc-frontmatter-check.sh +173 -0
- package/templates/.claude/hooks/quality-check.sh +23 -10
- package/templates/.claude/hooks/scope-guard.sh +34 -32
- package/templates/.claude/hooks/session-caws-status.sh +2 -2
- package/templates/.claude/hooks/session-log.sh +76 -3
- package/templates/.claude/hooks/stop-worktree-check.sh +1 -1
- package/templates/.claude/hooks/test_classify_command.py +370 -0
- package/templates/.claude/hooks/test_wrapper_smoke.sh +96 -0
- package/templates/.claude/hooks/worktree-guard.sh +2 -2
- package/templates/.claude/hooks/worktree-write-guard.sh +1 -1
- package/templates/.claude/settings.json +26 -0
- package/templates/.cursor/hooks/caws-quality-check.sh +4 -4
- package/templates/.cursor/hooks/caws-scope-guard.sh +1 -1
- package/templates/.cursor/hooks/session-log.sh +924 -0
- package/templates/.cursor/hooks.json +25 -0
- package/templates/.cursor/rules/02-quality-gates.mdc +3 -5
- package/templates/.cursor/rules/10-documentation-quality-standards.mdc +6 -11
- package/templates/.cursor/rules/11-scope-management-waivers.mdc +14 -18
- package/templates/.cursor/rules/12-implementation-completeness.mdc +4 -4
- package/templates/.cursor/rules/13-language-agnostic-standards.mdc +3 -13
- package/templates/.github/copilot-instructions.md +5 -5
- package/templates/.idea/runConfigurations/CAWS_Evaluate.xml +1 -1
- package/templates/.junie/guidelines.md +2 -2
- package/templates/.vscode/settings.json +3 -1
- package/templates/.windsurf/rules/caws-quality-standards.md +2 -2
- package/templates/.windsurf/workflows/caws-guided-development.md +3 -3
- package/templates/CLAUDE.md +43 -8
- package/templates/{AGENTS.md → agents.md} +29 -9
- package/templates/docs/README.md +8 -7
- package/templates/scripts/new_feature.sh +80 -0
- package/dist/budget-derivation.d.ts +0 -74
- package/dist/budget-derivation.d.ts.map +0 -1
- package/dist/cicd-optimizer.d.ts +0 -142
- package/dist/cicd-optimizer.d.ts.map +0 -1
- package/dist/commands/archive.d.ts +0 -51
- package/dist/commands/archive.d.ts.map +0 -1
- package/dist/commands/burnup.d.ts +0 -6
- package/dist/commands/burnup.d.ts.map +0 -1
- package/dist/commands/diagnose.d.ts +0 -52
- package/dist/commands/diagnose.d.ts.map +0 -1
- package/dist/commands/evaluate.d.ts +0 -8
- package/dist/commands/evaluate.d.ts.map +0 -1
- package/dist/commands/init.d.ts +0 -5
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/iterate.d.ts +0 -8
- package/dist/commands/iterate.d.ts.map +0 -1
- package/dist/commands/mode.d.ts +0 -25
- package/dist/commands/mode.d.ts.map +0 -1
- package/dist/commands/parallel.d.ts +0 -7
- package/dist/commands/parallel.d.ts.map +0 -1
- package/dist/commands/plan.d.ts +0 -49
- package/dist/commands/plan.d.ts.map +0 -1
- package/dist/commands/provenance.d.ts +0 -32
- package/dist/commands/provenance.d.ts.map +0 -1
- package/dist/commands/quality-gates.d.ts +0 -6
- package/dist/commands/quality-gates.d.ts.map +0 -1
- package/dist/commands/quality-gates.js +0 -444
- package/dist/commands/quality-monitor.d.ts +0 -17
- package/dist/commands/quality-monitor.d.ts.map +0 -1
- package/dist/commands/session.d.ts +0 -7
- package/dist/commands/session.d.ts.map +0 -1
- package/dist/commands/specs.d.ts +0 -77
- package/dist/commands/specs.d.ts.map +0 -1
- package/dist/commands/status.d.ts +0 -44
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/templates.d.ts +0 -74
- package/dist/commands/templates.d.ts.map +0 -1
- package/dist/commands/tool.d.ts +0 -13
- package/dist/commands/tool.d.ts.map +0 -1
- package/dist/commands/troubleshoot.d.ts +0 -8
- package/dist/commands/troubleshoot.d.ts.map +0 -1
- package/dist/commands/troubleshoot.js +0 -104
- package/dist/commands/tutorial.d.ts +0 -55
- package/dist/commands/tutorial.d.ts.map +0 -1
- package/dist/commands/validate.d.ts +0 -15
- package/dist/commands/validate.d.ts.map +0 -1
- package/dist/commands/waivers.d.ts +0 -8
- package/dist/commands/waivers.d.ts.map +0 -1
- package/dist/commands/workflow.d.ts +0 -85
- package/dist/commands/workflow.d.ts.map +0 -1
- package/dist/commands/worktree.d.ts +0 -7
- package/dist/commands/worktree.d.ts.map +0 -1
- package/dist/config/index.d.ts +0 -29
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/lite-scope.d.ts +0 -33
- package/dist/config/lite-scope.d.ts.map +0 -1
- package/dist/config/modes.d.ts +0 -264
- package/dist/config/modes.d.ts.map +0 -1
- package/dist/constants/spec-types.d.ts +0 -93
- package/dist/constants/spec-types.d.ts.map +0 -1
- package/dist/error-handler.d.ts +0 -151
- package/dist/error-handler.d.ts.map +0 -1
- package/dist/generators/jest-config-generator.d.ts +0 -32
- package/dist/generators/jest-config-generator.d.ts.map +0 -1
- package/dist/generators/jest-config.d.ts +0 -32
- package/dist/generators/jest-config.d.ts.map +0 -1
- package/dist/generators/jest-config.js +0 -242
- package/dist/generators/working-spec.d.ts +0 -13
- package/dist/generators/working-spec.d.ts.map +0 -1
- package/dist/index-new.d.ts +0 -5
- package/dist/index-new.d.ts.map +0 -1
- package/dist/index-new.js +0 -317
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.backup +0 -4711
- package/dist/minimal-cli.d.ts +0 -3
- package/dist/minimal-cli.d.ts.map +0 -1
- package/dist/parallel/parallel-manager.d.ts +0 -67
- package/dist/parallel/parallel-manager.d.ts.map +0 -1
- package/dist/policy/PolicyManager.d.ts +0 -104
- package/dist/policy/PolicyManager.d.ts.map +0 -1
- package/dist/scaffold/claude-hooks.d.ts +0 -28
- package/dist/scaffold/claude-hooks.d.ts.map +0 -1
- package/dist/scaffold/cursor-hooks.d.ts +0 -7
- package/dist/scaffold/cursor-hooks.d.ts.map +0 -1
- package/dist/scaffold/git-hooks.d.ts +0 -38
- package/dist/scaffold/git-hooks.d.ts.map +0 -1
- package/dist/scaffold/index.d.ts +0 -17
- package/dist/scaffold/index.d.ts.map +0 -1
- package/dist/session/session-manager.d.ts +0 -94
- package/dist/session/session-manager.d.ts.map +0 -1
- package/dist/spec/SpecFileManager.d.ts +0 -146
- package/dist/spec/SpecFileManager.d.ts.map +0 -1
- package/dist/templates/.cursor/hooks/caws-tool-validation.sh +0 -121
- package/dist/templates/.github/copilot/instructions.md +0 -311
- package/dist/test-analysis.d.ts +0 -231
- package/dist/test-analysis.d.ts.map +0 -1
- package/dist/tool-interface.d.ts +0 -236
- package/dist/tool-interface.d.ts.map +0 -1
- package/dist/tool-loader.d.ts +0 -77
- package/dist/tool-loader.d.ts.map +0 -1
- package/dist/tool-validator.d.ts +0 -72
- package/dist/tool-validator.d.ts.map +0 -1
- package/dist/utils/async-utils.d.ts +0 -73
- package/dist/utils/async-utils.d.ts.map +0 -1
- package/dist/utils/command-wrapper.d.ts +0 -66
- package/dist/utils/command-wrapper.d.ts.map +0 -1
- package/dist/utils/detection.d.ts +0 -14
- package/dist/utils/detection.d.ts.map +0 -1
- package/dist/utils/error-categories.d.ts +0 -52
- package/dist/utils/error-categories.d.ts.map +0 -1
- package/dist/utils/finalization.d.ts +0 -17
- package/dist/utils/finalization.d.ts.map +0 -1
- package/dist/utils/git-lock.d.ts +0 -13
- package/dist/utils/git-lock.d.ts.map +0 -1
- package/dist/utils/gitignore-updater.d.ts +0 -39
- package/dist/utils/gitignore-updater.d.ts.map +0 -1
- package/dist/utils/ide-detection.d.ts +0 -89
- package/dist/utils/ide-detection.d.ts.map +0 -1
- package/dist/utils/project-analysis.d.ts +0 -34
- package/dist/utils/project-analysis.d.ts.map +0 -1
- package/dist/utils/promise-utils.d.ts +0 -30
- package/dist/utils/promise-utils.d.ts.map +0 -1
- package/dist/utils/quality-gates-utils.d.ts +0 -49
- package/dist/utils/quality-gates-utils.d.ts.map +0 -1
- package/dist/utils/quality-gates.d.ts +0 -49
- package/dist/utils/quality-gates.d.ts.map +0 -1
- package/dist/utils/quality-gates.js +0 -402
- package/dist/utils/spec-resolver.d.ts +0 -80
- package/dist/utils/spec-resolver.d.ts.map +0 -1
- package/dist/utils/typescript-detector.d.ts +0 -66
- package/dist/utils/typescript-detector.d.ts.map +0 -1
- package/dist/utils/yaml-validation.d.ts +0 -32
- package/dist/utils/yaml-validation.d.ts.map +0 -1
- package/dist/validation/spec-validation.d.ts +0 -43
- package/dist/validation/spec-validation.d.ts.map +0 -1
- package/dist/waivers-manager.d.ts +0 -167
- package/dist/waivers-manager.d.ts.map +0 -1
- package/dist/worktree/worktree-manager.d.ts +0 -54
- package/dist/worktree/worktree-manager.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paths.design/caws-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.1",
|
|
4
4
|
"description": "CAWS CLI - Coding Agent Workflow System command-line tools for spec management, quality gates, and AI-assisted development",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dev": "mkdir -p dist && cp -r src/* dist/ && node dist/index.js",
|
|
18
18
|
"typecheck": "tsc --emitDeclarationOnly --outDir dist",
|
|
19
19
|
"start": "node dist/index.js",
|
|
20
|
-
"test": "
|
|
20
|
+
"test": "node scripts/run-tests.js",
|
|
21
21
|
"test:unit": "npm run build && jest --testPathIgnorePatterns='perf-budgets|integration|e2e|mutation|axe|contract' && npm run test:cleanup",
|
|
22
22
|
"test:contract": "npm run build && jest --testPathPatterns=contract && npm run test:cleanup",
|
|
23
23
|
"test:integration": "npm run build && jest --testPathPatterns=integration && npm run test:cleanup",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"validate": "echo 'CLI package validation not required'",
|
|
35
35
|
"caws:validate": "node ../../.caws/validate.js ../../.caws/working-spec.yaml",
|
|
36
36
|
"clean": "rm -rf dist test-caws-project .agent && npm run test:cleanup",
|
|
37
|
-
"prepare": "husky"
|
|
37
|
+
"prepare": "husky >/dev/null 2>&1 || true"
|
|
38
38
|
},
|
|
39
39
|
"keywords": [
|
|
40
40
|
"caws",
|
|
@@ -59,7 +59,9 @@
|
|
|
59
59
|
"chalk": "4.1.2",
|
|
60
60
|
"commander": "^11.0.0",
|
|
61
61
|
"fs-extra": "^11.0.0",
|
|
62
|
-
"inquirer": "8.2.7"
|
|
62
|
+
"inquirer": "8.2.7",
|
|
63
|
+
"ajv": "8.17.1",
|
|
64
|
+
"js-yaml": "4.1.0"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
67
|
"@eslint/js": "^9.0.0",
|
|
@@ -71,12 +73,10 @@
|
|
|
71
73
|
"@types/inquirer": "^8.2.6",
|
|
72
74
|
"@types/js-yaml": "^4.0.0",
|
|
73
75
|
"@types/node": "^20.0.0",
|
|
74
|
-
"ajv": "8.17.1",
|
|
75
76
|
"esbuild": "0.25.10",
|
|
76
77
|
"eslint": "^9.0.0",
|
|
77
78
|
"husky": "9.1.7",
|
|
78
79
|
"jest": "30.1.3",
|
|
79
|
-
"js-yaml": "4.1.0",
|
|
80
80
|
"lint-staged": "15.5.2",
|
|
81
81
|
"micromatch": "4.0.8",
|
|
82
82
|
"prettier": "^3.0.0",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "CAWS Policy",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": ["version", "risk_tiers"],
|
|
6
|
+
"properties": {
|
|
7
|
+
"version": { "type": "integer", "const": 1 },
|
|
8
|
+
"risk_tiers": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"1": { "$ref": "#/$defs/tier" },
|
|
12
|
+
"2": { "$ref": "#/$defs/tier" },
|
|
13
|
+
"3": { "$ref": "#/$defs/tier" }
|
|
14
|
+
},
|
|
15
|
+
"required": ["1", "2", "3"]
|
|
16
|
+
},
|
|
17
|
+
"edit_rules": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"properties": {
|
|
20
|
+
"policy_and_code_same_pr": { "type": "boolean" },
|
|
21
|
+
"min_approvers_for_budget_raise": { "type": "integer", "minimum": 1 },
|
|
22
|
+
"require_signed_commits": { "type": "boolean" }
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"gates": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"properties": {
|
|
30
|
+
"enabled": { "type": "boolean" },
|
|
31
|
+
"description": { "type": "string" },
|
|
32
|
+
"mode": { "type": "string", "enum": ["block", "warn", "skip"] },
|
|
33
|
+
"thresholds": { "type": "object" }
|
|
34
|
+
},
|
|
35
|
+
"required": ["enabled"]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"$defs": {
|
|
40
|
+
"tier": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"required": ["max_files", "max_loc"],
|
|
43
|
+
"properties": {
|
|
44
|
+
"max_files": { "type": "integer", "minimum": 1 },
|
|
45
|
+
"max_loc": { "type": "integer", "minimum": 1 },
|
|
46
|
+
"description": { "type": "string" }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,30 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"title": "CAWS
|
|
3
|
+
"title": "CAWS Waiver",
|
|
4
|
+
"description": "Individual waiver file created by caws waivers create",
|
|
4
5
|
"type": "object",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
6
|
+
"required": ["id", "title", "reason", "gates", "created_at", "expires_at", "approved_by", "status"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"id": { "type": "string", "pattern": "^WV-\\d{4}$" },
|
|
9
|
+
"title": { "type": "string", "minLength": 1 },
|
|
10
|
+
"reason": { "type": "string", "minLength": 10 },
|
|
11
|
+
"description": { "type": "string" },
|
|
12
|
+
"gates": {
|
|
13
|
+
"type": "array",
|
|
14
|
+
"items": { "type": "string" },
|
|
15
|
+
"minItems": 1,
|
|
16
|
+
"description": "Gate names this waiver applies to"
|
|
17
|
+
},
|
|
18
|
+
"created_at": { "type": "string" },
|
|
19
|
+
"expires_at": { "type": "string" },
|
|
20
|
+
"approved_by": { "type": "string" },
|
|
21
|
+
"impact_level": { "type": "string" },
|
|
22
|
+
"mitigation_plan": { "type": "string" },
|
|
23
|
+
"status": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"enum": ["active", "expired", "revoked"],
|
|
26
|
+
"default": "active"
|
|
27
|
+
},
|
|
28
|
+
"created_by_session": { "type": ["string", "null"] },
|
|
29
|
+
"compensating_control": { "type": "string" },
|
|
30
|
+
"ticket_url": { "type": "string", "format": "uri" },
|
|
31
|
+
"revoked_at": { "type": "string" },
|
|
32
|
+
"revoked_by": { "type": "string" },
|
|
33
|
+
"revocation_reason": { "type": "string" }
|
|
28
34
|
},
|
|
29
35
|
"additionalProperties": false
|
|
30
36
|
}
|
|
@@ -18,8 +18,15 @@
|
|
|
18
18
|
"properties": {
|
|
19
19
|
"id": { "type": "string", "pattern": "^[A-Z]{2,6}-\\d{3,4}$" },
|
|
20
20
|
"title": { "type": "string", "minLength": 10, "maxLength": 200 },
|
|
21
|
+
"type": { "type": "string", "enum": ["feature", "fix", "refactor", "chore", "docs"] },
|
|
22
|
+
"status": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"enum": ["draft", "active", "in_progress", "completed", "closed", "archived"]
|
|
25
|
+
},
|
|
26
|
+
"created_at": { "type": "string" },
|
|
27
|
+
"updated_at": { "type": "string" },
|
|
21
28
|
"risk_tier": { "type": ["integer", "string"], "enum": [1, 2, 3, "1", "2", "3"] },
|
|
22
|
-
"mode": { "type": "string", "enum": ["feature", "refactor", "fix", "doc", "chore"] },
|
|
29
|
+
"mode": { "type": "string", "enum": ["feature", "refactor", "fix", "doc", "docs", "chore", "development"] },
|
|
23
30
|
"waiver_ids": {
|
|
24
31
|
"type": "array",
|
|
25
32
|
"items": { "type": "string", "pattern": "^WV-\\d{4}$" },
|
|
@@ -45,7 +52,7 @@
|
|
|
45
52
|
"invariants": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
|
|
46
53
|
"acceptance": {
|
|
47
54
|
"type": "array",
|
|
48
|
-
"minItems":
|
|
55
|
+
"minItems": 0,
|
|
49
56
|
"items": {
|
|
50
57
|
"type": "object",
|
|
51
58
|
"required": ["id", "given", "when", "then"],
|
|
@@ -57,6 +64,35 @@
|
|
|
57
64
|
}
|
|
58
65
|
}
|
|
59
66
|
},
|
|
67
|
+
"acceptance_criteria": {
|
|
68
|
+
"type": "array",
|
|
69
|
+
"minItems": 0,
|
|
70
|
+
"items": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"required": ["id"],
|
|
73
|
+
"properties": {
|
|
74
|
+
"id": { "type": "string" },
|
|
75
|
+
"description": { "type": "string" },
|
|
76
|
+
"completed": { "type": "boolean" },
|
|
77
|
+
"test": { "type": "string" },
|
|
78
|
+
"test_command": { "type": "string" },
|
|
79
|
+
"test_nodeids": {
|
|
80
|
+
"type": "array",
|
|
81
|
+
"items": { "type": "string" }
|
|
82
|
+
},
|
|
83
|
+
"evidence": {
|
|
84
|
+
"oneOf": [
|
|
85
|
+
{ "type": "string" },
|
|
86
|
+
{
|
|
87
|
+
"type": "array",
|
|
88
|
+
"items": { "type": "string" }
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"additionalProperties": true
|
|
94
|
+
}
|
|
95
|
+
},
|
|
60
96
|
"non_functional": {
|
|
61
97
|
"type": "object",
|
|
62
98
|
"properties": {
|
|
@@ -75,13 +111,14 @@
|
|
|
75
111
|
},
|
|
76
112
|
"contracts": {
|
|
77
113
|
"type": "array",
|
|
78
|
-
"minItems": 1,
|
|
79
114
|
"items": {
|
|
80
115
|
"type": "object",
|
|
81
116
|
"required": ["type", "path"],
|
|
82
117
|
"properties": {
|
|
83
|
-
"type": { "type": "string", "enum": ["openapi", "graphql", "proto", "pact"] },
|
|
84
|
-
"path": { "type": "string" }
|
|
118
|
+
"type": { "type": "string", "enum": ["openapi", "graphql", "proto", "pact", "project_setup"] },
|
|
119
|
+
"path": { "type": "string" },
|
|
120
|
+
"description": { "type": "string" },
|
|
121
|
+
"version": { "type": "string" }
|
|
85
122
|
}
|
|
86
123
|
}
|
|
87
124
|
},
|
|
@@ -95,9 +132,15 @@
|
|
|
95
132
|
},
|
|
96
133
|
"migrations": { "type": "array", "items": { "type": "string" } },
|
|
97
134
|
"rollback": { "type": "array", "items": { "type": "string" } },
|
|
98
|
-
"
|
|
99
|
-
"type": "
|
|
100
|
-
"description": "Enables experimental mode with reduced requirements"
|
|
135
|
+
"experimental_mode": {
|
|
136
|
+
"type": "object",
|
|
137
|
+
"description": "Enables experimental mode with reduced requirements",
|
|
138
|
+
"required": ["enabled", "rationale", "expires_at"],
|
|
139
|
+
"properties": {
|
|
140
|
+
"enabled": { "type": "boolean" },
|
|
141
|
+
"rationale": { "type": "string" },
|
|
142
|
+
"expires_at": { "type": "string" }
|
|
143
|
+
}
|
|
101
144
|
},
|
|
102
145
|
"timeboxed_hours": {
|
|
103
146
|
"type": "integer",
|
|
@@ -21,11 +21,13 @@
|
|
|
21
21
|
"baseBranch": { "type": "string" },
|
|
22
22
|
"scope": { "type": ["string", "null"] },
|
|
23
23
|
"specId": { "type": ["string", "null"] },
|
|
24
|
+
"owner": { "type": ["string", "null"], "description": "CLAUDE_SESSION_ID of the creating agent" },
|
|
24
25
|
"createdAt": { "type": "string", "format": "date-time" },
|
|
25
26
|
"destroyedAt": { "type": "string", "format": "date-time" },
|
|
27
|
+
"autoRegistered": { "type": "boolean" },
|
|
26
28
|
"status": {
|
|
27
29
|
"type": "string",
|
|
28
|
-
"enum": ["active", "orphaned", "missing", "destroyed"]
|
|
30
|
+
"enum": ["fresh", "active", "merged", "orphaned", "missing", "stale-merged", "destroyed"]
|
|
29
31
|
}
|
|
30
32
|
},
|
|
31
33
|
"additionalProperties": false
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
id: '{{FEATURE_ID}}'
|
|
2
2
|
title: '{{FEATURE_TITLE}}'
|
|
3
|
-
risk_tier: {
|
|
3
|
+
risk_tier: {{TIER}}
|
|
4
|
+
mode: feature
|
|
5
|
+
blast_radius:
|
|
6
|
+
modules: []
|
|
7
|
+
operational_rollback_slo: "30m"
|
|
4
8
|
scope:
|
|
5
9
|
in:
|
|
6
10
|
- '{{SCOPE_ITEM_1}}'
|
|
@@ -37,8 +41,8 @@ non_functional:
|
|
|
37
41
|
a11y:
|
|
38
42
|
- '{{ACCESSIBILITY_REQUIREMENT}}'
|
|
39
43
|
perf:
|
|
40
|
-
api_p95_ms: {
|
|
41
|
-
lcp_ms: {
|
|
44
|
+
api_p95_ms: {{PERF_BUDGET}}
|
|
45
|
+
lcp_ms: {{LCP_BUDGET}}
|
|
42
46
|
security:
|
|
43
47
|
- '{{SECURITY_REQUIREMENT}}'
|
|
44
48
|
contracts:
|
|
@@ -1,23 +1,70 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# CAWS
|
|
3
|
-
#
|
|
2
|
+
# CAWS Command Safety Gate for Claude Code
|
|
3
|
+
# Delegates to classify_command.py for robust command parsing and classification.
|
|
4
|
+
# Falls back to bash pattern matching if Python is unavailable.
|
|
5
|
+
#
|
|
6
|
+
# The Python classifier handles:
|
|
7
|
+
# - Heredoc-aware parsing (won't false-positive on quoted dangerous commands)
|
|
8
|
+
# - Quoted-region stripping (echo "git reset --hard" is safe)
|
|
9
|
+
# - Pipeline-aware dangers (curl | sh)
|
|
10
|
+
# - Context-aware rm classification (safe prefixes vs dangerous targets)
|
|
11
|
+
# - Proper shell segmentation (&&, ||, ;, |)
|
|
12
|
+
#
|
|
4
13
|
# @author @darianrosebrook
|
|
5
14
|
|
|
6
15
|
set -euo pipefail
|
|
7
16
|
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
|
+
|
|
8
19
|
# Read JSON input from Claude Code
|
|
9
20
|
INPUT=$(cat)
|
|
10
21
|
|
|
11
22
|
# Extract tool info
|
|
12
|
-
TOOL_NAME=$(
|
|
13
|
-
COMMAND=$(
|
|
23
|
+
TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // ""')
|
|
24
|
+
COMMAND=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // ""')
|
|
14
25
|
|
|
15
26
|
# Only check Bash tool
|
|
16
27
|
if [[ "$TOOL_NAME" != "Bash" ]] || [[ -z "$COMMAND" ]]; then
|
|
17
28
|
exit 0
|
|
18
29
|
fi
|
|
19
30
|
|
|
20
|
-
#
|
|
31
|
+
# --- Try Python classifier first (preferred) ---
|
|
32
|
+
CLASSIFIER="$SCRIPT_DIR/classify_command.py"
|
|
33
|
+
if [[ -f "$CLASSIFIER" ]] && command -v python3 >/dev/null 2>&1; then
|
|
34
|
+
REPO_ROOT="${CLAUDE_PROJECT_DIR:-.}"
|
|
35
|
+
CLASSIFIER_STDERR=$(mktemp)
|
|
36
|
+
RESULT=$(printf '%s' "$COMMAND" | python3 "$CLASSIFIER" \
|
|
37
|
+
--repo-root "$REPO_ROOT" \
|
|
38
|
+
--home "$HOME" \
|
|
39
|
+
--cwd "$(pwd)" 2>"$CLASSIFIER_STDERR") || {
|
|
40
|
+
DIAG=$(head -c 200 "$CLASSIFIER_STDERR" 2>/dev/null || true)
|
|
41
|
+
rm -f "$CLASSIFIER_STDERR"
|
|
42
|
+
RESULT="{\"decision\":\"ask\",\"reason\":\"command classifier failed: ${DIAG:-unknown error}\"}"
|
|
43
|
+
}
|
|
44
|
+
rm -f "$CLASSIFIER_STDERR"
|
|
45
|
+
|
|
46
|
+
DECISION=$(printf '%s' "$RESULT" | jq -r '.decision // "ask"')
|
|
47
|
+
REASON=$(printf '%s' "$RESULT" | jq -r '.reason // "unknown"')
|
|
48
|
+
|
|
49
|
+
case "$DECISION" in
|
|
50
|
+
allow)
|
|
51
|
+
exit 0
|
|
52
|
+
;;
|
|
53
|
+
deny)
|
|
54
|
+
echo "BLOCKED: $REASON" >&2
|
|
55
|
+
echo "Command was: $COMMAND" >&2
|
|
56
|
+
exit 2
|
|
57
|
+
;;
|
|
58
|
+
ask)
|
|
59
|
+
echo "WARNING: $REASON" >&2
|
|
60
|
+
echo "Command was: $COMMAND" >&2
|
|
61
|
+
exit 1
|
|
62
|
+
;;
|
|
63
|
+
esac
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# --- Fallback: bash pattern matching (less precise, no heredoc/quote awareness) ---
|
|
67
|
+
|
|
21
68
|
DANGEROUS_PATTERNS=(
|
|
22
69
|
# Destructive file operations
|
|
23
70
|
'rm -rf /'
|
|
@@ -96,7 +143,6 @@ for pattern in "${DANGEROUS_PATTERNS[@]}"; do
|
|
|
96
143
|
# Allow git rebase/cherry-pick only when no worktrees are active
|
|
97
144
|
if [[ "$pattern" == *"git rebase"* ]] || [[ "$pattern" == *"git cherry-pick"* ]]; then
|
|
98
145
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
99
|
-
# Resolve to main repo root if we're in a worktree
|
|
100
146
|
if command -v git >/dev/null 2>&1; then
|
|
101
147
|
GIT_COMMON=$(cd "$PROJECT_DIR" && git rev-parse --git-common-dir 2>/dev/null || echo "")
|
|
102
148
|
if [[ -n "$GIT_COMMON" ]] && [[ "$GIT_COMMON" != ".git" ]]; then
|
|
@@ -116,7 +162,6 @@ for pattern in "${DANGEROUS_PATTERNS[@]}"; do
|
|
|
116
162
|
} catch(e) { console.log(0); }
|
|
117
163
|
" 2>/dev/null || echo "0")
|
|
118
164
|
if [[ "$ACTIVE_COUNT" -gt 0 ]]; then
|
|
119
|
-
# Extract the specific git subcommand for the message
|
|
120
165
|
GIT_SUBCMD="git operation"
|
|
121
166
|
[[ "$pattern" == *"git rebase"* ]] && GIT_SUBCMD="git rebase"
|
|
122
167
|
[[ "$pattern" == *"git cherry-pick"* ]] && GIT_SUBCMD="git cherry-pick"
|
|
@@ -126,7 +171,6 @@ for pattern in "${DANGEROUS_PATTERNS[@]}"; do
|
|
|
126
171
|
exit 2
|
|
127
172
|
fi
|
|
128
173
|
fi
|
|
129
|
-
# No active worktrees — allow
|
|
130
174
|
continue
|
|
131
175
|
fi
|
|
132
176
|
|
|
@@ -142,11 +186,8 @@ for pattern in "${DANGEROUS_PATTERNS[@]}"; do
|
|
|
142
186
|
fi
|
|
143
187
|
fi
|
|
144
188
|
|
|
145
|
-
# Output to stderr for Claude to see
|
|
146
189
|
echo "BLOCKED: Command matches dangerous pattern: $pattern" >&2
|
|
147
190
|
echo "Command was: $COMMAND" >&2
|
|
148
|
-
|
|
149
|
-
# Exit code 2 blocks the tool and shows stderr to Claude
|
|
150
191
|
exit 2
|
|
151
192
|
fi
|
|
152
193
|
done
|