npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

plotos

v0.1.0

Published

A local-first CLI tool for story creation and management

Readme

PlotOS

A local-first CLI tool for story creation and management.

PlotOS helps writers create structured narratives with world-building, character management, conflict graphs, and plot generation.

Features

  • Plain Text, Local-first - All data stored as JSON, works offline
  • BYO API - Bring your own LLM API key (OpenAI, OpenRouter, DeepSeek, etc.)
  • Static Output - Generate shareable HTML plot pages
  • Four Core Schemas - World, Character, Conflict Graph, Plot
  • Narrative Engine - Generate plots from structured data
  • State Machine - Track project status from draft to published

Installation

# Install globally from npm
npm install -g plotos

# Or use with npx (no install required)
npx plotos init my-story

From Source

# Clone or download
git clone https://github.com/plotos/plotos.git
cd plotos

# Install dependencies
npm install

# Build
npm run build

# Link for global use
npm link

Quick Start

# Create a new project
plot init my-story
cd my-story

# Fill in world settings
# Edit memory/canon/world.json

# Add characters
# Edit memory/canon/characters.json

# Define conflicts
# Edit memory/canon/conflict_graph.json

# Check project health
plot doctor

# Validate data
plot validate

# Generate plot
plot build

# Export to HTML
plot export

# Publish to GitHub Pages
plot publish

Commands

plot init [name]

Initialize a new PlotOS project.

plot init my-story
plot init my-story --force  # Overwrite existing

Creates:

my-story/
├── plotos.json              # Project configuration
├── state.json               # Project state
├── memory/canon/            # Canon (locked) settings
│   ├── world.json           # World settings
│   ├── characters.json      # Characters
│   ├── conflict_graph.json  # Conflict graph
│   └── style_card.json      # Style guide
├── workspace/               # Working directory
│   ├── drafts/
│   ├── experiments/
│   ├── notes/
│   └── plot_variants/       # Plot versions
└── dist/                    # Output files

plot doctor

Diagnose project structure and configuration.

plot doctor
plot doctor --fix  # Auto-fix issues

plot validate

Validate project data against schemas.

plot validate
plot validate --strict  # Treat warnings as errors

plot build [version]

Generate plot from canon data.

plot build                    # Generate new version
plot build v002               # Specific version
plot build --model five_act   # Story structure model
plot build --scenes 30        # Target scene count
plot build --no-llm           # Generate without LLM
plot build --force            # Overwrite existing

plot lock / plot unlock

Lock or unlock canon settings.

plot lock                     # Freeze canon
plot lock --reason "Ready for publication"
plot unlock                   # Allow editing

plot export [version]

Export plot to HTML.

plot export                   # Export current version
plot export v002              # Export specific version
plot export --all             # Export all versions
plot export --runtime         # Generate runtime.json

plot publish

Publish to GitHub Pages.

plot publish
plot publish --dry-run        # Preview without publishing

plot preview

Preview exported plot locally.

plot preview
plot preview --port 8080

Project Structure

Canon Layer (memory/canon/)

Authoritative settings that should not be changed after locking.

  • world.json - World rules, systems, stakes, setting
  • characters.json - Character desires, fears, beliefs, arcs
  • conflict_graph.json - Conflict nodes, edges, sets
  • style_card.json - Narrative voice, prose style

Workspace Layer (workspace/)

Draft area for experimentation.

  • drafts/ - Draft content
  • experiments/ - Experimental variations
  • notes/ - Research and notes
  • plot_variants/ - Plot versions (plot_v001.json, etc.)

Publish Layer (dist/)

Generated output for sharing.

  • index.html - Version index
  • plot_v001.html - Plot page
  • runtime.json - Interactive mode config

Configuration (plotos.json)

{
  "name": "my-story",
  "version": "0.1.0",
  "provider": "openrouter",
  "model": "deepseek-chat",
  "api_key_env": "PLOTOS_API_KEY",
  "base_url": "https://openrouter.ai/api/v1",
  "language": "zh-CN",
  "template": "default",
  "generation": {
    "temperature": 0.7,
    "max_tokens": 4096
  }
}

State Machine

Init ──→ Draft ──→ Canon ──→ Published ──→ Interactive
  │        │         │           │             │
  └────────┴─────────┴───────────┴─────────────┘
                    (can iterate back)

| State | Description | |-------|-------------| | Init | Project created, no content yet | | Draft | World/characters/conflict in progress | | Canon | Settings locked, ready for generation | | Published | HTML exported and published | | Interactive | Runtime mode with user interaction |

Schema Overview

World Schema

{
  "schema_version": "1.0",
  "world_id": "w_xxx",
  "title": "Story Title",
  "genre": ["fantasy", "adventure"],
  "premise": {
    "logline": "One-line story summary",
    "theme": "Core theme"
  },
  "axioms": [...],      // World rules
  "systems": [...],     // Power/magic systems
  "stakes": {...},      // What can be lost
  "setting": {...}      // Time, place, factions
}

Character Schema

{
  "schema_version": "1.0",
  "characters": [{
    "character_id": "c_xxx",
    "name": "Character Name",
    "role": "protagonist",
    "core": {
      "desire": "What they want",
      "fear": "What they fear",
      "belief": "Core belief"
    },
    "arc": {...},
    "relationships": [...]
  }]
}

Conflict Graph Schema

{
  "schema_version": "1.0",
  "graph_id": "g_xxx",
  "nodes": [
    { "id": "c_hero", "type": "character" },
    { "id": "goal_truth", "type": "goal" }
  ],
  "edges": [
    { "type": "wants", "from": "c_hero", "to": "goal_truth" },
    { "type": "blocks", "from": "c_villain", "to": "c_hero" }
  ],
  "conflict_sets": [...]
}

Plot Schema

{
  "schema_version": "1.0",
  "plot_id": "p_xxx",
  "structure": {
    "model": "three_act",
    "beats": [...]
  },
  "promises": {
    "reader_promise": [...]
  },
  "scenes": [{
    "scene_id": "s_001",
    "act": 1,
    "goal": "Scene goal",
    "turn": "Turning point",
    "outcome": "Result"
  }],
  "chapter_map": [...]
}

LLM Integration

PlotOS supports any OpenAI-compatible API:

# Set API key
export PLOTOS_API_KEY=your-api-key

# Configure provider in plotos.json
{
  "provider": "openrouter",
  "model": "deepseek-chat",
  "base_url": "https://openrouter.ai/api/v1"
}

Supported providers:

  • OpenAI
  • OpenRouter
  • DeepSeek
  • Anthropic (via OpenRouter)
  • Local models (Ollama, vLLM)

Development

# Development
npm run dev -- init test-story

# Build
npm run build

# Type check
npm run typecheck

License

MIT

Contributing

Contributions welcome! Please read the documentation in /docs for architecture details.