claude-skills/docs/commands/cs-book-to-plugin.md
Claude abd9c9d8de
docs(site): generate agent-launcher pages (18th domain) + nav
generate-docs.py learns the agent-launcher domain (5 hardcoded maps extended);
regenerated docs tree: 343 skill pages / 96 agent pages / 122 command pages
(561 total). mkdocs.yml nav gains the Agent Launcher skill section (7 pages),
4 cs-agent-* agent entries, and 8 /cs:* command entries; all nav targets verified
to exist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012FwXG6TqCXKZQvF4iD69cv
2026-08-24 17:26:12 +00:00

3.5 KiB

title description
/cs-book-to-plugin — Slash Command for AI Coding Agents /cs:book-to-plugin <compiled-skill-dir> [--domain <domain>] — wrap a compiled book skill in a claude-skills plugin package (manifest + cs-* agent +. Slash command for Claude Code, Codex CLI, Gemini CLI.

/cs-book-to-plugin

:material-console: Slash Command :material-github: Source

Command: /cs:book-to-plugin <compiled-skill-dir> [--domain <domain>] [--rights <basis>]

A folder in ~/.claude/skills/ is invisible to this repository: no manifest, no agent, no command, no marketplace entry, so nothing else in the library can route to it. This command closes that gap.

What it emits

<domain>/<slug>/
├── .claude-plugin/plugin.json     manifest, ./skills/<slug>, provenance + rights metadata
├── README.md                      what the skill knows, where it came from, its limits
├── agents/cs-<slug>.md            persona that answers from the source and cites chapters
├── commands/cs-<slug>.md          /cs:<slug> [topic | framework | chNN]
└── skills/<slug>/                 the compiled skill, copied verbatim

…then prints the .claude-plugin/marketplace.json entry to register. It never edits marketplace.json itself — registration is a repo-wide change and stays a human decision.

Gates

Gate Behaviour
Source has no SKILL.md Refuses. This is not a compiled book skill.
Source has validation errors Refuses and lists them. A package built on a broken index stays broken. --skip-validation overrides, and is almost always the wrong call.
Destination already exists Refuses without --force.
--distribution shareable without --rights Refuses. Compiled notes from a copyrighted work are personal study notes; redistributing them needs a basis.

Accepted rights bases: public-domain, open-license, internal-docs, author-permission. Fair use is deliberately not one — it is a defence, not a licence, and not a script's call. Without a basis the package emits as --distribution local and records source.cleared_for_distribution: false in the manifest.

Run

SKILL_ROOT=engineering/book-to-skill/skills/book-to-skill

# see exactly what would be written, first
python3 "$SKILL_ROOT/scripts/skill_plugin_emitter.py" \
    --skill-dir ~/.claude/skills/<slug> \
    --dest ./engineering --domain engineering \
    --source-note "<Full Title> by <Author>" \
    --dry-run

# write it
python3 "$SKILL_ROOT/scripts/skill_plugin_emitter.py" \
    --skill-dir ~/.claude/skills/<slug> \
    --dest ./engineering --domain engineering \
    --source-note "<Full Title> by <Author>"

After emitting

  1. Paste the printed entry into .claude-plugin/marketplace.json → plugins.
  2. Re-derive the headline counters: python3 scripts/derive_counters.py --check, then update README.md, CLAUDE.md and the marketplace description to match.
  3. Read the generated agent and command — they are scaffolds keyed to the source, and the voice is worth a pass by hand.
  4. Open the PR against dev. Never main.
  • /cs:book-to-skill — compile the source in the first place
  • /cs:plugin-audit — 8-phase audit of the emitted package before merge