anvil-dev-framework 0.1.6
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 +719 -0
- package/VERSION +1 -0
- package/docs/ANVIL-REPO-IMPLEMENTATION-PLAN.md +441 -0
- package/docs/FIRST-SKILL-TUTORIAL.md +408 -0
- package/docs/INSTALLATION-RETRO-NOTES.md +458 -0
- package/docs/INSTALLATION.md +984 -0
- package/docs/anvil-hud.md +469 -0
- package/docs/anvil-init.md +255 -0
- package/docs/anvil-state.md +210 -0
- package/docs/boris-cherny-ralph-wiggum-insights.md +608 -0
- package/docs/command-reference.md +2022 -0
- package/docs/hooks-tts.md +368 -0
- package/docs/implementation-guide.md +810 -0
- package/docs/linear-github-integration.md +247 -0
- package/docs/local-issues.md +677 -0
- package/docs/patterns/README.md +419 -0
- package/docs/planning-responsibilities.md +139 -0
- package/docs/session-workflow.md +573 -0
- package/docs/simplification-plan-template.md +297 -0
- package/docs/simplification-principles.md +129 -0
- package/docs/specifications/CCS-RALPH-INTEGRATION-DESIGN.md +633 -0
- package/docs/specifications/CCS-RESEARCH-REPORT.md +169 -0
- package/docs/specifications/PLAN-ANV-verification-ralph-wiggum.md +403 -0
- package/docs/specifications/PLAN-parallel-tracks-anvil-memory-ccs.md +494 -0
- package/docs/specifications/SPEC-ANV-VRW/component-01-verify.md +208 -0
- package/docs/specifications/SPEC-ANV-VRW/component-02-stop-gate.md +226 -0
- package/docs/specifications/SPEC-ANV-VRW/component-03-posttooluse.md +209 -0
- package/docs/specifications/SPEC-ANV-VRW/component-04-ralph-wiggum.md +604 -0
- package/docs/specifications/SPEC-ANV-VRW/component-05-atomic-actions.md +311 -0
- package/docs/specifications/SPEC-ANV-VRW/component-06-verify-subagent.md +264 -0
- package/docs/specifications/SPEC-ANV-VRW/component-07-claude-md.md +363 -0
- package/docs/specifications/SPEC-ANV-VRW/index.md +182 -0
- package/docs/specifications/SPEC-ANV-anvil-memory.md +573 -0
- package/docs/specifications/SPEC-ANV-context-checkpoints.md +781 -0
- package/docs/specifications/SPEC-ANV-verification-ralph-wiggum.md +789 -0
- package/docs/sync.md +122 -0
- package/global/CLAUDE.md +140 -0
- package/global/agents/verify-app.md +164 -0
- package/global/commands/anvil-settings.md +527 -0
- package/global/commands/anvil-sync.md +121 -0
- package/global/commands/change.md +197 -0
- package/global/commands/clarify.md +252 -0
- package/global/commands/cleanup.md +292 -0
- package/global/commands/commit-push-pr.md +207 -0
- package/global/commands/decay-review.md +127 -0
- package/global/commands/discover.md +158 -0
- package/global/commands/doc-coverage.md +122 -0
- package/global/commands/evidence.md +307 -0
- package/global/commands/explore.md +121 -0
- package/global/commands/force-exit.md +135 -0
- package/global/commands/handoff.md +191 -0
- package/global/commands/healthcheck.md +302 -0
- package/global/commands/hud.md +84 -0
- package/global/commands/insights.md +319 -0
- package/global/commands/linear-setup.md +184 -0
- package/global/commands/lint-fix.md +198 -0
- package/global/commands/orient.md +510 -0
- package/global/commands/plan.md +228 -0
- package/global/commands/ralph.md +346 -0
- package/global/commands/ready.md +182 -0
- package/global/commands/release.md +305 -0
- package/global/commands/retro.md +96 -0
- package/global/commands/shard.md +166 -0
- package/global/commands/spec.md +227 -0
- package/global/commands/sprint.md +184 -0
- package/global/commands/tasks.md +228 -0
- package/global/commands/test-and-commit.md +151 -0
- package/global/commands/validate.md +132 -0
- package/global/commands/verify.md +251 -0
- package/global/commands/weekly-review.md +156 -0
- package/global/hooks/__pycache__/ralph_context_monitor.cpython-314.pyc +0 -0
- package/global/hooks/__pycache__/statusline_agent_sync.cpython-314.pyc +0 -0
- package/global/hooks/anvil_memory_observe.ts +322 -0
- package/global/hooks/anvil_memory_session.ts +166 -0
- package/global/hooks/anvil_memory_stop.ts +187 -0
- package/global/hooks/parse_transcript.py +116 -0
- package/global/hooks/post_merge_cleanup.sh +132 -0
- package/global/hooks/post_tool_format.sh +215 -0
- package/global/hooks/ralph_context_monitor.py +240 -0
- package/global/hooks/ralph_stop.sh +502 -0
- package/global/hooks/statusline.sh +1110 -0
- package/global/hooks/statusline_agent_sync.py +224 -0
- package/global/hooks/stop_gate.sh +250 -0
- package/global/lib/.claude/anvil-state.json +21 -0
- package/global/lib/__pycache__/agent_registry.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/claim_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coderabbit_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/config_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coordination_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/doc_coverage_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/gate_logger.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/github_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/hygiene_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_models.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_data_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/local_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/quality_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/ralph_state.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/state_manager.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/transcript_parser.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verification_runner.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_iteration.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_subagent.cpython-314.pyc +0 -0
- package/global/lib/agent_registry.py +995 -0
- package/global/lib/anvil-state.sh +435 -0
- package/global/lib/claim_service.py +515 -0
- package/global/lib/coderabbit_service.py +314 -0
- package/global/lib/config_service.py +423 -0
- package/global/lib/coordination_service.py +331 -0
- package/global/lib/doc_coverage_service.py +1305 -0
- package/global/lib/gate_logger.py +316 -0
- package/global/lib/github_service.py +310 -0
- package/global/lib/handoff_generator.py +775 -0
- package/global/lib/hygiene_service.py +712 -0
- package/global/lib/issue_models.py +257 -0
- package/global/lib/issue_provider.py +339 -0
- package/global/lib/linear_data_service.py +210 -0
- package/global/lib/linear_provider.py +987 -0
- package/global/lib/linear_provider.py.backup +671 -0
- package/global/lib/local_provider.py +486 -0
- package/global/lib/orient_fast.py +457 -0
- package/global/lib/quality_service.py +470 -0
- package/global/lib/ralph_prompt_generator.py +563 -0
- package/global/lib/ralph_state.py +1202 -0
- package/global/lib/state_manager.py +417 -0
- package/global/lib/transcript_parser.py +597 -0
- package/global/lib/verification_runner.py +557 -0
- package/global/lib/verify_iteration.py +490 -0
- package/global/lib/verify_subagent.py +250 -0
- package/global/skills/README.md +155 -0
- package/global/skills/quality-gates/SKILL.md +252 -0
- package/global/skills/skill-template/SKILL.md +109 -0
- package/global/skills/testing-strategies/SKILL.md +337 -0
- package/global/templates/CHANGE-template.md +105 -0
- package/global/templates/HANDOFF-template.md +63 -0
- package/global/templates/PLAN-template.md +111 -0
- package/global/templates/SPEC-template.md +93 -0
- package/global/templates/ralph/PROMPT.md.template +89 -0
- package/global/templates/ralph/fix_plan.md.template +31 -0
- package/global/templates/ralph/progress.txt.template +23 -0
- package/global/tests/__pycache__/test_doc_coverage.cpython-314.pyc +0 -0
- package/global/tests/test_doc_coverage.py +520 -0
- package/global/tests/test_issue_models.py +299 -0
- package/global/tests/test_local_provider.py +323 -0
- package/global/tools/README.md +178 -0
- package/global/tools/__pycache__/anvil-hud.cpython-314.pyc +0 -0
- package/global/tools/anvil-hud.py +3622 -0
- package/global/tools/anvil-hud.py.bak +3318 -0
- package/global/tools/anvil-issue.py +432 -0
- package/global/tools/anvil-memory/CLAUDE.md +49 -0
- package/global/tools/anvil-memory/README.md +42 -0
- package/global/tools/anvil-memory/bun.lock +25 -0
- package/global/tools/anvil-memory/bunfig.toml +9 -0
- package/global/tools/anvil-memory/package.json +23 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/context-monitor.test.ts +535 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/edge-cases.test.ts +645 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/fixtures.ts +363 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/index.ts +8 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/integration.test.ts +417 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/prompt-generator.test.ts +571 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/ralph-stop.test.ts +440 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/test-utils.ts +252 -0
- package/global/tools/anvil-memory/src/__tests__/commands.test.ts +657 -0
- package/global/tools/anvil-memory/src/__tests__/db.test.ts +641 -0
- package/global/tools/anvil-memory/src/__tests__/hooks.test.ts +272 -0
- package/global/tools/anvil-memory/src/__tests__/performance.test.ts +427 -0
- package/global/tools/anvil-memory/src/__tests__/test-utils.ts +113 -0
- package/global/tools/anvil-memory/src/commands/checkpoint.ts +197 -0
- package/global/tools/anvil-memory/src/commands/get.ts +115 -0
- package/global/tools/anvil-memory/src/commands/init.ts +94 -0
- package/global/tools/anvil-memory/src/commands/observe.ts +163 -0
- package/global/tools/anvil-memory/src/commands/search.ts +112 -0
- package/global/tools/anvil-memory/src/db.ts +638 -0
- package/global/tools/anvil-memory/src/index.ts +205 -0
- package/global/tools/anvil-memory/src/types.ts +122 -0
- package/global/tools/anvil-memory/tsconfig.json +29 -0
- package/global/tools/ralph-loop.sh +359 -0
- package/package.json +45 -0
- package/scripts/anvil +822 -0
- package/scripts/extract_patterns.py +222 -0
- package/scripts/init-project.sh +541 -0
- package/scripts/install.sh +229 -0
- package/scripts/postinstall.js +41 -0
- package/scripts/rollback.sh +188 -0
- package/scripts/sync.sh +623 -0
- package/scripts/test-statusline.sh +248 -0
- package/scripts/update_claude_md.py +224 -0
- package/scripts/verify.sh +255 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
verify_subagent.py - Invocation wrapper for the verify-app subagent.
|
|
4
|
+
|
|
5
|
+
This module provides functions to invoke the verification subagent and
|
|
6
|
+
parse its structured JSON response.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Verification result structure
|
|
17
|
+
class VerificationResult:
|
|
18
|
+
"""Structured verification result."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, data: dict):
|
|
21
|
+
self.overall = data.get("overall", "fail")
|
|
22
|
+
self.tests = data.get("tests", {"passed": False, "count": 0, "failures": []})
|
|
23
|
+
self.lint = data.get("lint", {"passed": False, "errors": 0})
|
|
24
|
+
self.types = data.get("types", {"passed": False, "errors": 0})
|
|
25
|
+
self.summary = data.get("summary", "Verification failed")
|
|
26
|
+
self._raw = data
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def passed(self) -> bool:
|
|
30
|
+
"""Overall pass/fail status."""
|
|
31
|
+
return self.overall == "pass"
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def test_count(self) -> int:
|
|
35
|
+
"""Number of tests run."""
|
|
36
|
+
return self.tests.get("count", 0)
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def test_failures(self) -> list:
|
|
40
|
+
"""List of test failures."""
|
|
41
|
+
return self.tests.get("failures", [])
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def lint_errors(self) -> int:
|
|
45
|
+
"""Number of lint errors."""
|
|
46
|
+
return self.lint.get("errors", 0)
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def type_errors(self) -> int:
|
|
50
|
+
"""Number of type errors."""
|
|
51
|
+
return self.types.get("errors", 0)
|
|
52
|
+
|
|
53
|
+
def to_dict(self) -> dict:
|
|
54
|
+
"""Return raw dictionary."""
|
|
55
|
+
return self._raw
|
|
56
|
+
|
|
57
|
+
def __repr__(self) -> str:
|
|
58
|
+
return f"VerificationResult(overall={self.overall}, summary={self.summary!r})"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def detect_project_type(project_path: Optional[Path] = None) -> str:
|
|
62
|
+
"""Detect project type from config files."""
|
|
63
|
+
path = project_path or Path.cwd()
|
|
64
|
+
|
|
65
|
+
if (path / "package.json").exists():
|
|
66
|
+
return "node"
|
|
67
|
+
elif (path / "pyproject.toml").exists() or (path / "setup.py").exists():
|
|
68
|
+
return "python"
|
|
69
|
+
elif (path / "Cargo.toml").exists():
|
|
70
|
+
return "rust"
|
|
71
|
+
elif (path / "go.mod").exists():
|
|
72
|
+
return "go"
|
|
73
|
+
else:
|
|
74
|
+
return "unknown"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_verification_commands(project_type: str) -> dict:
|
|
78
|
+
"""Get verification commands for project type."""
|
|
79
|
+
commands = {
|
|
80
|
+
"node": {
|
|
81
|
+
"test": "npm test",
|
|
82
|
+
"lint": "npm run lint",
|
|
83
|
+
"typecheck": "npm run typecheck"
|
|
84
|
+
},
|
|
85
|
+
"python": {
|
|
86
|
+
"test": "pytest",
|
|
87
|
+
"lint": "ruff check .",
|
|
88
|
+
"typecheck": "mypy ."
|
|
89
|
+
},
|
|
90
|
+
"rust": {
|
|
91
|
+
"test": "cargo test",
|
|
92
|
+
"lint": "cargo clippy -- -D warnings",
|
|
93
|
+
"typecheck": None # Included in clippy
|
|
94
|
+
},
|
|
95
|
+
"go": {
|
|
96
|
+
"test": "go test ./...",
|
|
97
|
+
"lint": "golangci-lint run",
|
|
98
|
+
"typecheck": None # Included in build
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return commands.get(project_type, {})
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def run_verification_local(project_path: Optional[Path] = None) -> VerificationResult:
|
|
105
|
+
"""
|
|
106
|
+
Run verification locally without subagent.
|
|
107
|
+
|
|
108
|
+
This is a fallback when the subagent is not available.
|
|
109
|
+
"""
|
|
110
|
+
path = project_path or Path.cwd()
|
|
111
|
+
project_type = detect_project_type(path)
|
|
112
|
+
commands = get_verification_commands(project_type)
|
|
113
|
+
|
|
114
|
+
result = {
|
|
115
|
+
"overall": "pass",
|
|
116
|
+
"tests": {"passed": True, "count": 0, "failures": []},
|
|
117
|
+
"lint": {"passed": True, "errors": 0, "warnings": 0},
|
|
118
|
+
"types": {"passed": True, "errors": 0},
|
|
119
|
+
"summary": ""
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
issues = []
|
|
123
|
+
|
|
124
|
+
# Run tests
|
|
125
|
+
if commands.get("test"):
|
|
126
|
+
try:
|
|
127
|
+
proc = subprocess.run(
|
|
128
|
+
commands["test"],
|
|
129
|
+
shell=True,
|
|
130
|
+
cwd=path,
|
|
131
|
+
capture_output=True,
|
|
132
|
+
text=True,
|
|
133
|
+
timeout=300
|
|
134
|
+
)
|
|
135
|
+
if proc.returncode != 0:
|
|
136
|
+
result["tests"]["passed"] = False
|
|
137
|
+
result["overall"] = "fail"
|
|
138
|
+
issues.append("tests failed")
|
|
139
|
+
except subprocess.TimeoutExpired:
|
|
140
|
+
result["tests"]["passed"] = False
|
|
141
|
+
result["overall"] = "fail"
|
|
142
|
+
issues.append("tests timed out")
|
|
143
|
+
except Exception as e:
|
|
144
|
+
result["tests"]["passed"] = False
|
|
145
|
+
issues.append(f"test error: {e}")
|
|
146
|
+
|
|
147
|
+
# Run lint
|
|
148
|
+
if commands.get("lint"):
|
|
149
|
+
try:
|
|
150
|
+
proc = subprocess.run(
|
|
151
|
+
commands["lint"],
|
|
152
|
+
shell=True,
|
|
153
|
+
cwd=path,
|
|
154
|
+
capture_output=True,
|
|
155
|
+
text=True,
|
|
156
|
+
timeout=120
|
|
157
|
+
)
|
|
158
|
+
if proc.returncode != 0:
|
|
159
|
+
result["lint"]["passed"] = False
|
|
160
|
+
result["lint"]["errors"] = 1 # At least one
|
|
161
|
+
result["overall"] = "fail"
|
|
162
|
+
issues.append("lint errors")
|
|
163
|
+
except Exception:
|
|
164
|
+
pass # Lint failure is non-fatal
|
|
165
|
+
|
|
166
|
+
# Run typecheck
|
|
167
|
+
if commands.get("typecheck"):
|
|
168
|
+
try:
|
|
169
|
+
proc = subprocess.run(
|
|
170
|
+
commands["typecheck"],
|
|
171
|
+
shell=True,
|
|
172
|
+
cwd=path,
|
|
173
|
+
capture_output=True,
|
|
174
|
+
text=True,
|
|
175
|
+
timeout=120
|
|
176
|
+
)
|
|
177
|
+
if proc.returncode != 0:
|
|
178
|
+
result["types"]["passed"] = False
|
|
179
|
+
result["types"]["errors"] = 1
|
|
180
|
+
result["overall"] = "fail"
|
|
181
|
+
issues.append("type errors")
|
|
182
|
+
except Exception:
|
|
183
|
+
pass # Type check failure is non-fatal
|
|
184
|
+
|
|
185
|
+
# Build summary
|
|
186
|
+
if result["overall"] == "pass":
|
|
187
|
+
result["summary"] = "All checks passed."
|
|
188
|
+
else:
|
|
189
|
+
result["summary"] = f"Verification failed: {', '.join(issues)}"
|
|
190
|
+
|
|
191
|
+
return VerificationResult(result)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def invoke_verify_subagent(
|
|
195
|
+
prompt: str = "Run full verification suite and report results as JSON",
|
|
196
|
+
timeout: int = 300,
|
|
197
|
+
project_path: Optional[Path] = None
|
|
198
|
+
) -> VerificationResult:
|
|
199
|
+
"""
|
|
200
|
+
Invoke the verify-app subagent.
|
|
201
|
+
|
|
202
|
+
This function spawns a Claude Code subagent to run verification.
|
|
203
|
+
If the subagent is not available, falls back to local verification.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
prompt: The prompt to send to the subagent
|
|
207
|
+
timeout: Timeout in seconds
|
|
208
|
+
project_path: Path to the project to verify
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
VerificationResult with structured results
|
|
212
|
+
"""
|
|
213
|
+
# For now, use local verification as the subagent invocation
|
|
214
|
+
# requires the Task tool which is only available in Claude Code context
|
|
215
|
+
return run_verification_local(project_path)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def main():
|
|
219
|
+
"""CLI interface for verification."""
|
|
220
|
+
import argparse
|
|
221
|
+
|
|
222
|
+
parser = argparse.ArgumentParser(description="Run project verification")
|
|
223
|
+
parser.add_argument("--path", type=Path, help="Project path")
|
|
224
|
+
parser.add_argument("--json", action="store_true", help="Output JSON")
|
|
225
|
+
args = parser.parse_args()
|
|
226
|
+
|
|
227
|
+
result = run_verification_local(args.path)
|
|
228
|
+
|
|
229
|
+
if args.json:
|
|
230
|
+
print(json.dumps(result.to_dict(), indent=2))
|
|
231
|
+
else:
|
|
232
|
+
status = "✅ PASS" if result.passed else "❌ FAIL"
|
|
233
|
+
print(f"\n{status}: {result.summary}\n")
|
|
234
|
+
|
|
235
|
+
if not result.tests.get("passed", True):
|
|
236
|
+
print("Test Failures:")
|
|
237
|
+
for failure in result.test_failures:
|
|
238
|
+
print(f" - {failure.get('file', 'unknown')}:{failure.get('line', '?')} - {failure.get('message', 'failed')}")
|
|
239
|
+
|
|
240
|
+
if result.lint_errors > 0:
|
|
241
|
+
print(f"Lint Errors: {result.lint_errors}")
|
|
242
|
+
|
|
243
|
+
if result.type_errors > 0:
|
|
244
|
+
print(f"Type Errors: {result.type_errors}")
|
|
245
|
+
|
|
246
|
+
sys.exit(0 if result.passed else 1)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
if __name__ == "__main__":
|
|
250
|
+
main()
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Skills
|
|
2
|
+
|
|
3
|
+
Skills are domain-specific knowledge modules that Claude loads on-demand to enhance its capabilities in specialized areas.
|
|
4
|
+
|
|
5
|
+
## Why Skills?
|
|
6
|
+
|
|
7
|
+
Skills solve the context window problem:
|
|
8
|
+
- **Without skills**: All knowledge must fit in system prompt (limited)
|
|
9
|
+
- **With skills**: Load only relevant knowledge when needed (efficient)
|
|
10
|
+
|
|
11
|
+
## Skill Structure
|
|
12
|
+
|
|
13
|
+
Each skill is a directory containing:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
skills/
|
|
17
|
+
└── my-skill/
|
|
18
|
+
├── SKILL.md # Main skill file (required)
|
|
19
|
+
├── README.md # Human documentation (optional)
|
|
20
|
+
└── examples/ # Reference examples (optional)
|
|
21
|
+
├── example-1.ts
|
|
22
|
+
└── example-2.ts
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### SKILL.md Format
|
|
26
|
+
|
|
27
|
+
```markdown
|
|
28
|
+
---
|
|
29
|
+
name: My Skill
|
|
30
|
+
description: Brief description of what this skill provides
|
|
31
|
+
triggers:
|
|
32
|
+
- keyword1
|
|
33
|
+
- keyword2
|
|
34
|
+
version: 1.0.0
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# My Skill
|
|
38
|
+
|
|
39
|
+
## When to Use
|
|
40
|
+
[Describe when Claude should load this skill]
|
|
41
|
+
|
|
42
|
+
## Key Concepts
|
|
43
|
+
[Domain knowledge Claude needs]
|
|
44
|
+
|
|
45
|
+
## Patterns
|
|
46
|
+
[Specific patterns to follow]
|
|
47
|
+
|
|
48
|
+
## Examples
|
|
49
|
+
[Code examples or references to examples/ directory]
|
|
50
|
+
|
|
51
|
+
## Anti-Patterns
|
|
52
|
+
[What to avoid]
|
|
53
|
+
|
|
54
|
+
## References
|
|
55
|
+
[Links to external documentation]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## How Skills Work
|
|
59
|
+
|
|
60
|
+
1. **Trigger**: User request mentions skill keywords
|
|
61
|
+
2. **Load**: Claude reads SKILL.md into context
|
|
62
|
+
3. **Apply**: Claude uses skill knowledge for the task
|
|
63
|
+
4. **Unload**: Skill naturally leaves context after task
|
|
64
|
+
|
|
65
|
+
## Creating a New Skill
|
|
66
|
+
|
|
67
|
+
1. Copy `skill-template/` to `skills/your-skill-name/`
|
|
68
|
+
2. Edit `SKILL.md` with your domain knowledge
|
|
69
|
+
3. Add examples if helpful
|
|
70
|
+
4. Test by asking Claude to use the skill
|
|
71
|
+
|
|
72
|
+
## Built-in vs Custom Skills
|
|
73
|
+
|
|
74
|
+
**Built-in** (from Anvil):
|
|
75
|
+
- None included by default
|
|
76
|
+
- Framework provides structure, not content
|
|
77
|
+
|
|
78
|
+
**Custom** (you create):
|
|
79
|
+
- Project-specific patterns
|
|
80
|
+
- Tech stack conventions
|
|
81
|
+
- Domain knowledge
|
|
82
|
+
|
|
83
|
+
## Skill Categories
|
|
84
|
+
|
|
85
|
+
Consider organizing skills by domain:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
skills/
|
|
89
|
+
├── frontend/
|
|
90
|
+
│ ├── component-patterns/
|
|
91
|
+
│ ├── state-management/
|
|
92
|
+
│ └── accessibility/
|
|
93
|
+
├── backend/
|
|
94
|
+
│ ├── api-design/
|
|
95
|
+
│ ├── database-patterns/
|
|
96
|
+
│ └── security/
|
|
97
|
+
├── testing/
|
|
98
|
+
│ ├── unit-testing/
|
|
99
|
+
│ └── integration-testing/
|
|
100
|
+
└── devops/
|
|
101
|
+
├── ci-cd/
|
|
102
|
+
└── deployment/
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Best Practices
|
|
106
|
+
|
|
107
|
+
1. **Keep skills focused** — One skill = one domain
|
|
108
|
+
2. **Include examples** — Show, don't just tell
|
|
109
|
+
3. **Document triggers** — Help Claude know when to load
|
|
110
|
+
4. **Version skills** — Track changes over time
|
|
111
|
+
5. **Test skills** — Verify they improve output quality
|
|
112
|
+
|
|
113
|
+
## Skill Size Guidelines
|
|
114
|
+
|
|
115
|
+
| Size | Lines | Use Case |
|
|
116
|
+
|------|-------|----------|
|
|
117
|
+
| Small | <100 | Single pattern or concept |
|
|
118
|
+
| Medium | 100-300 | Domain with multiple patterns |
|
|
119
|
+
| Large | 300-500 | Complex domain (consider splitting) |
|
|
120
|
+
| Too Large | >500 | Split into multiple skills |
|
|
121
|
+
|
|
122
|
+
## Example: Security Patterns Skill
|
|
123
|
+
|
|
124
|
+
```markdown
|
|
125
|
+
---
|
|
126
|
+
name: Backend Security Patterns
|
|
127
|
+
description: Security patterns for API routes and data handling
|
|
128
|
+
triggers:
|
|
129
|
+
- security
|
|
130
|
+
- authentication
|
|
131
|
+
- authorization
|
|
132
|
+
- api route
|
|
133
|
+
version: 1.0.0
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
# Backend Security Patterns
|
|
137
|
+
|
|
138
|
+
## Authentication
|
|
139
|
+
- Always verify session on protected routes
|
|
140
|
+
- Use httpOnly cookies for tokens
|
|
141
|
+
- Implement CSRF protection
|
|
142
|
+
|
|
143
|
+
## Authorization
|
|
144
|
+
- Check permissions before operations
|
|
145
|
+
- Use Row Level Security in database
|
|
146
|
+
- Validate ownership of resources
|
|
147
|
+
|
|
148
|
+
## Input Validation
|
|
149
|
+
- Sanitize all user input
|
|
150
|
+
- Use parameterized queries
|
|
151
|
+
- Validate types and ranges
|
|
152
|
+
|
|
153
|
+
## Examples
|
|
154
|
+
See examples/auth-middleware.ts
|
|
155
|
+
```
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Quality Gates
|
|
3
|
+
description: Layered quality gate patterns for catching issues at the right time
|
|
4
|
+
triggers:
|
|
5
|
+
- quality gates
|
|
6
|
+
- pre-commit
|
|
7
|
+
- pre-push
|
|
8
|
+
- ci pipeline
|
|
9
|
+
- git hooks
|
|
10
|
+
- lint
|
|
11
|
+
- typecheck
|
|
12
|
+
version: 1.0.0
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Quality Gates
|
|
16
|
+
|
|
17
|
+
Framework-agnostic patterns for layered quality validation.
|
|
18
|
+
|
|
19
|
+
## Philosophy
|
|
20
|
+
|
|
21
|
+
**Catch issues at the right time, not all at once.**
|
|
22
|
+
|
|
23
|
+
Running full validation on every keystroke is slow. Running nothing until CI is too late. Layer your gates by speed and scope.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Layer Model
|
|
28
|
+
|
|
29
|
+
| Layer | When | Speed Target | Scope |
|
|
30
|
+
|-------|------|--------------|-------|
|
|
31
|
+
| Pre-commit | Before each commit | <5 seconds | Staged files only |
|
|
32
|
+
| Pre-push | Before pushing | <30 seconds | Changed files |
|
|
33
|
+
| CI | After push | Minutes | Full codebase |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Pre-Commit Layer (Fast, Staged Files)
|
|
38
|
+
|
|
39
|
+
**Purpose:** Catch obvious issues immediately. Must be fast or developers bypass.
|
|
40
|
+
|
|
41
|
+
### Typical Checks
|
|
42
|
+
- Linting (staged files only)
|
|
43
|
+
- Formatting (auto-fix)
|
|
44
|
+
- No debug statements (console.log, print, debugger)
|
|
45
|
+
- No secrets (quick pattern match)
|
|
46
|
+
- Commit message format
|
|
47
|
+
|
|
48
|
+
### Implementation Patterns
|
|
49
|
+
|
|
50
|
+
**Node/TypeScript (husky + lint-staged):**
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"lint-staged": {
|
|
54
|
+
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
|
|
55
|
+
"*.{json,md}": ["prettier --write"]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Python (pre-commit):**
|
|
61
|
+
```yaml
|
|
62
|
+
repos:
|
|
63
|
+
- repo: https://github.com/psf/black
|
|
64
|
+
hooks:
|
|
65
|
+
- id: black
|
|
66
|
+
- repo: https://github.com/pycqa/flake8
|
|
67
|
+
hooks:
|
|
68
|
+
- id: flake8
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### What NOT to Include
|
|
72
|
+
- Type checking (too slow for staged files)
|
|
73
|
+
- Full test suite
|
|
74
|
+
- Build verification
|
|
75
|
+
- Anything >5 seconds
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Pre-Push Layer (Thorough, Changed Files)
|
|
80
|
+
|
|
81
|
+
**Purpose:** Catch type errors and test failures before remote.
|
|
82
|
+
|
|
83
|
+
### Typical Checks
|
|
84
|
+
- Type checking
|
|
85
|
+
- Unit tests (affected by changes)
|
|
86
|
+
- Build verification (if fast)
|
|
87
|
+
- Security scanning (quick)
|
|
88
|
+
|
|
89
|
+
### Implementation Pattern
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# .git/hooks/pre-push or via husky
|
|
93
|
+
npm run typecheck
|
|
94
|
+
npm run test -- --changedSince=origin/main
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Tradeoff
|
|
98
|
+
Can be skipped with `--no-verify` for WIP pushes. CI catches what slips through.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## CI Layer (Comprehensive, Full Suite)
|
|
103
|
+
|
|
104
|
+
**Purpose:** Canonical quality verification. Never skip.
|
|
105
|
+
|
|
106
|
+
### Typical Checks
|
|
107
|
+
- Full lint
|
|
108
|
+
- Full type check
|
|
109
|
+
- Full test suite (unit + integration)
|
|
110
|
+
- Build verification
|
|
111
|
+
- Security scanning (dependencies, SAST)
|
|
112
|
+
- Coverage thresholds
|
|
113
|
+
|
|
114
|
+
### AI-Specific Additions
|
|
115
|
+
|
|
116
|
+
Checks particularly relevant for AI-generated code:
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
# Check for common AI mistakes
|
|
120
|
+
- name: Check for 'any' types
|
|
121
|
+
run: grep -r "any" src/ && exit 1 || exit 0
|
|
122
|
+
|
|
123
|
+
- name: Check for console.log
|
|
124
|
+
run: grep -r "console.log" src/ && exit 1 || exit 0
|
|
125
|
+
|
|
126
|
+
- name: Check TODO without issue
|
|
127
|
+
run: grep -rn "TODO" src/ | grep -v "TODO(#" && exit 1 || exit 0
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Security Scanning Tools
|
|
131
|
+
|
|
132
|
+
| Tool | Purpose | Speed |
|
|
133
|
+
|------|---------|-------|
|
|
134
|
+
| gitleaks/trufflehog | Secrets in commits | Fast |
|
|
135
|
+
| npm audit / pip audit | Dependency vulnerabilities | Fast |
|
|
136
|
+
| Semgrep | SAST (code patterns) | Medium |
|
|
137
|
+
| Trivy | Container scanning | Medium |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Configuration by Ecosystem
|
|
142
|
+
|
|
143
|
+
### Node.js / TypeScript
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
// package.json
|
|
147
|
+
{
|
|
148
|
+
"scripts": {
|
|
149
|
+
"lint": "eslint . --ext .ts,.tsx",
|
|
150
|
+
"lint:staged": "eslint --fix",
|
|
151
|
+
"typecheck": "tsc --noEmit",
|
|
152
|
+
"test": "vitest",
|
|
153
|
+
"test:ci": "vitest run --coverage",
|
|
154
|
+
"precommit": "lint-staged",
|
|
155
|
+
"prepush": "npm run typecheck && npm test"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Python
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
# .pre-commit-config.yaml
|
|
164
|
+
repos:
|
|
165
|
+
- repo: local
|
|
166
|
+
hooks:
|
|
167
|
+
- id: pytest
|
|
168
|
+
name: pytest
|
|
169
|
+
entry: pytest
|
|
170
|
+
language: system
|
|
171
|
+
pass_filenames: false
|
|
172
|
+
stages: [push]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Go
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Makefile
|
|
179
|
+
lint:
|
|
180
|
+
golangci-lint run
|
|
181
|
+
|
|
182
|
+
test:
|
|
183
|
+
go test ./...
|
|
184
|
+
|
|
185
|
+
pre-commit:
|
|
186
|
+
gofmt -w .
|
|
187
|
+
golangci-lint run --fast
|
|
188
|
+
|
|
189
|
+
pre-push:
|
|
190
|
+
go test ./...
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Anti-Patterns
|
|
196
|
+
|
|
197
|
+
❌ **Running full suite on pre-commit**
|
|
198
|
+
- Too slow → gets bypassed
|
|
199
|
+
- Fix: Staged files only, defer heavy checks
|
|
200
|
+
|
|
201
|
+
❌ **No pre-push checks**
|
|
202
|
+
- CI feedback too slow (minutes vs seconds)
|
|
203
|
+
- Fix: Add quick type/test check before push
|
|
204
|
+
|
|
205
|
+
❌ **Skippable CI checks**
|
|
206
|
+
- Defeats the purpose
|
|
207
|
+
- Fix: Required status checks on main
|
|
208
|
+
|
|
209
|
+
❌ **Notifications without blocking**
|
|
210
|
+
- Gets ignored
|
|
211
|
+
- Fix: Block merge, not just notify
|
|
212
|
+
|
|
213
|
+
❌ **Same checks at every layer**
|
|
214
|
+
- Redundant, slow
|
|
215
|
+
- Fix: Layer by speed and scope
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Quality Gate Checklist
|
|
220
|
+
|
|
221
|
+
Before committing:
|
|
222
|
+
- [ ] Pre-commit hooks installed and running
|
|
223
|
+
- [ ] Lint passes on staged files
|
|
224
|
+
- [ ] No debug statements
|
|
225
|
+
|
|
226
|
+
Before pushing:
|
|
227
|
+
- [ ] Types pass
|
|
228
|
+
- [ ] Tests pass (affected files)
|
|
229
|
+
- [ ] No secrets in diff
|
|
230
|
+
|
|
231
|
+
Before merge (CI):
|
|
232
|
+
- [ ] Full test suite passes
|
|
233
|
+
- [ ] Coverage threshold met
|
|
234
|
+
- [ ] Security scan clean
|
|
235
|
+
- [ ] Build succeeds
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Implementation Notes
|
|
240
|
+
|
|
241
|
+
This skill provides **patterns**, not project-specific configuration.
|
|
242
|
+
|
|
243
|
+
**Project implements:**
|
|
244
|
+
- Install git hooks tooling (husky, pre-commit, etc.)
|
|
245
|
+
- Configure hooks for project's tech stack
|
|
246
|
+
- Set up CI pipeline
|
|
247
|
+
- Document in CONTRIBUTING.md
|
|
248
|
+
|
|
249
|
+
**Framework provides:**
|
|
250
|
+
- Principles (layer by speed/scope)
|
|
251
|
+
- Common patterns per ecosystem
|
|
252
|
+
- Anti-patterns to avoid
|