✨ Story Skills
Agent Skills for planning, tracking, and drafting fiction in markdown.
Story Skills gives agents a shared project format for fiction: a story bible, character files, worldbuilding notes, factions, artifacts, plot arcs, scene state, continuity questions, promises/payoffs, timelines, and chapter drafts. Everything is plain markdown with YAML frontmatter, packaged as standard Agent Skills with Codex and Claude Code plugin support.
The companion CLI treats the story bible as a checkable contract: a continuity engine catches dead characters walking, payoffs that land before their setup, unfired Chekhov guns, and stale story state — deterministically, before a reader ever could.
Install it as a Codex or Claude Code plugin, with the Agent Skills CLI, or copy the
skills/folders into any agent that supportsSKILL.md.
🚀 Quick Start
# Codex plugin
codex plugin marketplace add danjdewhurst/story-skills
codex plugin add story-skills@story-skills
# Claude Code plugin (type these inside a Claude Code session, not a shell)
/plugin marketplace add danjdewhurst/story-skills
/plugin install story-skills@story-skillsFor compatible SKILL.md agents, you can also install the bundle with the Agent Skills CLI:
npx skills add danjdewhurst/story-skills
# Or with Bun
bunx skills add danjdewhurst/story-skillsThen ask "Start a new story" to scaffold the project.
🔎 The Continuity Engine
Long-range consistency is the thing language models are worst at and prompts cannot fix. Story Skills makes it deterministic: character deaths, promises/payoffs, open questions, scene casts, and durable knowledge/object state live in frontmatter, and story continuity treats contradictions like a compiler treats type errors.
examples/the-unraveled-thread/ is a deliberately broken mystery. It passes story validate and story links cleanly — every file is well-formed — but the story itself doesn't hold together:
$ story continuity examples/the-unraveled-thread
Continuity check failed: 4 errors, 3 warnings
error: chapters/chapter-04.md lists edran-vale, who died in chapter-02; move posthumous appearances to mentions
error: continuity/promises/the-broken-compass.md pays off in chapter-02 before it is planted in chapter-03
error: continuity/questions/who-burned-the-mill.md resolves in chapter-02 before it is introduced in chapter-03
error: continuity/state.md knowledge-state[0] references missing chapter chapter-05
warning: chapters/chapter-03.md POV character nessa-thorn is not listed in characters
warning: continuity/promises/the-sealed-letter.md was planted in chapter-01, 3 chapters ago, and has no payoff yet
warning: continuity/state.md object-state[0] status active conflicts with worldbuilding/artifacts/vales-compass.md status destroyedThese findings are exact, file-addressed, and reproducible — CI asserts them on every commit. Intentional flashbacks and posthumous appearances stay legal via the chapter mentions field. story doctor and story next fold the same checks into prioritized repair actions.
📦 Installation
Codex
# Add the marketplace
codex plugin marketplace add danjdewhurst/story-skills
# Install the plugin
codex plugin add story-skills@story-skillsFor local skill authoring without a plugin install:
git clone https://github.com/danjdewhurst/story-skills.git
cp -r story-skills/skills/* ~/.agents/skills/
# Or install to a specific repo as repo-scoped skills
cp -r story-skills/skills/* .agents/skills/Codex detects repo and user skills automatically. The plugin install is still the recommended path for this bundle.
Claude Code
# Add the marketplace
/plugin marketplace add danjdewhurst/story-skills
# Install the plugin
/plugin install story-skills@story-skillsGitHub Copilot (VS Code)
VS Code with Copilot discovers skills from multiple directories:
git clone https://github.com/danjdewhurst/story-skills.git
# Copy skills to your project (any of these work)
cp -r story-skills/skills/* .github/skills/
cp -r story-skills/skills/* .agents/skills/
# Or install globally
cp -r story-skills/skills/* ~/.copilot/skills/Skills can activate when your request matches a skill description, or you can invoke them manually.
Cursor
Cursor supports the SKILL.md standard:
git clone https://github.com/danjdewhurst/story-skills.git
cp -r story-skills/skills/* .agents/skills/Windsurf
Windsurf discovers skills from workspace and global directories:
git clone https://github.com/danjdewhurst/story-skills.git
# Copy skills to your project
cp -r story-skills/skills/* .windsurf/skills/
# Or install globally
cp -r story-skills/skills/* ~/.codeium/windsurf/skills/Cascade can invoke a matching skill automatically. You can also use @skill-name to invoke one directly.
Gemini CLI
Gemini CLI supports the same SKILL.md format via the Agent Skills standard:
# Install all skills globally
gemini skills install https://github.com/danjdewhurst/story-skills.git
# Or install a specific skill
gemini skills install https://github.com/danjdewhurst/story-skills.git --path skills/story-init
gemini skills install https://github.com/danjdewhurst/story-skills.git --path skills/character-management
gemini skills install https://github.com/danjdewhurst/story-skills.git --path skills/worldbuilding
gemini skills install https://github.com/danjdewhurst/story-skills.git --path skills/plot-structure
gemini skills install https://github.com/danjdewhurst/story-skills.git --path skills/chapter-writing
gemini skills install https://github.com/danjdewhurst/story-skills.git --path skills/revision-continuity
gemini skills install https://github.com/danjdewhurst/story-skills.git --path skills/story-maintenance
# Or link locally after cloning
git clone https://github.com/danjdewhurst/story-skills.git
gemini skills link story-skills/skillsGemini discovers the skills and can activate them when your request matches a skill description.
OpenCode
The skills use the same SKILL.md format that OpenCode supports natively:
git clone https://github.com/danjdewhurst/story-skills.git
# Copy skills to your project
cp -r story-skills/skills/* .opencode/skills/
# Or install globally
cp -r story-skills/skills/* ~/.config/opencode/skills/OpenCode also searches common skill paths such as .claude/skills/, so compatible project-level skills can be discovered automatically.
Other platforms
These skills follow the open Agent Skills standard: SKILL.md files with YAML frontmatter. If your agent supports the Agent Skills CLI, install the bundle directly:
npx skills add danjdewhurst/story-skills
# Or with Bun
bunx skills add danjdewhurst/story-skillsUse --skill <name> to install only specific skills, or --agent <name> to target a supported agent. You can also copy the skill folders into any compatible agent's skills directory.
For non-agent use:
- Claude.ai / ChatGPT Projects — add the SKILL.md and reference files as project knowledge
- Any LLM API — include skill content in system prompts
- Manual use — the templates, workflows, and story structure are model-agnostic
🛠️ Skills
| Skill | What it does | Try saying |
|---|---|---|
| story-init | Scaffolds the story bible, folders, and registries | "Start a new story" |
| character-management | Creates character profiles with relationships, traits, arcs, and family trees | "Create a character" |
| worldbuilding | Builds locations and systems: magic, politics, technology, religion, and more | "Design a magic system" |
| plot-structure | Plans arcs with structures like three-act, hero's journey, Save the Cat, and kishotenketsu | "Create a plot arc" |
| chapter-writing | Drafts chapters through an outline-first workflow that pulls from story context | "Write the next chapter" |
| revision-continuity | Revises drafts, audits continuity, and keeps character state, timeline, and arc changes consistent | "Continuity-check chapter 3" |
| story-maintenance | Runs deterministic CLI checks for validation, continuity, reports, indexing, links, word counts, import, and export | "Validate my story project" |
For stronger prose, pair chapter-writing with better-writing. It adds voice calibration, anti-generic writing checks, and a final prose-quality pass, and installs the same way:
npx skills add forjd/better-writing🧰 Companion CLI
The optional story CLI handles deterministic project maintenance while the skills handle the creative workflow.
bun install
bun run story --helpThe package also exposes a Node-compatible bin with no runtime dependencies. It is not on the npm registry yet, so run it straight from GitHub:
npx --yes --package github:danjdewhurst/story-skills story --helpThe CLI needs Node 18 or newer.
For copied-skill installs, story-maintenance includes a bundled scripts/story.js fallback that agents can run with Node.
The CLI is for deterministic maintenance only. Agents should write story content directly to markdown files, not create project-local build or generator scripts to emit the story.
| Command | Purpose |
|---|---|
story init "The Last Ember" | Scaffold a story project with the standard markdown layout |
story add character "Sera Voss" | Create entity files for characters, locations, systems, factions, artifacts, arcs, chapters, scenes, questions, promises, and glossary terms |
story rename character sera-voss "Sera Vale" | Rename an entity and update kebab-case references |
story remove promise old-setup | Remove an entity and scrub metadata references |
story migrate [path] | Upgrade a project to the current schema |
story validate [path] | Check required files, schema version, YAML frontmatter, registries, and word-count warnings |
story reindex [path] | Rebuild registry tables from the current markdown files |
story wordcount [path] --write | Count chapter prose and update chapter frontmatter plus the chapter registry |
story links [path] | Check character, location, chapter, and arc cross-references/backlinks |
story continuity [path] | Check deterministic continuity contracts: deaths, promises/payoffs, questions, casts, and durable state |
story import draft.md --title "The Lost Coast" | Split an existing manuscript into a new story project and suggest entity candidates |
story report [path] --actionable | Summarize inventory and optionally include next actions |
story next [path] | Recommend the next deterministic writing or maintenance actions |
story doctor [path] | Show health checks with actionable repair steps |
story export [path] --out manuscript.md | Combine chapters into a single manuscript markdown file |
story build [path] --format epub | Build disposable markdown, EPUB, or DOCX artifacts in dist/ |
EPUB and DOCX builds target plain prose: *italic* and **bold** become italic and bold runs, scene-break lines (***, ---) become a * * * separator paragraph, and other markdown structure such as lists or tables is flattened to text. The markdown export keeps chapter text as-is.
story rename and story remove update entity ids in frontmatter reference fields and in markdown link targets. They never edit prose, so a character called "Port" can be renamed without touching the word "port" in chapter text.
Commands that change a frontmatter value regenerate that file's frontmatter from the parsed values, which drops any YAML comments in it. Files whose values do not change are left untouched.
For a complete starter transcript, read docs/first-20-minutes.md. For the project contract, read docs/schema-v2.md and schemas/story.schema.json.
🤖 Write A Book Via Pull Requests
A story project with deterministic checks is a story project an agent can advance unattended. The templates/github/ workflows turn a story repository into a self-drafting book:
story-checks.ymlrunsstory validate,story links, andstory continuityon every push and pull request, so a chapter PR cannot merge with a continuity contradiction.draft-next-chapter.ymlruns Claude Code on a schedule: it asksstory nextfor the next deterministic action, drafts the next chapter with the chapter-writing skill, updates scene records and continuity state, runs the maintenance checks, and opens a pull request for review.
Copy both files into .github/workflows/ in the repository that holds your story project, add an ANTHROPIC_API_KEY secret, and review one chapter PR per morning.
GitHub does not start story-checks.yml for a pull request opened with the built-in GITHUB_TOKEN, so the draft workflow runs the same checks itself after drafting. Pass a personal access token as github_token if you want the checks workflow to run on those PRs as well.
📥 Import An Existing Manuscript
Most writers don't start from a blank page. story import reverse-engineers a Story Skills project from work in progress:
story import draft.md --title "The Lost Coast" --genre mysteryIt splits the manuscript on chapter headings (or imports a directory of chapter files), creates the full project layout with accurate word counts and registries, and prints recurring proper-name candidates so an agent can follow up with story add character and story add location to build out the bible.
📁 Project Structure
Running story-init creates this layout:
my-story/
├── story.md # Story bible — title, genre, themes, POV, tense
├── characters/
│ └── _index.md # Character registry
├── worldbuilding/
│ ├── _index.md # World overview
│ ├── locations/
│ ├── systems/
│ ├── factions/
│ └── artifacts/
├── plot/
│ ├── _index.md # Arc overview
│ ├── arcs/
│ └── timeline.md
├── scenes/
│ └── _index.md # Machine-readable scene registry
├── continuity/
│ ├── state.md # Character, object, and knowledge state
│ ├── questions/
│ │ └── _index.md
│ └── promises/
│ └── _index.md
├── glossary/
│ ├── _index.md
│ └── terms/
└── chapters/
└── _index.md # Chapter registry
⚙️ How It Works
Every story element is a markdown file with YAML frontmatter. The skills cross-reference those files so the project stays consistent:
story.mdis the top-level bible read by all skillsstory.mdincludesschema-version: 2so the CLI can detect incompatible project formats- Every entity file is named by a kebab-case identifier (e.g.,
sera-voss,chapter-01) _index.mdfiles serve as registries for each domain- Relationships and references are maintained bidirectionally
- Scene records and continuity state make character knowledge, object ownership, and setup/payoff tracking durable
- Story content is created directly as markdown; generated build scripts are not part of the project format
📖 Examples
- Read The Cormorant Tide, a full story project generated with Story Skills.
- Read Pippa and the Borrowed Star, a complete children's Christmas story (6 chapters, 2,183 words) generated with Story Skills.
- Explore
examples/the-last-ember/for a complete fantasy example: three characters, two locations, a magic system, a plot arc with foreshadowing, and a drafted first chapter. - Explore
examples/harbor-of-second-light/for a near-future coastal mystery example with memory technology, a posthumous witness arc, populated continuity state, and a drafted first chapter. - Explore
examples/the-unraveled-thread/for a deliberately broken project that demonstrates every class of finding the continuity engine reports.
🧪 Development And Releasing
Development uses Bun for tests and coverage:
bun run test
bun run test:coverage
bun run test:examples
bun run check:metadataThe copied-skill fallback CLI is generated from the package entrypoint. After changing CLI source, rebuild and check it before release:
bun run build:fallback
bun run check:fallback
node skills/story-maintenance/scripts/story.js --helpCodex uses .codex-plugin/plugin.json as its plugin version source. Claude Code uses .claude-plugin/plugin.json. Every published change needs a new version in both files and in package.json so installed users receive updates; keep marketplace entries unversioned to avoid duplicate version state.
Cut a release with the release script, which bumps all three files, runs the CI checks, commits chore: release X.Y.Z, tags vX.Y.Z, pushes, and creates a GitHub release with generated notes. It requires a clean main that matches origin/main and a logged-in gh:
bun run release patch # or minor, major, or an explicit version like 1.2.0
bun run release patch --dry-run # run the checks and print the plan without changing anythingDistribution metadata lives in .claude-plugin/ for Claude Code and .codex-plugin/ plus .agents/plugins/marketplace.json for Codex. The plugins/story-skills symlink is intentional: Codex marketplace entries must point at a child plugin directory, so the symlink exposes the repo-root plugin without duplicating skills/.