Skip to content
Development
Command

/write-skill

Author a new skill from scratch with paired trigger fixtures and full validation. Use when adding a skill that has no upstream skills.sh source (discipline, meta, or internal-pattern skills).

From plugin
2812 skills12 commands
shell
$ npx -y skills add iliaal/whetstone --agent claude-code

Ships with whetstone. Installing the plugin gets this command.

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/write-skill

Context preview

What this command does when you run it.

Author a new skill from scratch with paired trigger fixtures and full validation. Use when adding a skill that has no upstream skills.sh source (discipline, meta, or internal-pattern skills).

Command definition

write-skill.md
name: write-skill
description: Author a new skill from scratch with paired trigger fixtures and full validation. Use when adding a skill that has no upstream skills.sh source (discipline, meta, or internal-pattern skills).
argument-hint: "<skill-name>  (e.g. ia-foo)"

Write Skill

**Skill name:** `$ARGUMENTS`

Scaffold a new plugin skill from scratch, generate paired trigger fixtures, register the regex pattern, and run all gates. For distilling a skill from skills.sh sources, use the `skill-distiller` skill instead — `/write-skill` is for skills with no external upstream.

Phase 1: Resolve target

1. If `$ARGUMENTS` is empty or doesn't start with `ia-`, ask for the skill name. 2. Validate format: must match `^ia-[a-z0-9][a-z0-9-]*$`, no consecutive hyphens, no banned tokens (`anthropic`, `claude`). 3. Confirm the skill doesn't already exist:

  • `plugins/whetstone/skills/<name>/SKILL.md` must NOT exist.
  • `distillery/tests/fixtures/triggers/<name>.jsonl` must NOT exist.
  • No matching `SKILL_PATTERNS[<name>]=` line in `plugins/whetstone/hooks/skill-patterns.sh`.

4. Read `CLAUDE.md` "Skill compliance checklist" section to refresh the gates this skill must pass.

Phase 2: Batch up-front interview

Use `AskUserQuestion` once to collect everything needed before scaffolding. Do not drip-feed questions across turns.

Ask:

1. **Class** — one of the five values from `CLAUDE.md` "Skill class taxonomy": `language`, `discipline`, `workflow`, `meta`, `tool`. Read that section before asking so the option descriptions match what the validator will accept. 2. **Scope summary** — one or two sentences: what this skill is for, when it fires. 3. **Primary trigger vocabulary** — 3-6 distinctive phrases users would type. 4. **Existing skills it should not overlap with** — names of any close-in-scope `ia-*` skills the user already has in mind.

Phase 3: Inspect prior art

Read the SKILL.md of every skill the user named in question 4 (and any others that look similar by class). Goals:

  • Match house style (frontmatter shape, body voice, references/ patterns).
  • Identify trigger overlap risk — `validate-plugin` will flag descriptions with >70% word overlap.
  • Find a close structural template to model the new skill after.

Phase 4: Scaffold

Generate four artifacts atomically. Do not split across phases.

4a. SKILL.md

Path: `plugins/whetstone/skills/<name>/SKILL.md`

Frontmatter rules (all hard requirements — `validate-plugin` enforces them):

  • `name:` matches the directory name exactly.
  • `class:` one of `language`, `discipline`, `workflow`, `meta`, `tool` (the value from question 1). Required. The validator rejects unknown values.
  • `description:` describes **what + when**, not how. Lead with one sentence on what the skill does, then `Use when ...` with concrete trigger language. Stay under 80 tokens. No vague phrases (`comprehensive`, `best practices`, `robust`, `seamless`, `powerful` — see `_VAGUE_DESCRIPTION_PHRASES` in `distillery/scripts/distiller.py`). No second person, no provider names unless the skill is intentionally provider-specific.
  • No inert fields (`triggers`, `role`, `scope`, `domain`, `version`, `tags` — they're ignored by Claude Code).

Body rules:

  • Imperative voice (verb-first instructions).
  • 100-2000 tokens ideal, 4000 hard cap. Split to `references/` if larger.
  • No machine-specific paths (`/home/...`, `/Users/...`, `~/ai/...`, `C:\Users\...`). Use `<repo-root>` or `<skill-dir>` placeholders.
  • No placeholder text (`TODO`, `FIXME`, `XXX`, `[YOUR ...]`).
  • No MUST/ALWAYS/NEVER spam (>15 directives is flagged as OVER_CONSTRAINED).
  • Hunt no-ops sentence by sentence, not just line by line: run the no-op test on each sentence in isolation, and when one fails (it restates the obvious, or the agent would behave identically without it), delete the whole sentence rather than trim words from it. Most prose that fails should go, not be reworded.
  • Anchor a behavior in a single strong token where one exists (`tight`, `red`, `surgical`) instead of spelling the same instruction out three ways -- a well-chosen leading word carries the intent at lower token cost than a paragraph.
  • If creating `references/`, link every file with `[name](./references/name.md)` syntax — orphans are flagged. Each reference under 150 lines (warning) and 800 lines (error).
  • **Skill Independence**: do not instruct the agent to invoke another skill by name. Forms to avoid: `run the ia-X skill`, `use the \`ia-X\` skill`, `hand off to ia-X`, `<vendor>:Y` runtime references. Other skills may be missing, renamed, or user-overridden — name-invocation silently breaks in all three cases. Instead, state the intent directly (`If on \`main\`, create a feature branch first.`) and trust skill discovery to surface the right skill, or load a local file via `[name](./references/name.md)`. Naming an agent (Agent tool dispatch) or referencing a skill in non-runtime prose (provenance, audit allowlist) is fine.

4b. Trigger fixtures

Path: `distillery/tests/fixtures/triggers/<name>.jsonl`

JSONL format. **Required floors: 5 should_trigger AND 5 should_not_trigger** — `test-triggers` fails the run if either count is below floor.

{"prompt": "<realistic phrasing a user would type>", "expect": true, "added_in": "<current-version>", "source": "initial"}
{"prompt": "<adjacent task that must NOT trigger this skill>", "expect": false, "added_in": "<current-version>", "source": "initial"}

Drafting guidance:

  • Positives: 5+ phrasings that exercise different ways a user might invoke this skill. Vary verb, vary scope, include at least one terse phrasing.
  • Negatives: 5+ phrasings that look superficially related but should not trigger. Include phrasings that match adjacent skills' descriptions (the `validate-plugin` DUPLICATE_TRIGGER detector catches this kind of overlap).
  • Do not use AI-flavored placeholders. Each prompt should be a thing a real user would type.

Read the current plugin version fro

Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withwhetstone

A Claude Code plugin that makes AI coding agents follow engineering discipline. Plan before coding. Verify before claiming done. Find root cause before patching. Review before merge. Skills activate based on file type and task signals, not manual toggling.

Get the whole plugin, auto-invoked
Stats
28
Stars
0
Views
2
Forks
Active
Maintenance
Python
Language
MIT
License
4d ago
Last commit
5mo ago
Created

Repo: iliaal/whetstone