@paths.design/caws-cli 4.0.0 → 5.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/dist/commands/archive.js +353 -0
- package/dist/commands/iterate.js +12 -13
- package/dist/commands/mode.js +259 -0
- package/dist/commands/plan.js +448 -0
- package/dist/commands/quality-gates.js +490 -0
- package/dist/commands/specs.js +735 -0
- package/dist/commands/status.js +552 -22
- package/dist/commands/tutorial.js +481 -0
- package/dist/commands/validate.js +137 -54
- package/dist/commands/waivers.js +101 -26
- package/dist/config/modes.js +321 -0
- package/dist/constants/spec-types.js +42 -0
- package/dist/index.js +225 -10
- package/dist/scaffold/git-hooks.js +32 -44
- package/dist/scaffold/index.js +19 -0
- package/dist/utils/quality-gates-errors.js +520 -0
- package/dist/utils/quality-gates.js +361 -0
- package/dist/utils/spec-resolver.js +602 -0
- package/dist/waivers-manager.js +49 -4
- package/package.json +6 -5
- package/templates/.cursor/hooks/caws-scope-guard.sh +64 -8
- package/templates/.cursor/hooks/validate-spec.sh +22 -12
- package/templates/.cursor/rules/{01-claims-verification.mdc → 00-claims-verification.mdc} +1 -1
- package/templates/.cursor/rules/01-working-style.mdc +50 -0
- package/templates/.cursor/rules/{02-testing-standards.mdc → 02-quality-gates.mdc} +84 -29
- package/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
- package/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
- package/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
- package/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
- package/templates/.cursor/rules/07-process-ops.mdc +20 -0
- package/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
- package/templates/.cursor/rules/09-docstrings.mdc +89 -0
- package/templates/.cursor/rules/10-authorship-and-attribution.mdc +15 -0
- package/templates/.cursor/rules/11-documentation-quality-standards.mdc +390 -0
- package/templates/.cursor/rules/12-scope-management-waivers.mdc +385 -0
- package/templates/.cursor/rules/13-implementation-completeness.mdc +516 -0
- package/templates/.cursor/rules/14-language-agnostic-standards.mdc +588 -0
- package/templates/.cursor/rules/15-sophisticated-todo-detection.mdc +425 -0
- package/templates/.cursor/rules/README.md +93 -7
- package/templates/scripts/quality-gates/check-god-objects.js +146 -0
- package/templates/scripts/quality-gates/run-quality-gates.js +50 -0
- package/templates/scripts/v3/analysis/todo_analyzer.py +1950 -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/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/provenance.d.ts +0 -32
- package/dist/commands/provenance.d.ts.map +0 -1
- package/dist/commands/quality-monitor.d.ts +0 -17
- package/dist/commands/quality-monitor.d.ts.map +0 -1
- package/dist/commands/status.d.ts +0 -43
- 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/validate.d.ts +0 -8
- 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/config/index.d.ts +0 -29
- package/dist/config/index.d.ts.map +0 -1
- package/dist/error-handler.d.ts +0 -164
- package/dist/error-handler.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/working-spec.d.ts +0 -13
- package/dist/generators/working-spec.d.ts.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/minimal-cli.d.ts +0 -3
- package/dist/minimal-cli.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/cursor-hooks.d.ts +0 -7
- package/dist/scaffold/cursor-hooks.d.ts.map +0 -1
- package/dist/scaffold/git-hooks.d.ts +0 -20
- package/dist/scaffold/git-hooks.d.ts.map +0 -1
- package/dist/scaffold/index.d.ts +0 -20
- package/dist/scaffold/index.d.ts.map +0 -1
- package/dist/spec/SpecFileManager.d.ts +0 -146
- package/dist/spec/SpecFileManager.d.ts.map +0 -1
- package/dist/test-analysis.d.ts +0 -182
- 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/detection.d.ts +0 -7
- package/dist/utils/detection.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/project-analysis.d.ts +0 -14
- package/dist/utils/project-analysis.d.ts.map +0 -1
- package/dist/utils/typescript-detector.d.ts +0 -63
- package/dist/utils/typescript-detector.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/templates/.cursor/rules/03-infrastructure-standards.mdc +0 -251
- package/templates/.cursor/rules/04-documentation-integrity.mdc +0 -291
- package/templates/.cursor/rules/05-production-readiness-checklist.mdc +0 -214
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paths.design/caws-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "CAWS CLI - Coding Agent Workflow System command line tools",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"templates"
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "mkdir -p dist && cp -r src/* dist/
|
|
16
|
+
"build": "mkdir -p dist && cp -r src/* dist/",
|
|
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",
|
|
@@ -51,12 +51,10 @@
|
|
|
51
51
|
"directory": "packages/caws-cli"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"ajv": "^8.12.0",
|
|
55
54
|
"chalk": "4.1.2",
|
|
56
55
|
"commander": "^11.0.0",
|
|
57
56
|
"fs-extra": "^11.0.0",
|
|
58
|
-
"inquirer": "8.2.7"
|
|
59
|
-
"js-yaml": "4.1.0"
|
|
57
|
+
"inquirer": "8.2.7"
|
|
60
58
|
},
|
|
61
59
|
"devDependencies": {
|
|
62
60
|
"@eslint/js": "^9.0.0",
|
|
@@ -68,10 +66,13 @@
|
|
|
68
66
|
"@types/inquirer": "^8.2.6",
|
|
69
67
|
"@types/js-yaml": "^4.0.0",
|
|
70
68
|
"@types/node": "^20.0.0",
|
|
69
|
+
"ajv": "8.17.1",
|
|
71
70
|
"esbuild": "0.25.10",
|
|
72
71
|
"eslint": "^9.0.0",
|
|
73
72
|
"jest": "30.1.3",
|
|
73
|
+
"js-yaml": "4.1.0",
|
|
74
74
|
"lint-staged": "15.5.2",
|
|
75
|
+
"micromatch": "4.0.8",
|
|
75
76
|
"prettier": "^3.0.0",
|
|
76
77
|
"semantic-release": "25.0.0-beta.6",
|
|
77
78
|
"typescript": "^5.0.0"
|
|
@@ -13,6 +13,57 @@ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
|
|
|
13
13
|
# Check if CAWS is available and we have a working spec
|
|
14
14
|
if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
|
|
15
15
|
|
|
16
|
+
# AGENT GUARDRAILS - Prevent policy bypass attempts
|
|
17
|
+
if [[ "$ACTION" == "edit_file" ]] || [[ "$ACTION" == "create_file" ]]; then
|
|
18
|
+
if [[ "$FILE_PATH" == ".caws/policy.yaml" ]]; then
|
|
19
|
+
echo '{
|
|
20
|
+
"userMessage": "🚫 Policy file editing blocked by agent guardrails",
|
|
21
|
+
"agentMessage": "Agents cannot edit .caws/policy.yaml - requires human dual control",
|
|
22
|
+
"block": true,
|
|
23
|
+
"suggestions": [
|
|
24
|
+
"Policy changes must be approved by humans with Gatekeeper role",
|
|
25
|
+
"Create a separate PR for policy changes",
|
|
26
|
+
"For budget exceptions: caws waivers create --title=\"Budget exception\" --reason=architectural_refactor --gates=budget_limit",
|
|
27
|
+
"Contact @gatekeepers for policy modifications"
|
|
28
|
+
]
|
|
29
|
+
}'
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
if [[ "$FILE_PATH" == "CODEOWNERS" ]]; then
|
|
34
|
+
echo '{
|
|
35
|
+
"userMessage": "🚫 CODEOWNERS editing blocked by agent guardrails",
|
|
36
|
+
"agentMessage": "Agents cannot modify CODEOWNERS - governance changes require approval",
|
|
37
|
+
"block": true,
|
|
38
|
+
"suggestions": [
|
|
39
|
+
"CODEOWNERS changes require governance review",
|
|
40
|
+
"Contact repository maintainers for ownership changes",
|
|
41
|
+
"For approval workflows: caws waivers create --reason=governance_change"
|
|
42
|
+
]
|
|
43
|
+
}'
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
if [[ "$FILE_PATH" == ".caws/working-spec.yaml" ]]; then
|
|
48
|
+
# Check if trying to add change_budget
|
|
49
|
+
FILE_CONTENT=$(echo "$INPUT" | jq -r '.content // ""')
|
|
50
|
+
if echo "$FILE_CONTENT" | grep -q "change_budget"; then
|
|
51
|
+
echo '{
|
|
52
|
+
"userMessage": "🚫 Budget editing blocked by agent guardrails",
|
|
53
|
+
"agentMessage": "Agents cannot introduce change_budget fields - budgets are derived automatically",
|
|
54
|
+
"block": true,
|
|
55
|
+
"suggestions": [
|
|
56
|
+
"Check current budget status: caws burnup",
|
|
57
|
+
"For budget exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=budget_limit --expires-at=\"2025-12-31T23:59:59Z\"",
|
|
58
|
+
"Add waiver_ids to working spec instead: [\"WV-XXXX\"]",
|
|
59
|
+
"Validate waiver: caws validate .caws/working-spec.yaml"
|
|
60
|
+
]
|
|
61
|
+
}'
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
fi
|
|
65
|
+
fi
|
|
66
|
+
|
|
16
67
|
# For file access actions, check scope
|
|
17
68
|
if [[ "$ACTION" == "read_file" ]] || [[ "$ACTION" == "edit_file" ]] || [[ -n "$FILE_PATH" ]]; then
|
|
18
69
|
|
|
@@ -25,9 +76,10 @@ if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
|
|
|
25
76
|
"agentMessage": "Cannot access '"$FILE_PATH"' - outside CAWS defined scope",
|
|
26
77
|
"block": true,
|
|
27
78
|
"suggestions": [
|
|
28
|
-
"Check
|
|
29
|
-
"Update scope in .caws/working-spec.yaml
|
|
30
|
-
"
|
|
79
|
+
"Check current scope: caws validate .caws/working-spec.yaml",
|
|
80
|
+
"Update scope in working spec: edit .caws/working-spec.yaml scope.in array",
|
|
81
|
+
"For scope exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=scope_boundary --description=\"Need access to '"$FILE_PATH"' for implementation\"",
|
|
82
|
+
"Validate changes: caws validate .caws/working-spec.yaml"
|
|
31
83
|
]
|
|
32
84
|
}'
|
|
33
85
|
exit 1
|
|
@@ -36,8 +88,10 @@ if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
|
|
|
36
88
|
"userMessage": "⚠️ File access outside primary scope",
|
|
37
89
|
"agentMessage": "File '"$FILE_PATH"' is outside primary scope but allowed",
|
|
38
90
|
"suggestions": [
|
|
39
|
-
"
|
|
40
|
-
"
|
|
91
|
+
"Check if needed in primary scope: edit .caws/working-spec.yaml scope.in",
|
|
92
|
+
"Consider scope implications: caws agent evaluate",
|
|
93
|
+
"Document scope decision in working spec invariants",
|
|
94
|
+
"Validate scope changes: caws validate .caws/working-spec.yaml"
|
|
41
95
|
]
|
|
42
96
|
}'
|
|
43
97
|
fi
|
|
@@ -63,9 +117,11 @@ if command -v caws &> /dev/null && [[ -f ".caws/working-spec.yaml" ]]; then
|
|
|
63
117
|
"userMessage": "⚠️ Prompt references files outside CAWS scope",
|
|
64
118
|
"agentMessage": "Prompt mentions out-of-scope files: '"$OUT_OF_SCOPE"'",
|
|
65
119
|
"suggestions": [
|
|
66
|
-
"
|
|
67
|
-
"Update working spec scope
|
|
68
|
-
"
|
|
120
|
+
"Check current scope definition: caws validate .caws/working-spec.yaml",
|
|
121
|
+
"Update working spec scope: edit .caws/working-spec.yaml scope.in array",
|
|
122
|
+
"For scope exceptions: caws waivers create --title=\"Scope expansion\" --reason=architectural_refactor --gates=scope_boundary",
|
|
123
|
+
"Refocus prompt on in-scope files or request scope update approval",
|
|
124
|
+
"Validate scope changes: caws validate .caws/working-spec.yaml"
|
|
69
125
|
]
|
|
70
126
|
}'
|
|
71
127
|
fi
|
|
@@ -16,20 +16,30 @@ FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // ""')
|
|
|
16
16
|
|
|
17
17
|
# Only validate if working-spec.yaml was edited
|
|
18
18
|
if [[ "$FILE_PATH" == *"working-spec.yaml"* ]] || [[ "$FILE_PATH" == *"working-spec.yml"* ]]; then
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
echo "🔍 Validating CAWS working spec..." >&2
|
|
20
|
+
|
|
21
|
+
# Check if CAWS CLI is available
|
|
22
|
+
if command -v caws &> /dev/null; then
|
|
23
|
+
# Run CAWS validation with suggestions
|
|
24
|
+
if VALIDATION=$(caws validate "$FILE_PATH" --quiet 2>&1); then
|
|
25
|
+
echo '{"userMessage":"✅ CAWS spec validation passed","agentMessage":"Working specification is valid and complete."}' 2>/dev/null
|
|
26
|
+
else
|
|
27
|
+
# Get suggestions for fixing the spec
|
|
28
|
+
SUGGESTIONS=$(caws validate "$FILE_PATH" --suggestions 2>/dev/null | head -5 | tr '\n' '; ' | sed 's/; $//' || echo "Run caws validate --suggestions for details")
|
|
29
|
+
|
|
30
|
+
echo '{
|
|
31
|
+
"userMessage": "⚠️ CAWS spec validation failed. Run: caws validate --suggestions",
|
|
32
|
+
"agentMessage": "The working-spec.yaml file has validation errors. Please review and fix before continuing.",
|
|
33
|
+
"suggestions": [
|
|
34
|
+
"Run caws validate --suggestions for detailed error messages",
|
|
35
|
+
"Check required fields: id, title, risk_tier, mode",
|
|
36
|
+
"Ensure acceptance criteria are properly defined",
|
|
37
|
+
"Verify scope boundaries are appropriate"
|
|
38
|
+
]
|
|
39
|
+
}' 2>/dev/null
|
|
24
40
|
fi
|
|
25
41
|
else
|
|
26
|
-
|
|
27
|
-
if command -v caws &> /dev/null; then
|
|
28
|
-
if ! caws validate --quiet 2>/dev/null; then
|
|
29
|
-
echo '{"userMessage":"⚠️ CAWS spec validation failed. Run: caws validate --suggestions","agentMessage":"The working-spec.yaml file has validation errors."}' 2>/dev/null
|
|
30
|
-
exit 0
|
|
31
|
-
fi
|
|
32
|
-
fi
|
|
42
|
+
echo '{"userMessage":"⚠️ CAWS CLI not available for validation","agentMessage":"Install CAWS CLI for automatic spec validation: npm install -g @caws/cli"}' 2>/dev/null
|
|
33
43
|
fi
|
|
34
44
|
fi
|
|
35
45
|
|
|
@@ -141,4 +141,4 @@ Use this before any production claim:
|
|
|
141
141
|
- [ ] Deployment docs exist and are tested
|
|
142
142
|
- [ ] Documentation matches code reality
|
|
143
143
|
|
|
144
|
-
**If ANY box is unchecked, do not claim production readiness.**
|
|
144
|
+
**If ANY box is unchecked, do not claim production readiness.**
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Default agent behavior, edit style, and risk limits
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Working Style & Risk Limits
|
|
8
|
+
|
|
9
|
+
## Intent
|
|
10
|
+
|
|
11
|
+
Prefer directly applying fixes over explaining. Explanations are secondary unless asked, or when a change is **risky** (see Risk Gate).
|
|
12
|
+
|
|
13
|
+
## Edit Principles
|
|
14
|
+
|
|
15
|
+
- **Small, bounded diffs.** Keep edits minimal, cohesive, and reviewable.
|
|
16
|
+
- **Edit existing modules over forking.** Prefer refactor + rename to duplication.
|
|
17
|
+
- **Preserve public behavior** unless the task explicitly requests behavioral change.
|
|
18
|
+
|
|
19
|
+
## Ask-First Triggers (Risk Gate)
|
|
20
|
+
|
|
21
|
+
Before editing, _ask with a Targeted Edit Plan_ if any are true:
|
|
22
|
+
|
|
23
|
+
- Changes cross package boundaries or public APIs.
|
|
24
|
+
- Requires deleting files or renaming public symbols.
|
|
25
|
+
- Introduces a new dependency or build tool.
|
|
26
|
+
- Affects security, persistence, auth, or infra.
|
|
27
|
+
- Touches > 10 files or > 300 LOC.
|
|
28
|
+
|
|
29
|
+
**Targeted Edit Plan (TEP)** must include:
|
|
30
|
+
|
|
31
|
+
- Scope (files, symbols), risks, rollback notes.
|
|
32
|
+
- Tests to run/update.
|
|
33
|
+
- Acceptance checks (what passing looks like).
|
|
34
|
+
|
|
35
|
+
## Diff Hygiene
|
|
36
|
+
|
|
37
|
+
- Keep each commit focused on one intent.
|
|
38
|
+
- Include brief rationale in the commit subject (≤72 chars).
|
|
39
|
+
- Never bypass pre-commit hooks; `--no-verify` is **forbidden**.
|
|
40
|
+
|
|
41
|
+
## When to Explain
|
|
42
|
+
|
|
43
|
+
- On TEP prompts, on rejected edits, or when trade-offs are non-obvious.
|
|
44
|
+
- Keep explanations concise and adjacent to the diff.
|
|
45
|
+
|
|
46
|
+
## Acceptance (per PR)
|
|
47
|
+
|
|
48
|
+
- Tests + lints pass locally.
|
|
49
|
+
- No widened public API surface without TEP.
|
|
50
|
+
- No dead code or duplicate modules introduced.
|
|
@@ -36,9 +36,9 @@ alwaysApply: true
|
|
|
36
36
|
### Test Structure Requirements
|
|
37
37
|
|
|
38
38
|
```typescript
|
|
39
|
-
describe(
|
|
40
|
-
describe(
|
|
41
|
-
it(
|
|
39
|
+
describe('ComponentName', () => {
|
|
40
|
+
describe('when condition A', () => {
|
|
41
|
+
it('should behave correctly', () => {
|
|
42
42
|
// Given: Setup preconditions
|
|
43
43
|
// When: Execute the action
|
|
44
44
|
// Then: Verify the outcome
|
|
@@ -116,11 +116,11 @@ describe("ComponentName", () => {
|
|
|
116
116
|
|
|
117
117
|
```typescript
|
|
118
118
|
// DON'T: Mock the function you're supposed to test
|
|
119
|
-
jest.mock(
|
|
119
|
+
jest.mock('./businessLogic', () => ({
|
|
120
120
|
calculateTotal: jest.fn(() => 100),
|
|
121
121
|
}));
|
|
122
122
|
|
|
123
|
-
test(
|
|
123
|
+
test('calculateTotal', () => {
|
|
124
124
|
expect(calculateTotal()).toBe(100); // Tests the mock, not the logic
|
|
125
125
|
});
|
|
126
126
|
```
|
|
@@ -129,7 +129,7 @@ test("calculateTotal", () => {
|
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
131
|
// DON'T: Test private methods or internal state
|
|
132
|
-
test(
|
|
132
|
+
test('internal counter increments', () => {
|
|
133
133
|
component.privateCounter = 5; // Accessing private state
|
|
134
134
|
expect(component.privateCounter).toBe(5);
|
|
135
135
|
});
|
|
@@ -139,7 +139,7 @@ test("internal counter increments", () => {
|
|
|
139
139
|
|
|
140
140
|
```typescript
|
|
141
141
|
// DON'T: Generic error testing
|
|
142
|
-
test(
|
|
142
|
+
test('throws error', () => {
|
|
143
143
|
expect(() => riskyOperation()).toThrow(); // Too vague
|
|
144
144
|
});
|
|
145
145
|
```
|
|
@@ -148,8 +148,8 @@ test("throws error", () => {
|
|
|
148
148
|
|
|
149
149
|
```typescript
|
|
150
150
|
// DON'T: Leave test data behind
|
|
151
|
-
test(
|
|
152
|
-
await createUser({ name:
|
|
151
|
+
test('creates user', async () => {
|
|
152
|
+
await createUser({ name: 'test' });
|
|
153
153
|
// No cleanup - data persists
|
|
154
154
|
});
|
|
155
155
|
```
|
|
@@ -159,9 +159,9 @@ test("creates user", async () => {
|
|
|
159
159
|
### ✅ Proper Error Testing
|
|
160
160
|
|
|
161
161
|
```typescript
|
|
162
|
-
test(
|
|
163
|
-
expect(() => validateEmail(
|
|
164
|
-
expect(() => validateEmail(
|
|
162
|
+
test('throws specific error for invalid input', () => {
|
|
163
|
+
expect(() => validateEmail('invalid')).toThrow(ValidationError);
|
|
164
|
+
expect(() => validateEmail('invalid')).toThrow('Invalid email format');
|
|
165
165
|
});
|
|
166
166
|
```
|
|
167
167
|
|
|
@@ -169,19 +169,19 @@ test("throws specific error for invalid input", () => {
|
|
|
169
169
|
|
|
170
170
|
```typescript
|
|
171
171
|
const realisticUser = {
|
|
172
|
-
id:
|
|
173
|
-
email:
|
|
174
|
-
name:
|
|
175
|
-
createdAt: new Date(
|
|
176
|
-
preferences: { theme:
|
|
172
|
+
id: 'user-123',
|
|
173
|
+
email: 'user@example.com',
|
|
174
|
+
name: 'John Doe',
|
|
175
|
+
createdAt: new Date('2024-01-01'),
|
|
176
|
+
preferences: { theme: 'dark', notifications: true },
|
|
177
177
|
};
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
### ✅ Proper Async Testing
|
|
181
181
|
|
|
182
182
|
```typescript
|
|
183
|
-
test(
|
|
184
|
-
const result = await fetchUserData(
|
|
183
|
+
test('resolves with correct data', async () => {
|
|
184
|
+
const result = await fetchUserData('user-123');
|
|
185
185
|
expect(result).toEqual(expectedUserData);
|
|
186
186
|
});
|
|
187
187
|
```
|
|
@@ -189,7 +189,7 @@ test("resolves with correct data", async () => {
|
|
|
189
189
|
### ✅ Database Test Cleanup
|
|
190
190
|
|
|
191
191
|
```typescript
|
|
192
|
-
describe(
|
|
192
|
+
describe('UserService', () => {
|
|
193
193
|
let dbClient;
|
|
194
194
|
|
|
195
195
|
beforeEach(async () => {
|
|
@@ -209,7 +209,7 @@ describe("UserService", () => {
|
|
|
209
209
|
### Test Comments for Complex Logic
|
|
210
210
|
|
|
211
211
|
```typescript
|
|
212
|
-
test(
|
|
212
|
+
test('calculates compound interest with monthly compounding', () => {
|
|
213
213
|
// Formula: A = P(1 + r/n)^(nt)
|
|
214
214
|
// Where: A = final amount, P = principal, r = rate, n = compounding frequency, t = time
|
|
215
215
|
const principal = 1000;
|
|
@@ -217,12 +217,7 @@ test("calculates compound interest with monthly compounding", () => {
|
|
|
217
217
|
const compoundingFrequency = 12; // monthly
|
|
218
218
|
const timeInYears = 2;
|
|
219
219
|
|
|
220
|
-
const result = calculateCompoundInterest(
|
|
221
|
-
principal,
|
|
222
|
-
rate,
|
|
223
|
-
compoundingFrequency,
|
|
224
|
-
timeInYears
|
|
225
|
-
);
|
|
220
|
+
const result = calculateCompoundInterest(principal, rate, compoundingFrequency, timeInYears);
|
|
226
221
|
const expected = 1104.54; // Pre-calculated expected value
|
|
227
222
|
|
|
228
223
|
expect(result).toBeCloseTo(expected, 2);
|
|
@@ -245,7 +240,7 @@ test("calculates compound interest with monthly compounding", () => {
|
|
|
245
240
|
### Response Time Assertions
|
|
246
241
|
|
|
247
242
|
```typescript
|
|
248
|
-
test(
|
|
243
|
+
test('responds within SLA', async () => {
|
|
249
244
|
const startTime = Date.now();
|
|
250
245
|
const result = await expensiveOperation();
|
|
251
246
|
const duration = Date.now() - startTime;
|
|
@@ -312,4 +307,64 @@ test("meets color contrast requirements", () => {
|
|
|
312
307
|
getContrastRatio(styles.color, styles.backgroundColor)
|
|
313
308
|
).toBeGreaterThan(4.5);
|
|
314
309
|
});
|
|
315
|
-
```
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Execution Discipline
|
|
313
|
+
|
|
314
|
+
- Run unit tests and lints after any major change; iterate until green.
|
|
315
|
+
- If the project defines an engine, confirm Node version via console before running scripts.
|
|
316
|
+
- `.env` files exist; do **not** attempt to cat protected dotfiles. Use framework tooling or documented env loaders.
|
|
317
|
+
|
|
318
|
+
## Commits
|
|
319
|
+
|
|
320
|
+
- `--no-verify` is **not allowed**. If hooks fail, **fix the cause** or split work into smaller audited commits.
|
|
321
|
+
- Commit subjects: **what + why** in one sentence. Bodies for context only when needed.
|
|
322
|
+
|
|
323
|
+
## TODOs & Placeholders
|
|
324
|
+
|
|
325
|
+
Tag placeholders explicitly in code:
|
|
326
|
+
|
|
327
|
+
- `// TODO: ...` (critical, must block if reached)
|
|
328
|
+
- `// PLACEHOLDER: ...` (non-critical placeholder, warn)
|
|
329
|
+
- `// MOCK DATA: ...` (remove before release)
|
|
330
|
+
|
|
331
|
+
**Critical TODOs**: throw at execution site with clear message.
|
|
332
|
+
|
|
333
|
+
## Diagrams/Charts
|
|
334
|
+
|
|
335
|
+
- In Markdown, use **Mermaid** only. Ensure contrast (dark text on light, light on dark backgrounds).
|
|
336
|
+
|
|
337
|
+
## CAWS Integration
|
|
338
|
+
|
|
339
|
+
### Quality Gate Commands
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Run comprehensive test suite
|
|
343
|
+
caws quality-gates --test-coverage --mutation-testing
|
|
344
|
+
|
|
345
|
+
# Check test quality metrics
|
|
346
|
+
caws metrics track --metric="test_coverage" --value=85
|
|
347
|
+
caws metrics track --metric="mutation_score" --value=70
|
|
348
|
+
|
|
349
|
+
# Update progress with test completion
|
|
350
|
+
caws progress update --criterion-id="TEST-001" --status="completed" --tests-passing=25
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Test Analysis
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# Analyze test patterns and budget prediction
|
|
357
|
+
caws test-analysis assess-budget
|
|
358
|
+
caws test-analysis analyze-patterns
|
|
359
|
+
caws test-analysis find-similar
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Acceptance
|
|
363
|
+
|
|
364
|
+
- `test`, `lint`, `typecheck` succeed.
|
|
365
|
+
- No TODOs executed at runtime.
|
|
366
|
+
- No style violations flagged by project linters.
|
|
367
|
+
- Coverage thresholds met (80%+ line, 90%+ branch)
|
|
368
|
+
- Mutation testing scores meet targets (70%+ for critical components)
|
|
369
|
+
- All integration tests use real database connections
|
|
370
|
+
- Performance tests meet documented SLAs
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Canonical naming; forbid enhanced/new/final forks; refactor rules
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Canonical Naming & Refactor Rules
|
|
8
|
+
|
|
9
|
+
## No Duplicate/Fork Names
|
|
10
|
+
|
|
11
|
+
Reject or remove modules/files named with these modifiers:
|
|
12
|
+
`enhanced | unified | better | new | next | final | copy | revamp | improved` (case-insensitive).
|
|
13
|
+
|
|
14
|
+
**Pre-flight check (human-run or agent-run shell):**
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
rg -n --no-ignore -g '!node_modules' '(?i)\b(enhanced|unified|better|new|next|final|copy|revamp|improved)\b'
|
|
18
|
+
rg -n --no-ignore -g '!node_modules' '(?i)(enhanced|unified|new|final|copy).*\.([tj]sx?|mjs|cjs|mts|cts)$'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
If hits exist in proposed filenames/symbols: **do not proceed**. Use **purpose-first canonical names** and edit the existing module.
|
|
22
|
+
|
|
23
|
+
## Refactor Strategy
|
|
24
|
+
|
|
25
|
+
- **Merge, then delete**: If two files cover one domain, merge into the canonical name, update imports, remove the duplicate.
|
|
26
|
+
- Prefer **Strategy** + feature flags over file forks.
|
|
27
|
+
- Every refactor must include tests proving no behavior change (or updated tests + CHANGELOG if behavior changes).
|
|
28
|
+
|
|
29
|
+
## Acceptance
|
|
30
|
+
|
|
31
|
+
- No banned modifiers present in filenames or public symbols.
|
|
32
|
+
- Imports updated; build is green.
|
|
33
|
+
- Duplicates removed from tree.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Logging, language tone, emoji policy
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Logging & Language
|
|
8
|
+
|
|
9
|
+
## Clarity over chronology
|
|
10
|
+
|
|
11
|
+
Remove "phase/week" phrasing in docs/logs. State the **specific improvement**:
|
|
12
|
+
|
|
13
|
+
- ❌ "PHASE 1 optimization"
|
|
14
|
+
- ✅ "Initialize workload analyzer for parallelization"
|
|
15
|
+
|
|
16
|
+
## Emojis
|
|
17
|
+
|
|
18
|
+
- Emojis are banned across code, docs, and commits.
|
|
19
|
+
- Exception (debug logs only): ⚠️, ✅, 🚫.
|
|
20
|
+
|
|
21
|
+
## Commit Tone
|
|
22
|
+
|
|
23
|
+
Professional, neutral, and specific. Avoid hype or vague framing.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Safe defaults, guard clauses, early returns
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Safe Defaults & Guard Clauses
|
|
8
|
+
|
|
9
|
+
## Intent
|
|
10
|
+
|
|
11
|
+
Minimize null/undefined faults and nesting.
|
|
12
|
+
|
|
13
|
+
## Guidelines (language-agnostic)
|
|
14
|
+
|
|
15
|
+
- Prefer **guard clauses** at top of function to fail fast.
|
|
16
|
+
- Default parameter objects in signatures.
|
|
17
|
+
- Prefer **short-circuiting** / optional access / null-coalescing where supported.
|
|
18
|
+
- Loop defensively on possibly-empty collections.
|
|
19
|
+
|
|
20
|
+
## Acceptance
|
|
21
|
+
|
|
22
|
+
- No deep nesting introduced where guard clauses apply.
|
|
23
|
+
- Inputs validated at boundaries; failures are explicit and early.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: TypeScript/JS conventions (alias imports, const, types source of truth)
|
|
3
|
+
globs:
|
|
4
|
+
- '**/*.ts'
|
|
5
|
+
- '**/*.tsx'
|
|
6
|
+
- '**/*.mts'
|
|
7
|
+
- '**/*.cts'
|
|
8
|
+
alwaysApply: false
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# TS/JS Conventions
|
|
12
|
+
|
|
13
|
+
## Variables
|
|
14
|
+
|
|
15
|
+
- Prefer `const` over `let` where possible.
|
|
16
|
+
|
|
17
|
+
## Imports
|
|
18
|
+
|
|
19
|
+
- Use aliased imports from `@/` (mapped to `src`).
|
|
20
|
+
- Replace deep relative paths (`../../x`) with `@/...` when available.
|
|
21
|
+
|
|
22
|
+
## Types
|
|
23
|
+
|
|
24
|
+
- Single source of truth at `src/types`.
|
|
25
|
+
- Before creating a new type, check and extend the canonical definition.
|
|
26
|
+
- Avoid duplicate declarations; prefer composition or augmentation.
|
|
27
|
+
|
|
28
|
+
## Modularity
|
|
29
|
+
|
|
30
|
+
- As files approach ~1000 LOC, evaluate separation of concerns; extract cohesive units.
|
|
31
|
+
|
|
32
|
+
## Acceptance
|
|
33
|
+
|
|
34
|
+
- No unnecessary `let`.
|
|
35
|
+
- No duplicate type declarations.
|
|
36
|
+
- No deep relative paths where alias exists.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Process discipline for local servers and hung commands
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Process Discipline
|
|
8
|
+
|
|
9
|
+
## Servers
|
|
10
|
+
|
|
11
|
+
- Before starting a dev server, check if one is already running on the port; reuse or stop it to avoid duplicates.
|
|
12
|
+
- If multiple processes are attached to the port, list and kill explicitly; document PIDs in the PR note if non-obvious.
|
|
13
|
+
|
|
14
|
+
## Hung/Canceled Commands
|
|
15
|
+
|
|
16
|
+
If a command is canceled or stalls:
|
|
17
|
+
|
|
18
|
+
1. Assume it hung or waited for input.
|
|
19
|
+
2. Re-run with verbose/debug flags.
|
|
20
|
+
3. Surface the prompt/interaction in the PR so reviewers understand the resolution.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Architecture invariants (SOLID) and change isolation
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Architecture Invariants
|
|
8
|
+
|
|
9
|
+
- SRP: Each module/class has one reason to change.
|
|
10
|
+
- OCP: Prefer extension points over editing stable internals.
|
|
11
|
+
- LSP/ISP/DIP: Respect substitution; segregate interfaces; depend on abstractions.
|
|
12
|
+
|
|
13
|
+
## Change Isolation
|
|
14
|
+
|
|
15
|
+
- Introduce seams (interfaces/strategies) near integration points.
|
|
16
|
+
- Add tests at seams; assert unchanged public behavior.
|