Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when the user asks to lint, audit, test, benchmark, validate, or fix an agent skill — from a single SKILL.md frontmatter check to trigger-accuracy measurement or a corpus-wide audit of installed skills for duplication — driving the shakespii CLI (init, lint --json, test --run, bench) to resolve findings until clean.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-12 | ✗→✓ | ▲ Improved | 75% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 26% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 91% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 146% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 134% | 0% |
Teach an agent to drive the shakespii CLI — the deterministic lint and scaffold substrate for Agent Skills — so skills get created and repaired against the anatomy contract instead of by taste. The CLI decides; this skill teaches the loop around it.
SKILL.md), or acorpus root — a directory of skill directories — audited in one run with --corpus.
should trigger it — all three confirmed with the human before scaffolding.
bun --version succeeds).bun add -g shakespii;the binary lands in ~/.bun/bin), or the repo cloned and linked (bun install && bun link inside it); shakespii --version then succeeds.
Shared core, both branches:
shakespii lint <dir> --json and parse stdout (schema version: 1). Eachfinding carries ruleId, severity, file, line, message.
0 means no errors — proceed. 1 means errors — enter the fix loop.2 means lint itself could not run — report the stderr message verbatim and stop; never guess around a broken run.
ruleId inreferences/rule-remediations.md and apply the minimal fix. A finding whose rule has no entry there is fixed from its own message — messages are written to be actionable.
the human explicitly with a reason. Never silently ignore a warning.
Audit branch — fix an existing skill:
root, run shakespii lint <root> --corpus --json: work each skill's findings with the same loop, and treat corpusFindings (XS rules, whose sites name every involved skill) as refactor suggestions spanning skills.
trigger; do not rewrite what the skill is for.
standing with reasons.
After a skill lints clean, verify its eval suite with the harness:
bashshakespii test <skill-dir> --json
Exit codes: 0 = no error findings (warnings allowed), 1 = error findings to fix, 2 = the run itself failed (bad path, no SKILL.md, claude CLI missing). The deterministic stage checks that evals/evals.json exists, parses, follows the skill-creator schema (skill_name equal to the frontmatter name, unique integer ids, non-empty prompts and expectations, at least three cases), and references only files that exist inside the skill directory. Without --run the scenario and grading stages report skipped — the command is free and safe to loop on.
To actually execute the evals — a headless agent runs each case, then an LLM grader scores every expectation with cited evidence — add --run:
bashshakespii test <skill-dir> --run --json
--run spends real tokens (one executor and one grader session per eval case), so confirm with the human before the first run on a suite (when a human is present to answer; in a non-interactive run, an explicit approval already given in the task prompt satisfies this). Results are cached per (skill content, eval, model): re-running after no changes replays instantly from cache; editing the skill or its evals re-runs only because the content hash changed. --fresh forces re-execution despite the cache; --model <name> overrides the default executor/grader model (sonnet). Fix loop: deterministic findings name the JSON path of the defect in evals/evals.json; scenario findings mean the executor run itself failed (timeout, crash); grading findings quote the failed expectation and the grader's evidence — fix the skill (or a genuinely wrong expectation, with the human's approval) and re-run until exit 0.
Once the evals pass, measure the skill's actual capability impact:
bashshakespii bench <skill-dir> --json
bench runs every eval in evals/evals.json with the skill mounted and again without it, --runs <n> times per configuration (default 3), and writes benchmark.json. Read run_summary.delta for the with-vs-without capability delta on pass rate, time, and tokens — that delta is the signal, not the exit code: exit 0 means the matrix was measured and written, full stop, whether the skill helped, hurt, or made no difference; bench never gates on the delta. Exit 1 means a run failed after its retry and nothing was written; exit 2 means the eval suite has deterministic findings (fix those first, same gate as test) or the claude CLI is unavailable. --model <name> overrides the default executor model (sonnet); --fresh bypasses the cache to force a fresh measurement. Like --run, bench spends real tokens per run — confirm with the human before the first run on a suite (or accept an approval the task prompt already grants), and never point it at an untrusted third-party skill: both --run and bench execute with --dangerously-skip-permissions.
A skill only helps if it fires at the right moments, so measure that directly rather than trusting the description by eye. Author evals/triggers.json: at least 16 labeled queries mixing prompts that should trigger the skill with near-miss negatives that should not — TR02 lints this set statically on every lint run (missing file, schema errors, too few queries, no negatives). Then run it for real:
bashshakespii test <skill-dir> --run --triggers --json
The trigger stage mounts the skill and issues each query 3 times against a real session, scores a query as triggered when a majority of its reps fire, and reports overall accuracy across the set. That stage fails (an error finding) below 0.8 accuracy. Treat description edits as a deliberate loop, not a guess: adjust the wording, re-run with --fresh to bypass the cache and force fresh measurement, and stop once accuracy holds at 0.8 or above without regressing queries that already passed.
Once a skill lints clean and its evals pass, land it in an agent's live skills directory through the gate rather than by hand-copying:
bashshakespii install <skill-dir-or-bundled-name> --json
install re-lints the source, runs the deterministic eval checks when evals/evals.json exists, and only then copies the skill into the target. Lint errors or deterministic failures block the install (exit 1); warnings never block — surface them to the human instead. The default target is Claude (~/.claude/skills); --provider <name> selects others (claude, codex, cursor, antigravity, gemini, agents, ezio — repeat the flag for several, or --provider all for every provider detected on the machine), and --target <dir> installs into an arbitrary directory. An occupied destination — an existing directory or symlink — is refused unless the human approves replacing it; with that approval, add --force. The --json report (version: 1) carries the gate verdict in gate.lint and gate.test plus one entry per target in targets[] (installed, forced, reason); targets[].advisory lists cross-skill duplication findings (XS rules) against the skills already installed at that target — advisory only, never a block, but report them to the human. Exit codes: 0 = gate passed and every target installed; 1 = gate blocked or a target refused; 2 = usage error (unknown provider, unresolvable skill).
Authoring branch — create a new skill:
them from the task prompt when it already supplies and approves them), then run shakespii init <name> in the agreed parent directory.
marks them with TODO(shakespii) plus a trailing colon) with real content.
evals/evals.json with at least three cases, each an in-skillbehavior branch (happy path, refusal or error branches, variants). Scope negatives do not belong here — put near-miss queries in evals/triggers.json, where the trigger stage measures them.
and its evals to the human. Install only with explicit approval and never with findings outstanding — and when approved, install through shakespii install (see "Installing a skill"), not by hand-copying.
counts and per-rule changes.
SKILL.md, README.md, evals/evals.json) thatlints clean, presented to the human for approval — not installed.
Audit, end to end. The user says: "Lint my skill at ~/.claude/skills/summarize-notes and fix what it finds."
Input: shakespii lint ~/.claude/skills/summarize-notes --json exits 1 with one finding — ruleId FM04, severity error, file SKILL.md, line 3, message "description must begin with a trigger phrase (one of: use when, use for, use if, use this, invoke when, when the user)".
The agent opens the FM04 entry in the remediation reference and rewrites the description from "Compresses long chat threads into short bullet summaries" to "Use when the user asks to summarize a long chat thread into short bullets", changing nothing else.
Output: the re-lint exits 0 with zero findings, and the agent reports "1 error → 0 findings; FM04 fixed by rewording the description trigger-first", listing no remaining warnings.
gutting a description. Fix the defect, keep the substance.
--corpus at a single skill directory — corpus mode takes the parentdirectory; lint a single skill without the flag.
2 — that exit means lint itself could not run;report it instead of retrying.
shakespii installexists — the gate is the point of the install step.
Other measured skills in the registry, with their headline benchmark lift.