book-to-skill skill
Converts books and documents (PDF, EPUB, DOCX, HTML, Markdown, plain text, RTF, MOBI/AZW with Calibre) into structured agent skills, extracting frameworks, mental models, principles, techniques, and anti-patterns. Use when the user wants to study a document through GitHub Copilot CLI, Amp, Claude Code, Hermes Agent, or OpenClaw, apply an author's frameworks while working, or build a reusable knowledge base from a file.
Is the book-to-skill skill safe?
Clean: nothing in its files matched our rules. We read 15 files in the folder on 2026-09-28.
No findings.
Install the book-to-skill skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/virgiliojr94/book-to-skill.git /tmp/book-to-skill mkdir -p ~/.claude/skills cp -r /tmp/book-to-skill/. ~/.claude/skills/book-to-skill
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
<!-- Cross-agent notes (informational; ignored by host agents):
.github/skills, .claude/skills, .agents/skills), Amp (.agents/skills, ~/.config/agents/skills, ~/.config/amp/skills), Claude Code (~/.claude/skills), Hermes Agent ($HERMESHOME/skills, .hermes/skills, .agents/skills), OpenClaw (${OPENCLAWSTATE_DIR:-~/.openclaw}/skills, .agents/skills, skills/; ~/.agents/skills only with the default state).
- Compatible skill roots: GitHub Copilot CLI (~/.copilot/skills, ~/.agents/skills,
shell/MCP-server names, Claude uses Bash/Read/Write/Glob/Grep, Amp adds shell_command. The skill needs shell (to run extract.py) and file read/write — each host will prompt for those on first use.
- allowed-tools is intentionally omitted to stay agent-neutral: Copilot CLI uses
-->
- Argument hint: ... [skill-name-slug]
Book-to-Skill Converter
Transform written knowledge into actionable agent skills by extracting structure — not producing summaries.
Philosophy
Books contain crystallized expertise: frameworks, principles, and techniques that took years to develop. This skill extracts that knowledge into a format GitHub Copilot CLI, Amp, Claude Code, Hermes Agent, OpenClaw, or another compatible agent can leverage repeatedly.
Extract structure, not summaries. A skill isn't a book report. It's a toolkit of:
- Named frameworks (mental models with clear application)
- Actionable principles (rules that guide decisions)
- Techniques (step-by-step methods)
- Anti-patterns (what to avoid and why)
- Voice calibration (how the author thinks and communicates)
Preserve the author's precision. Frameworks often have specific names for reasons. "The 5 Whys" isn't interchangeable with "ask why multiple times." Capture the exact formulation.
Layer depth appropriately. Simple books → simple skills. Complex books with 10+ frameworks → skills with reference files and on-demand chapters.
Modes of Operation
Four paths available. Route based on what the user asks:
1. Full Conversion (Default)
Trigger: User provides one or more document/directory/glob paths without special instructions Action: Run all steps below (Steps 0–9) Output: Complete skill with SKILL.md, chapters/, glossary, patterns, cheatsheet
2. Analyze Only
Trigger: User says "analyze", "just extract", or "I want to review before generating" Action: Run Steps 0–3, then produce a structured extraction report (frameworks, principles, techniques found). Stop — do NOT generate skill files. Output: Analysis report for user review
3. Generate from Prior Analysis
Trigger: User has existing analysis notes or previously ran analyze-only Action: Skip Steps 0–3, use the provided analysis as input, run Steps 4–9 Output: Skill files from the provided analysis
4. Update / Fold-in (Existing Skill)
Trigger: User provides one or more new source paths and indicates they want to update an existing skill (either by pointing to the existing skill folder, providing a skill slug that already exists in SKILLSHOME, or explicitly requesting an update). Action: Run Step 0 (out-of-scope check), Step 1 (validate inputs), Step 1.5 (identify book type), and Step 2 (extract new files). Then skip to Step 5 (identify/detect existing skill path) and run the Update / Fold-in Workflow to merge the new content into the existing skill files. Output:** Updated existing skill with new/revised chapter summaries and merged indexes/glossaries.
Skill Locations
This converter can run from multiple skill systems. When looking for this converter's helper script or writing the generated book skill, prefer these locations in order:
- GitHub Copilot CLI personal skills: ~/.copilot/skills/
- Cross-agent personal skills (Copilot, Amp, Codex; OpenClaw with its default state): ~/.agents/skills/
- Claude Code personal skills: ~/.claude/skills/
- Project-local Copilot skills: .github/skills/
- Project-local Claude skills: .claude/skills/
- Project-local Amp / Copilot / OpenClaw skills: .agents/skills/
- Amp global skills: ~/.config/agents/skills/
- Amp legacy global skills: ~/.config/amp/skills/
- Hermes Agent personal skills: $HERMES_HOME/skills/ (defaults to ~/.hermes/skills/)
- Hermes Agent project skills: .hermes/skills/ or .agents/skills/
- OpenClaw personal skills: ${OPENCLAWSTATEDIR:-~/.openclaw}/skills/ (active state; ~/.agents/skills/ is shared only with the default state)
- OpenClaw project skills: .agents/skills/ or skills/
For generated book skills, prefer the user-level cross-agent root ~/.agents/skills/ — one physical copy serves the cross-agent hosts and OpenClaw when it uses its default state. Copilot CLI and Amp discover it natively; Claude Code needs a symlink from ~/.claude/skills/ (created in Step 10, see Step 5 for the rules). Pick a host-private or project-local root only when the user explicitly asks for one. BOOKTOSKILL_SCOPE=project or personal can make that choice explicit for automation; do not ask a mandatory scope question merely because both scopes are available.
Step 0 — Out-of-scope check
If no arguments are provided, stop and respond:
"book-to-skill requires a supported document path, folder, or glob pattern. Usage: book-to-skill ... [skill-name-slug]"
Throughout the workflow:
- Identify the input paths and the optional skill slug.
- If the last argument is not a file, folder, or glob that exists or matches any files, and it looks like a skill slug (e.g. lowercase hyphens, alphanumeric), treat it as SKILL_NAME.
- Treat all other arguments as the list of INPUT_PATHS.
- If any input path is an existing skill directory (contains SKILL.md and a chapters/ sub-folder), or if SKILLNAME matches an existing skill slug in SKILLSHOME, flag this run as an Update/Fold-in operation (Mode 4).
Step 1 — Validate input
Verify that there is at least one supported file, directory, or glob pattern among the INPUT_PATHS. For directories and globs, expand them to find matching supported files (.pdf, .epub, .docx, .txt, .md, .markdown, .rst, .adoc, .html, .htm, .rtf, .mobi, .azw, .azw3).
If no supported files are found, stop with a clear error message.
Step 1.5 — Identify content type
Before extracting, ask the user:
"What kind of content do these sources have? This helps me choose the best extraction method.
1. Technical — has code blocks, tables, formulas, diagrams (e.g. programming books, academic papers, architecture guides)
2. Text-heavy — mostly prose, few or no tables/code (e.g. management, productivity, narrative non-fiction)
3. Not sure — I'll use the fast method and warn you if quality seems limited"
Store the answer as BOOK_TYPE:
- Option 1 → BOOK_TYPE=technical
- Option 2 → BOOK_TYPE=text
- Option 3 → BOOK_TYPE=text
If BOOKTYPE=technical**, inform the user before proceeding:
"📐 Technical mode selected — using Docling for structure-aware extraction (tables, code blocks, formulas preserved as markdown). This takes ~1.5s per page, so expect a few minutes for longer sources. Starting now…"
If BOOKTYPE=text**, inform:
"📄 Text mode selected — using the fastest suitable extractor for each file type. Plain text/Markdown/HTML are usually ready in seconds; PDFs use pdftotext when available."
Step 2 — Extract text from the source documents
Run the extraction script, passing the input paths:
SCRIPT_PATH=""
HERMES_HOME_RESOLVED="${HERMES_HOME:-$HOME/.hermes}"
OPENCLAW_STATE_DIR_RESOLVED="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
HERMES_PROJECT_TRUSTED=false
if [ -n "$PROJECT_ROOT" ] && [ "${HERMES_AGENT:-}" = true ] && \
command -v hermes >/dev/null 2>&1 && \
command -v python3 >/dev/null 2>&1 && \
hermes config get skills.trusted_project_dirs --json 2>/dev/null | PROJECT_ROOT="$PROJECT_ROOT" python3 -c 'import json, os, pathlib, sys; root=pathlib.Path(os.environ["PROJECT_ROOT"]).resolve(); sys.exit(not any(pathlib.Path(p).expanduser().resolve() == root for p in json.load(sys.stdin)))' 2>/dev/null
then
HERMES_PROJECT_TRUSTED=true
fi
CANDIDATES=(
"$HOME/.copilot/skills/book-to-skill/scripts/extract.py"
"$HOME/.agents/skills/book-to-skill/scripts/extract.py"
"$HOME/.claude/skills/book-to-skill/scripts/extract.py"
"${OPENCLAW_STATE_DIR_RESOLVED}/skills/book-to-skill/scripts/extract.py"
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/book-to-skill/scripts/extract.py
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/*/book-to-skill/scripts/extract.py
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/*/*/book-Before extraction, the script checks optional Python packages needed for the detected format. If a better extractor is missing, it prompts the user with the available fallback. Non-interactive sessions default to fallback unless install mode is explicitly yes.
Tip — preflight the environment: run "$PYTHONBIN" "$SCRIPTPATH" --check to print a per-format report of which extractors are installed and the exact command to install whatever is missing, without processing any file. Useful when a user reports a setup or quality problem.
This creates a per-run work directory — /bookskillwork-/ by default, or exactly the path you set in BOOKSKILLWORKDIR — containing:
- full_text.txt — combined extracted text of all sources with clear visually demarcated boundaries.
- metadata.json — overall combined size, words, pages, token counts, dropped EPUB image counts, the resolved workdir, and a detailed list of individual processed sources.
The run prints all three paths on completion (Workdir ->, Text ->, Meta ->). Take the paths from that output (or from metadata.json's own workdir field) rather than assuming a fixed location — the directory name differs per run so that concurrent extractions on one machine cannot overwrite each other's results.
Read that run's metadata.json to inspect the results.
Always confirm the extraction is the document you asked for before generating anything: check filename / sourcefile in metadata.json, or the SOURCE: header on the first line of fulltext.txt. If you are waiting on a background run, wait on its specific workdir — polling a shared path can surface a different run's output.