feat(core): add provider-adapter-author skill
Converts a target repo's provider-specific instruction file (CLAUDE.md, .cursor/rules, copilot-instructions.md, etc.) into a thin adapter over AGENTS.md, mirroring this repo's own two-tier CLAUDE.md pattern (ADR-0002/0003). Self-validates via a bundled deterministic script (scripts/validate-adapter.sh) rather than a separate paired audit skill. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
28
plugins/core/skills/provider-adapter-author/tests/README.md
Normal file
28
plugins/core/skills/provider-adapter-author/tests/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# tests/
|
||||
|
||||
Test files for scripts bundled with this skill.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Tests require [bats-support](https://github.com/bats-core/bats-support) and
|
||||
[bats-assert](https://github.com/bats-core/bats-assert). The test files load
|
||||
helpers from the repo root's `tests/test_helper/`.
|
||||
|
||||
From the repo root:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/bats-core/bats-support tests/test_helper/bats-support
|
||||
git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert
|
||||
```
|
||||
|
||||
Run all tests for this skill (from the repo root):
|
||||
|
||||
```bash
|
||||
bats plugins/core/skills/provider-adapter-author/tests/
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `validate-adapter.bats` | Bats test suite for `scripts/validate-adapter.sh` |
|
||||
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup() {
|
||||
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)"
|
||||
load "$REPO_ROOT/tests/test_helper/bats-support/load"
|
||||
load "$REPO_ROOT/tests/test_helper/bats-assert/load"
|
||||
|
||||
SCRIPT="$(cd "$BATS_TEST_DIRNAME/../scripts" && pwd)/validate-adapter.sh"
|
||||
TMPDIR="$(mktemp -d)"
|
||||
AGENTS_MD="$TMPDIR/AGENTS.md"
|
||||
cat > "$AGENTS_MD" <<'EOF'
|
||||
# AGENTS.md
|
||||
|
||||
## Setup commands
|
||||
- Install deps: `pnpm install`
|
||||
- Run tests: `pnpm test`
|
||||
|
||||
## Code style
|
||||
- TypeScript strict mode, single quotes, no semicolons.
|
||||
EOF
|
||||
}
|
||||
|
||||
teardown() {
|
||||
rm -rf "$TMPDIR"
|
||||
}
|
||||
|
||||
@test "fails when the adapter file is empty" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
: > "$ADAPTER"
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure
|
||||
assert_output --partial "empty"
|
||||
}
|
||||
|
||||
@test "fails when the adapter has no reference to AGENTS.md" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
cat > "$ADAPTER" <<'EOF'
|
||||
# Claude-specific notes
|
||||
Use the internal linter before committing.
|
||||
EOF
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure
|
||||
assert_output --partial "no reference"
|
||||
}
|
||||
|
||||
@test "passes a thin adapter with an @import line and provider-specific additions" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
cat > "$ADAPTER" <<'EOF'
|
||||
@AGENTS.md
|
||||
@core/instructions/governance.md
|
||||
EOF
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "fails when the adapter duplicates most of AGENTS.md's content" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
cat > "$ADAPTER" <<'EOF'
|
||||
@AGENTS.md
|
||||
|
||||
## Setup commands
|
||||
- Install deps: `pnpm install`
|
||||
- Run tests: `pnpm test`
|
||||
|
||||
## Code style
|
||||
- TypeScript strict mode, single quotes, no semicolons.
|
||||
EOF
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure
|
||||
assert_output --partial "duplicat"
|
||||
}
|
||||
|
||||
@test "fails when the adapter exceeds the max line threshold" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
{
|
||||
echo "@AGENTS.md"
|
||||
for i in $(seq 1 80); do echo "Provider-specific line $i unrelated to AGENTS.md content."; done
|
||||
} > "$ADAPTER"
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure
|
||||
assert_output --partial "thin"
|
||||
}
|
||||
|
||||
@test "allows a custom --max-lines threshold" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
{
|
||||
echo "@AGENTS.md"
|
||||
for i in $(seq 1 10); do echo "Provider-specific line $i unrelated to AGENTS.md content."; done
|
||||
} > "$ADAPTER"
|
||||
run bash "$SCRIPT" --max-lines 5 "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure
|
||||
assert_output --partial "thin"
|
||||
}
|
||||
|
||||
@test "with --no-import-syntax, a text pointer to AGENTS.md is accepted instead of an @import line" {
|
||||
ADAPTER="$TMPDIR/copilot-instructions.md"
|
||||
cat > "$ADAPTER" <<'EOF'
|
||||
See AGENTS.md at the repo root for setup, style, and testing conventions.
|
||||
|
||||
## Copilot-specific
|
||||
Prefer inline suggestions over chat for one-line edits.
|
||||
EOF
|
||||
run bash "$SCRIPT" --no-import-syntax "$ADAPTER" "$AGENTS_MD"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "with --no-import-syntax, still fails if there is no mention of AGENTS.md at all" {
|
||||
ADAPTER="$TMPDIR/copilot-instructions.md"
|
||||
cat > "$ADAPTER" <<'EOF'
|
||||
## Copilot-specific
|
||||
Prefer inline suggestions over chat for one-line edits.
|
||||
EOF
|
||||
run bash "$SCRIPT" --no-import-syntax "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure
|
||||
assert_output --partial "no reference"
|
||||
}
|
||||
|
||||
@test "--help exits 0 and documents usage" {
|
||||
run bash "$SCRIPT" --help
|
||||
assert_success
|
||||
assert_output --partial "Usage:"
|
||||
}
|
||||
|
||||
@test "fails with a clear error when the adapter file argument is missing" {
|
||||
run bash "$SCRIPT"
|
||||
assert_failure
|
||||
assert_output --partial "required"
|
||||
}
|
||||
Reference in New Issue
Block a user