Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2
Project description
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
repoandprojectscopes ghCLI only when usingauth: "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:
| Skill | Purpose |
|---|---|
create-prd |
Generate structured PRDs from feature ideas |
create-tech-spec |
Create codebase-aware technical specs from PRDs |
plan-sync |
Sync specs to GitHub Issues + Projects v2 |
Claude Code Plugin
Install the planpilot plugin directly in Claude Code (the planpilot CLI is installed automatically from PyPI):
claude plugin marketplace add aryeko/planpilot
claude plugin install planpilot@planpilot
Then use:
/planpilot:prd— create a PRD from a feature idea/planpilot:spec— create a tech spec from a PRD/planpilot:sync— generate.plansJSON and sync to GitHub
Agent Self-Install
Tell your agent:
Fetch and follow instructions from https://raw.githubusercontent.com/aryeko/planpilot/main/src/planpilot/skills/INSTALL.agent.md
The agent will install planpilot and all three skills automatically.
Manual Install
Install skills to the open discovery path used by agent platforms that support filesystem skills:
for skill in create-prd create-tech-spec plan-sync; do
mkdir -p ~/.agents/skills/$skill
curl -fsSL "https://raw.githubusercontent.com/aryeko/planpilot/main/src/planpilot/skills/$skill/SKILL.md" \
-o ~/.agents/skills/$skill/SKILL.md
done
Full standalone instructions: src/planpilot/skills/INSTALL.md
Quickstart
1. Generate planpilot.json
planpilot init
The interactive wizard auto-detects your git remote and guides you through provider, target repo, board URL, plan layout, and auth. Or create the config manually:
cat > planpilot.json <<'JSON'
{
"provider": "github",
"target": "your-org/your-repo",
"board_url": "https://github.com/orgs/your-org/projects/1",
"plan_paths": {
"epics": ".plans/epics.json",
"stories": ".plans/stories.json",
"tasks": ".plans/tasks.json"
},
"sync_path": ".plans/sync-map.json"
}
JSON
2. Dry-run (preview changes)
planpilot sync --config ./planpilot.json --dry-run
3. Apply changes
planpilot sync --config ./planpilot.json --apply
4. Multi-epic plans
planpilot supports multi-epic plans natively. Keep all epics/stories/tasks in the configured plan files and run once:
planpilot sync --config ./planpilot.json --apply
CLI commands
planpilot init
| Flag | Default | Description |
|---|---|---|
--output, -o |
planpilot.json |
Output file path |
--defaults |
off | Generate config with auto-detected defaults (no prompts) |
planpilot sync
| Flag | Default | Description |
|---|---|---|
--config |
./planpilot.json |
Path to planpilot.json |
--dry-run |
— | Preview mode (no provider mutations) |
--apply |
— | Apply mode |
--verbose |
off | Enable verbose logging |
planpilot clean
| Flag | Default | Description |
|---|---|---|
--config |
./planpilot.json |
Path to planpilot.json |
--dry-run |
— | Preview which issues would be deleted |
--apply |
— | Execute deletions |
--all |
off | Delete all planpilot-managed issues by label, regardless of current plan hash |
--verbose |
off | Enable verbose logging |
planpilot map sync
| Flag | Default | Description |
|---|---|---|
--config |
./planpilot.json |
Path to planpilot.json |
--dry-run |
— | Preview local sync-map reconciliation |
--apply |
— | Persist reconciled local sync-map |
--plan-id |
auto | Explicit remote plan ID to reconcile |
--verbose |
off | Enable verbose logging |
map sync reconciles local artifacts from provider metadata only; it does not mutate provider items.
In apply mode it writes both the local sync-map and local plan files.
Full CLI reference: docs/modules/cli.md
Plan file schemas
See docs/reference/plan-schemas.md for plan schema examples and docs/modules/plan.md for validation behavior.
A complete working example is in the examples/ directory, including sample rendered issue bodies and a sync-map output.
Documentation
- Start here:
- Architecture and behavior:
- Module implementation details:
- Operations:
Support
- Questions / ideas: use GitHub Discussions
- Bugs / feature requests: open a GitHub Issue
Branding
Branding assets (logo + social preview images) are in assets/branding/navigator/.
Development
Development tasks use poethepoet:
poe lint # ruff check
poe format # ruff format
poe docs-links # validate local markdown links
poe test # pytest -v --ignore=tests/e2e
poe test-e2e # run offline E2E suite
poe coverage # pytest + HTML coverage report
poe coverage-e2e # E2E-only coverage XML
poe typecheck # mypy
poe check # lint + format-check + typecheck + tests
Contributing
See CONTRIBUTING.md for setup and development instructions.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file planpilot-2.5.0.tar.gz.
File metadata
- Download URL: planpilot-2.5.0.tar.gz
- Upload date:
- Size: 148.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab61e76ae5dcd8ec03c65ff5c3a51449592cc71053a3c0b7fca4969ef5c5c9bf
|
|
| MD5 |
2c0ca869aa19aedcca0930eebc6458cf
|
|
| BLAKE2b-256 |
74f3f7eeb215cbaecaf4540e6b78d8f53dd8ea116633dd68517ae5c736281986
|
Provenance
The following attestation bundles were made for planpilot-2.5.0.tar.gz:
Publisher:
release.yml on aryeko/planpilot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
planpilot-2.5.0.tar.gz -
Subject digest:
ab61e76ae5dcd8ec03c65ff5c3a51449592cc71053a3c0b7fca4969ef5c5c9bf - Sigstore transparency entry: 976800045
- Sigstore integration time:
-
Permalink:
aryeko/planpilot@6a002e9456a0ce7b4fe2ea2ef99611151a0f080f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aryeko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6a002e9456a0ce7b4fe2ea2ef99611151a0f080f -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file planpilot-2.5.0-py3-none-any.whl.
File metadata
- Download URL: planpilot-2.5.0-py3-none-any.whl
- Upload date:
- Size: 203.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51f4a37fad560ef58411cd86981d34de522b42ede5ce192886a6befacdf130ce
|
|
| MD5 |
657ff8afb727b681c1cb86a9c0060b7d
|
|
| BLAKE2b-256 |
907e5d8951ac9742653593a62d4fc06bb22a121eef1b8cf3c41f51c7d72416f4
|
Provenance
The following attestation bundles were made for planpilot-2.5.0-py3-none-any.whl:
Publisher:
release.yml on aryeko/planpilot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
planpilot-2.5.0-py3-none-any.whl -
Subject digest:
51f4a37fad560ef58411cd86981d34de522b42ede5ce192886a6befacdf130ce - Sigstore transparency entry: 976800046
- Sigstore integration time:
-
Permalink:
aryeko/planpilot@6a002e9456a0ce7b4fe2ea2ef99611151a0f080f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aryeko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6a002e9456a0ce7b4fe2ea2ef99611151a0f080f -
Trigger Event:
workflow_run
-
Statement type: