planpilot

Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2.
⭐ If planpilot helps you manage your roadmaps, consider giving it a star!
Why planpilot?
Managing roadmaps through GitHub's UI works for small projects, but breaks down fast: manually creating dozens of issues, linking parent/child hierarchies, setting up blocked-by dependencies, and keeping project board fields in sync is tedious and error-prone. Scripting the GitHub API directly means dealing with pagination, rate limits, idempotency, and GraphQL complexity.
planpilot treats your roadmap as code. Define epics, stories, and tasks in JSON files, commit them alongside your source code, and let planpilot handle the rest — creating issues, wiring up sub-issue hierarchies, setting blocked-by relations, and populating project board fields. It's idempotent (safe to rerun), supports dry-run previews, and works across multiple epics in a single run.
What it does
planpilot takes structured plan files and turns them into a fully linked project board:
flowchart LR
A["roadmap.md"] --> B["epics.json\nstories.json\ntasks.json"]
B -->|planpilot| C["GitHub Issues\n+ Projects v2"]
C --> D["Epic / Story / Task\nissue types"]
C --> E["Sub-issue\nhierarchy"]
C --> F["Blocked-by\ndependencies"]
C --> G["Project fields\nstatus, priority,\niteration, size"]
- One-way sync: local plan files -> GitHub
- Idempotent: safe to rerun -- updates existing issues via markers
- Dry-run first: preview all changes before applying
- Multi-epic: sync multiple epics natively in one run
- Provider-agnostic: adapter pattern supports GitHub today, with Jira/Linear planned
- Async-first: built on asyncio for fast, concurrent sync operations
Architecture
planpilot follows SOLID principles with a modular, provider-agnostic design:
src/planpilot/
├── core/ # Runtime domains (auth/config/contracts/engine/plan/providers/renderers)
├── cli/ # CLI parser/app/commands and persistence helpers
├── sdk.py # SDK composition root and public facade
└── __init__.py # Public API exports
Core domains provide business logic, and the SDK composes runtime pieces. This keeps provider and renderer implementations swappable without changing engine internals.
See docs/design/architecture.md for the full architecture guide.
Requirements
- Python 3.11+
- GitHub token with
repo and project scopes
gh CLI only when using auth: "gh-cli"
Installation
# Install pipx if you don't have it
brew install pipx && pipx ensurepath # macOS
# or: sudo apt install -y pipx && pipx ensurepath # Debian/Ubuntu
# Install planpilot
pipx install planpilot
pipx installs CLI tools in isolated environments -- avoids PEP 668 / "externally managed environment" errors on macOS Homebrew and system Python.
Alternative: pip (inside a virtualenv)
python3 -m venv .venv && source .venv/bin/activate
pip install planpilot
From source (Poetry)
poetry install
Try it now
See planpilot in action without any configuration or GitHub token — the built-in example runs a fully offline dry-run:
git clone https://github.com/aryeko/planpilot.git && cd planpilot
pipx install . # or: pip install .
planpilot sync --config examples/sync-workflow/planpilot.json --dry-run
planpilot - sync complete (dry-run)
Plan ID: 3832d3ffce22
Target: example-org/example-repo
Board: https://github.com/orgs/example-org/projects/1
Items: 6 total (1 epic, 2 stories, 3 tasks)
Created: 6 (1 epic, 2 stories, 3 tasks)
Sync map: /absolute/path/to/examples/sync-workflow/output/sync-map-sample.json.dry-run
[dry-run] No changes were made
Install Agent Skills
planpilot ships three agent skills that form a complete product workflow: