From fiction
Build an EPUB from your fiction project. Compiles chapters, metadata, and optionally a cover image.
npx claudepluginhub howells/fiction --plugin fictionThis skill uses the workspace's default tool permissions.
Build an EPUB file from the current fiction project.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Builds scalable data pipelines, modern data warehouses, and real-time streaming architectures using Spark, dbt, Airflow, Kafka, and cloud platforms like Snowflake, BigQuery.
Builds production Apache Airflow DAGs with best practices for operators, sensors, testing, and deployment. For data pipelines, workflow orchestration, and batch job scheduling.
Build an EPUB file from the current fiction project.
ls chapters/*.md 2>/dev/null | wc -l | tr -d ' 'ls covers/cover.* 2>/dev/null | head -1 || echo "no cover found"chapters/ in orderepub.css (if present)covers/ (if specified)builds/ directory/fiction:build # Build dated epub (archive mode)
/fiction:build --sync # Build for Apple Books sync (preserves highlights)
/fiction:build --cover cover.png # Include specific cover image
/fiction:build /path/to/project # Build specific project
If arguments provided: $ARGUMENTS
Outputs: builds/YYYY-MM-DD/project-name-YYYY-MM-DD.epub
--sync)Outputs: builds/project-name.epub
Look for README.md, chapters/ directory. Support both flat and part-based structures:
Flat structure:
chapters/01-chapter.md
chapters/02-chapter.md
Part-based structure:
part-1-name/chapters/01-chapter.md
part-2-name/chapters/10-chapter.md
Extract from README.md:
Create a stable identifier for the EPUB:
com.author-name.project-name
This identifier is what Apple Books uses to recognize "same book, updated" — preserving highlights and reading position between builds.
Read all markdown files from chapters/ in order:
Look in covers/ for:
cover.png or cover.jpg (default)--cover argument to specifyLook for epub.css in project root. If present, include in epub.
Create a metadata file with the stable identifier:
---
title: "Book Title"
author: "Author Name"
identifier: "com.author-name.book-title"
lang: en-GB
---
Use pandoc to compile:
pandoc chapters/*.md \
--metadata-file=/tmp/metadata.yaml \
-o "builds/project-name.epub" \
--epub-cover-image=covers/cover.png \
--css=epub.css \
--split-level=1 \
--toc \
--toc-depth=1
Key options:
--split-level=1 — Only break chapters on H1 headings (avoids empty pages)--toc — Include table of contents--toc-depth=1 — Only show chapter titles in TOCWrite builds/YYYY-MM-DD/metadata.yaml:
title: "Book Title"
author: "Author Name"
identifier: "com.author-name.book-title"
built: "2026-01-18T21:30:00Z"
chapters: 18
word_count: 75000
cover: "cover.png"
Output build summary:
## Build Complete
**File:** builds/project-name.epub
**Size:** 8.4 MB
**Chapters:** 18
**Word count:** ~75,000
Cover: covers/cover.png included
Styles: epub.css applied
To open in Apple Books:
open -a 'Books' builds/project-name.epub
builds/
├── 2026-01-15/
│ ├── project-name-2026-01-15.epub
│ └── metadata.yaml
└── 2026-01-18/
├── project-name-2026-01-18.epub
└── metadata.yaml
builds/
└── project-name.epub # Always same file, updated in place
For highlights to persist between builds:
identifier field in metadata must stay constant--sync mode for consistent namingHow it works: Apple Books uses the EPUB's dc:identifier (stored in the OPF file) to recognize books. When you import a new build with the same identifier, it updates the existing book rather than adding a duplicate.
Caveat: Highlights are tied to text position. Major edits (adding/removing paragraphs) may shift or orphan highlights in that area. Minor edits (typos, word changes) are fine.
covers/
├── cover-01-concept.png # Early iterations
├── cover-02-revised.png # Refinements
├── cover-final.png # Selected cover
└── cover.png # Symlink or copy of final (used by build)
Store all cover iterations. The build uses cover.png by default.
Requires pandoc for epub generation:
brew install pandoc
--sync for daily reading while writingcovers/ directory is for iterations; cover.png is what gets built--sync modeIf you see blank pages between chapters:
page-break-after: always in epub.css — remove or change to auto\newpage in markdown files--split-level=1 is set (breaks only on H1)Minimal CSS that avoids empty page issues:
body {
font-family: Georgia, serif;
line-height: 1.6;
}
h1 {
page-break-before: auto;
margin-top: 2em;
}
p {
text-indent: 1.5em;
margin: 0;
}
p:first-of-type {
text-indent: 0;
}