Help us improve
Share bugs, ideas, or general feedback.
From obsidian-vault-agent
Analyzes EPUB/PDF books into structured chapter notes with key concepts extracted and synthesized via parallel agents.
npx claudepluginhub tuan3w/obsidian-vault-agent --plugin obsidian-vault-agentHow this skill is triggered — by the user, by Claude, or both
Slash command
/obsidian-vault-agent:book-analyzer [path/to/book.epub or book.pdf][path/to/book.epub or book.pdf]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<Purpose>
Autonomously extracts atomic concepts from EPUB books into Obsidian notes, validates against NotebookLM via autoresearch loop, and extends knowledge. Use for mastering book content.
Extracts knowledge from source notes (papers, posts, books, lectures) into a vault's permanent knowledge base using evidence-based learning techniques.
Builds Wikipedia-style Obsidian vaults from academic PDFs, extracting concepts into linked notes with atomic sentences and citations. Expands existing networks with new papers.
Share bugs, ideas, or general feedback.
<Use_When>
<Do_Not_Use_When>
<Why_This_Exists> Book notes that merely transcribe content are useless — the value is in synthesis. Most book notes in a vault end up sparse because processing a full book manually is exhausting. This skill automates the mechanical work (extraction, splitting, formatting) while delegating the intellectual work (synthesis, assessment, connections) to specialized agents with strict quality constraints. </Why_This_Exists>
<Execution_Policy>
Parse $ARGUMENTS to get the book file path and optional flags.
Argument format:
$ARGUMENTS = "path/to/book.epub" # basic
$ARGUMENTS = "path/to/book.pdf --no-terms" # skip term extraction
$ARGUMENTS = "path/to/book.epub --output ~/Desktop/" # custom output location
Parse logic:
--no-terms (skip concept extraction), --output <dir> (custom output).epub, .pdf, .mobiRun extraction based on format:
For EPUB:
SKILL_DIR="$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")"
# Find skill directory — check common locations
for dir in .claude/skills/book-analyzer ~/.claude/skills/book-analyzer; do
if [ -f "$dir/scripts/extract_epub.py" ]; then SKILL_DIR="$dir"; break; fi
done
WORK_DIR=".book-work-$(date +%s)"
python3 "$SKILL_DIR/scripts/extract_epub.py" "INPUT_PATH" "$WORK_DIR"
For PDF:
WORK_DIR=".book-work-$(date +%s)"
"$SKILL_DIR/scripts/extract_pdf.sh" "INPUT_PATH" "$WORK_DIR"
For MOBI: Convert to EPUB first with ebook-convert (calibre), then run EPUB extraction.
The work directory is created inside the vault root (e.g., .book-work-1709398200/).
Clean it up after the pipeline completes.
After extraction: Read $WORK_DIR/metadata.json to verify success.
PDF fallback: If metadata shows "needs_fallback": true, use the Claude Read tool instead:
Read(file_path="INPUT_PATH", pages="1-20"), then pages="21-40", etc.$WORK_DIR/pages/page_batch_NNN.txtRead metadata.json from the extraction output.
For EPUBs: Chapter structure comes directly from extraction (H1/H2 splitting). Proceed to Stage 3.
For PDFs: Chapter detection depends on extraction quality.
Agent(
subagent_type="general-purpose",
model="haiku",
prompt="Read the following text from the first 5 pages of a book. Identify chapter
boundaries and return a JSON array of {title, start_page, end_page} objects.
If no chapters are detectable, return [{title: 'Full Text', start_page: 1, end_page: LAST}].
TEXT:
[first 5 pages content]"
)
Result: A chapters/ directory with one file per chapter, and updated metadata.json.
Read the agent definition from agents/chapter-analyst.md in the skill directory.
Create analyses directory:
mkdir -p "$WORK_DIR/analyses"
For EACH chapter, launch a parallel agent that WRITES ITS OUTPUT TO A FILE:
Agent(
subagent_type="general-purpose",
model="sonnet",
run_in_background=true,
prompt="You are Chapter Analyst. Follow these instructions exactly:
[INSERT FULL CONTENT OF agents/chapter-analyst.md HERE]
BOOK CONTEXT:
- Title: {title}
- Author: {author}
- This is Chapter {N} of {total_chapters}
- Table of Contents: {chapter_list summary}
CHAPTER FILE TO READ: {path to chapter .md file}
OUTPUT_FILE: $WORK_DIR/analyses/ch{NN}_analysis.md
CRITICAL: Read the chapter file, produce your analysis, then WRITE it to OUTPUT_FILE using the Write tool. Be detailed — include all interesting quotes, concrete examples, and anecdotes. The master agent will read your file later."
)
Parallel execution: Launch ALL chapter agents simultaneously with run_in_background=true.
Wait for all to complete. Verify all analysis files exist in $WORK_DIR/analyses/.
Why file-based: Agent return messages get truncated by context compression. Writing to files preserves full detail — every quote, every example, every nuance. The master agent reads these files directly.
Chapter cap: If more than 50 chapters, batch adjacent chapters (2-3 per agent) to stay within limits.
Result: One analysis file per chapter in $WORK_DIR/analyses/, each containing detailed notes with quotes.
This stage runs the cross-book synthesizer AND section writers ALL IN PARALLEL.
Batching formula: Divide chapters into batches of ~5 chapters each.
M = min(max(ceil(N/5), 1), 10) where N = total number of chapters.
Create sections directory:
mkdir -p "$WORK_DIR/sections"
Read agent definitions from agents/book-synthesizer.md and agents/section-writer.md.
Launch ALL of the following simultaneously (one message, all with run_in_background=true):
Agent(
subagent_type="general-purpose",
model="opus",
run_in_background=true,
prompt="You are Book Synthesizer. Follow these instructions exactly:
[INSERT FULL CONTENT OF agents/book-synthesizer.md HERE]
BOOK METADATA:
- Title: {title}
- Author: {author}
- Total chapters: {N}
ANALYSIS FILES DIRECTORY: $WORK_DIR/analyses/
Read ALL .md files in this directory.
OUTPUT_FILE: $WORK_DIR/synthesis.md
Write your synthesis to this file.
IMPORTANT: Per-chapter detail is handled by section writer agents.
Your job is ONLY cross-chapter patterns: Core Thesis, Deepest Insights,
Chapter Map, Critical Assessment, Cross-Domain Connections."
)
For each batch of ~5 chapters:
Agent(
subagent_type="general-purpose",
model="sonnet",
run_in_background=true,
prompt="You are Section Writer. Follow these instructions exactly:
[INSERT FULL CONTENT OF agents/section-writer.md HERE]
BOOK CONTEXT:
- Title: {title}
- Author: {author}
YOUR ASSIGNED CHAPTER ANALYSES (read ALL of these):
- $WORK_DIR/analyses/ch{NN}_analysis.md
- $WORK_DIR/analyses/ch{NN}_analysis.md
- ... (list all files in this batch)
OUTPUT_FILE: $WORK_DIR/sections/part_{MM}.md
CRITICAL: Read each chapter analysis file. Format ALL their content into
vault-ready markdown preserving every key idea, every quote (in > blockquote
format), every example, and every anecdote. Your job is FORMATTING, not
summarizing. Write output to OUTPUT_FILE."
)
Example for a 20-chapter book (4 section writers):
Result: synthesis.md + sections/part_01.md through sections/part_MM.md, all written in parallel.
The master agent reads all section files and the synthesis, then assembles the final note.
This step is mostly CONCATENATION, not generation. The section writers already produced vault-ready markdown. The master agent's job is:
$WORK_DIR/synthesis.md$WORK_DIR/sections/part_*.md files in order------<!-- QUESTIONS: ... --> HTML comments in section files, deduplicate, add synthesis questions<!-- TERMS: ... --> HTML comments for Stage 5 concept extractionCRITICAL RULE: Chapter note content from section files must be copied VERBATIM into the final note. The assembly agent must NOT summarize, compress, or reduce the section content. If a section file has 15 bullets for a chapter, the final note has 15 bullets for that chapter.
Before proceeding to integration or cleanup, verify the assembled note:
### Ch heading in the final note. Count the headings and compare to total chapters from metadata.> blockquote syntax. Look for " patterns that aren't inside blockquotes.If any check fails, fix the issue using Edit before proceeding. Do NOT delete the work directory until verification passes.
Detect vault context: Check if .obsidian/ directory or CLAUDE.md file exists in the current working directory.
Create book note via create-note.py:
python3 .claude/scripts/create-note.py book "{Title}" author="{Author}" year={YEAR}
Script outputs the created file path. The template handles frontmatter (id, dates, type) automatically.
Fill the book note body using Edit tool on the created file:
processing_status: inbox to frontmatter🏷️Tags line (e.g., #psychology, #startup)[[short-form wikilinks]] for all internal referencesExtract concepts (unless --no-terms flag):
Read agent definition from agents/concept-extractor.md, then:
Agent(
subagent_type="general-purpose",
model="sonnet",
prompt="You are Concept Extractor. Follow these instructions exactly:
[INSERT FULL CONTENT OF agents/concept-extractor.md HERE]
VAULT ROOT: [current working directory]
BOOK NOTE TITLE: {Title}
ALL KEY TERMS FROM CHAPTER ANALYSES:
[INSERT COLLECTED KEY TERMS HERE]
Use create-note.py to create new Term notes:
python3 .claude/scripts/create-note.py term 'Term Name' processing_status=processed
Then Edit the created file to fill in definition, example, tags, and links.
Search the vault for existing terms using Grep and Glob.
Report what was found, created, and skipped."
)
Report results:
[[{Title}]]references/note-templates.md (Section 2)./book-analysis-{slug}.md (or --output dir if specified)<Tool_Usage>
create-note.py, check tool availabilitycreate-note.py creates the skeletonAgent delegation pattern:
agents/ directoryrun_in_background=true (parallel)run_in_background=true (ALL launched in parallel in one message)run_in_background=false (sequential, after assembly)Work directory cleanup: Do NOT delete $WORK_DIR until Stage 4.6 verification passes. If verification fails, the work directory is needed for debugging and fixing.
Finding the skill directory:
The skill lives at .claude/skills/book-analyzer/ (project-level). To find it reliably:
SKILL_DIR=".claude/skills/book-analyzer"
Read agent definitions with: Read(file_path="$SKILL_DIR/agents/chapter-analyst.md")
</Tool_Usage>
<Escalation_And_Stop_Conditions>
<Final_Checklist>
> blockquote markdown syntax$ARGUMENTS