Skip to content

Commit f57c7d5

Browse files
ddunnockclaude
andcommitted
Add primer schema, enhance schema validation, and add CI workflow
- Add primer.schema.json for AI context bootstrapping definitions - Enhance schema.rs with full jsonschema validation - Add test fixtures for all 6 schemas (26 tests passing) - Add GitHub Actions workflow for schema validation - Update README with all Schema Store catalog entries 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent ecf6ce1 commit f57c7d5

36 files changed

+4876
-18
lines changed

.claude/commands/validate-schemas.md

Whitespace-only changes.

.github/workflows/schemas.yml

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
name: Schema Validation
2+
3+
on:
4+
push:
5+
paths:
6+
- 'schemas/**'
7+
- 'cli/**'
8+
- '.github/workflows/schemas.yml'
9+
pull_request:
10+
paths:
11+
- 'schemas/**'
12+
- 'cli/**'
13+
- '.github/workflows/schemas.yml'
14+
15+
jobs:
16+
validate-schemas:
17+
name: Validate Schema Syntax
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Setup Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: '20'
26+
27+
- name: Install ajv-cli
28+
run: npm install -g ajv-cli ajv-formats
29+
30+
- name: Validate schema syntax (Draft-07)
31+
run: |
32+
for schema in schemas/v1/*.schema.json; do
33+
echo "Validating $schema..."
34+
ajv compile -s "$schema" --spec=draft7
35+
done
36+
37+
- name: Check Schema Store requirements
38+
run: |
39+
for schema in schemas/v1/*.schema.json; do
40+
echo "Checking Schema Store requirements for $schema..."
41+
# Check required fields exist
42+
jq -e '.["$schema"] and .["$id"] and .title and .description' "$schema" > /dev/null || {
43+
echo "ERROR: $schema missing required Schema Store fields (\$schema, \$id, title, description)"
44+
exit 1
45+
}
46+
# Check $id uses https
47+
ID=$(jq -r '.["$id"]' "$schema")
48+
if [[ ! "$ID" =~ ^https:// ]]; then
49+
echo "ERROR: $schema \$id must use https://"
50+
exit 1
51+
fi
52+
# Check $schema uses https
53+
SCHEMA=$(jq -r '.["$schema"]' "$schema")
54+
if [[ ! "$SCHEMA" =~ ^https:// ]]; then
55+
echo "ERROR: $schema \$schema must use https://"
56+
exit 1
57+
fi
58+
echo "✓ $schema passes Schema Store requirements"
59+
done
60+
61+
test-cli-validation:
62+
name: Test CLI Schema Validation
63+
runs-on: ubuntu-latest
64+
steps:
65+
- uses: actions/checkout@v4
66+
67+
- name: Setup Rust
68+
uses: dtolnay/rust-toolchain@stable
69+
70+
- name: Cache Cargo
71+
uses: actions/cache@v4
72+
with:
73+
path: |
74+
~/.cargo/bin/
75+
~/.cargo/registry/index/
76+
~/.cargo/registry/cache/
77+
~/.cargo/git/db/
78+
cli/target/
79+
key: ${{ runner.os }}-cargo-${{ hashFiles('cli/Cargo.lock') }}
80+
restore-keys: |
81+
${{ runner.os }}-cargo-
82+
83+
- name: Build CLI
84+
working-directory: cli
85+
run: cargo build --release
86+
87+
- name: Run schema validation tests
88+
working-directory: cli
89+
run: cargo test --test schema_validation
90+
91+
- name: Run all unit tests
92+
working-directory: cli
93+
run: cargo test
94+
95+
lint-schemas:
96+
name: Lint Schemas
97+
runs-on: ubuntu-latest
98+
steps:
99+
- uses: actions/checkout@v4
100+
101+
- name: Check JSON formatting
102+
run: |
103+
for schema in schemas/v1/*.schema.json; do
104+
echo "Checking formatting of $schema..."
105+
# Parse and re-format to check for valid JSON
106+
if ! jq . "$schema" > /dev/null 2>&1; then
107+
echo "ERROR: $schema is not valid JSON"
108+
exit 1
109+
fi
110+
echo "✓ $schema is valid JSON"
111+
done
112+
113+
- name: Check for duplicate keys
114+
run: |
115+
for schema in schemas/v1/*.schema.json; do
116+
echo "Checking for duplicate keys in $schema..."
117+
# jq will error on duplicate keys with -e
118+
if ! jq -e 'true' "$schema" > /dev/null 2>&1; then
119+
echo "ERROR: $schema may have duplicate keys"
120+
exit 1
121+
fi
122+
done
123+
124+
test-fixtures:
125+
name: Validate Test Fixtures
126+
runs-on: ubuntu-latest
127+
steps:
128+
- uses: actions/checkout@v4
129+
130+
- name: Setup Node.js
131+
uses: actions/setup-node@v4
132+
with:
133+
node-version: '20'
134+
135+
- name: Install ajv-cli
136+
run: npm install -g ajv-cli ajv-formats
137+
138+
- name: Validate valid fixtures against schemas
139+
run: |
140+
declare -A SCHEMA_MAP=(
141+
["cache"]="schemas/v1/cache.schema.json"
142+
["config"]="schemas/v1/config.schema.json"
143+
["vars"]="schemas/v1/vars.schema.json"
144+
["attempts"]="schemas/v1/attempts.schema.json"
145+
["sync"]="schemas/v1/sync.schema.json"
146+
["primer"]="schemas/v1/primer.schema.json"
147+
)
148+
149+
for schema_type in "${!SCHEMA_MAP[@]}"; do
150+
schema="${SCHEMA_MAP[$schema_type]}"
151+
valid_dir="cli/tests/fixtures/schemas/$schema_type/valid"
152+
153+
if [[ -d "$valid_dir" ]]; then
154+
for fixture in "$valid_dir"/*.json; do
155+
if [[ -f "$fixture" ]]; then
156+
echo "Validating $fixture against $schema..."
157+
ajv validate -s "$schema" -d "$fixture" --spec=draft7 || {
158+
echo "ERROR: Valid fixture $fixture failed validation"
159+
exit 1
160+
}
161+
fi
162+
done
163+
fi
164+
done
165+
166+
- name: Verify invalid fixtures fail validation
167+
run: |
168+
declare -A SCHEMA_MAP=(
169+
["cache"]="schemas/v1/cache.schema.json"
170+
["config"]="schemas/v1/config.schema.json"
171+
["vars"]="schemas/v1/vars.schema.json"
172+
["attempts"]="schemas/v1/attempts.schema.json"
173+
["sync"]="schemas/v1/sync.schema.json"
174+
["primer"]="schemas/v1/primer.schema.json"
175+
)
176+
177+
for schema_type in "${!SCHEMA_MAP[@]}"; do
178+
schema="${SCHEMA_MAP[$schema_type]}"
179+
invalid_dir="cli/tests/fixtures/schemas/$schema_type/invalid"
180+
181+
if [[ -d "$invalid_dir" ]]; then
182+
for fixture in "$invalid_dir"/*.json; do
183+
if [[ -f "$fixture" ]]; then
184+
echo "Verifying $fixture fails validation against $schema..."
185+
if ajv validate -s "$schema" -d "$fixture" --spec=draft7 2>/dev/null; then
186+
echo "ERROR: Invalid fixture $fixture should have failed validation"
187+
exit 1
188+
fi
189+
echo "✓ $fixture correctly failed validation"
190+
fi
191+
done
192+
fi
193+
done

cli/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ pub enum AcpError {
4848
#[error("Schema validation failed: {0}")]
4949
SchemaValidation(String),
5050

51+
/// Semantic validation failed (constraints that can't be expressed in JSON Schema)
52+
#[error("Semantic validation failed: {0}")]
53+
SemanticValidation(String),
54+
5155
/// Language not supported
5256
#[error("Unsupported language: {0}")]
5357
UnsupportedLanguage(String),

0 commit comments

Comments
 (0)