Sync local planning files to GitHub Issues.
Project description
Planhub
Planhub is a CLI app that syncs local planning artifacts (plans, issues,
milestones written as .md files) to GitHub Issues via the API.
Goals
- Keep planning artifacts in git and reviewable.
- Generate/update GitHub issues and milestones from local files.
- Make planning conversational: we can edit
.mdfiles and sync later.
How It Works
Planhub keeps planning data next to the code it describes. Each repository gets
a .plan/ folder containing milestones and issues as Markdown files with YAML
front matter. You edit these files like normal docs, then planhub sync maps
them to GitHub issues and milestones.
Installation
Global install from PyPI (recommended for CLI usage). pipx gives you a clean
CLI install without polluting your system Python, and puts planhub on your
PATH:
pipx install planhub
Project-local install with uv (inside your repo). This keeps the tool in a virtual environment for that repo:
uv venv
uv pip install planhub
Commands
planhub init- Creates the standard
.plan/structure in the current repo. - Use
--dry-runto preview the folders that would be created.
- Creates the standard
planhub issue <title>- Creates a new GitHub issue with the given title.
- Requires credentials and a GitHub
remote.origin.url.
planhub sync- Reads
.plan/files and creates or updates GitHub issues and milestones. - Writes the GitHub
numberback into each file after creation. - Sync runs in three phases: parse files, build a sync plan, then apply it.
- Use
--dry-runto validate files without writing changes. - Use
--import-existingto pull existing GitHub issues into.plan/. This requires credentials and a GitHubremote.origin.url. - Creating issues or milestones also requires credentials and a GitHub
remote.origin.url. - Sync never deletes local files. If something can't be identified, it reports an error and skips removal.
- Reads
Credentials
Planhub can reuse your GitHub CLI session or a token stored in the environment.
The simplest path is to authenticate once with gh, and the CLI will fetch a
token automatically.
gh auth login
Alternatively, create a personal access token and export it:
- GitHub → Settings → Developer settings → Personal access tokens.
- Create a fine-grained token for the target repo(s).
- Grant Issues: Read (and Write if you will push updates later).
export GITHUB_TOKEN=ghp_your_token_here
Suggested Data Repo Layout
.plan/
issues/
20260127-backlog-issue.md
milestones/
stage-1/
milestone.md
issues/
issue-001.md
assets/
diagram.png
Front Matter Tips
milestonecan be a title or a number; usemilestone: nullto clear it.- Use
labels: []orassignees: []to remove them on GitHub. state_reasonrequiresstate: "closed".
Development
Setup
Install development dependencies:
uv sync --dev
Pre-commit Hooks
This project uses pre-commit to run code quality checks before commits. Install the hooks:
uv run pre-commit install
The hooks will automatically run on git commit. They check for:
- Code formatting and linting (ruff)
- Trailing whitespace and end-of-file fixes
- YAML, JSON, and TOML syntax
- Merge conflicts and other common issues
To run hooks manually:
uv run pre-commit run --all-files
Version Bumping
This project includes a grow.py script for bumping versions and creating releases:
./grow.py
The script will:
- Read the current version from
pyproject.toml - Show commits since the last tag
- Prompt for the new version
- Update the version in
pyproject.toml - Create a commit with a changelog of commits since the last release
- Create an annotated tag with the new version
- Optionally push commits and tags to the remote repository
The changelog commit includes all commit messages since the last tag, making it easy to see what changed in each release on GitHub.
Next Steps
- Implement the parsing + GitHub sync logic.
- Add CI to validate file formats.
Project details
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 planhub-0.2.2.tar.gz.
File metadata
- Download URL: planhub-0.2.2.tar.gz
- Upload date:
- Size: 88.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f2319d7a3e58bdfede1ad9cadf8c8ac8dbe1ac588305049caa2d133a6e34e3f
|
|
| MD5 |
7375f224f05387923c32904380bdb2f9
|
|
| BLAKE2b-256 |
9a0f6c0e97cea99762a1eb95b8627c81a35ca3f62b866498ab699e4370af03f0
|
Provenance
The following attestation bundles were made for planhub-0.2.2.tar.gz:
Publisher:
release.yml on koradon/planhub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
planhub-0.2.2.tar.gz -
Subject digest:
5f2319d7a3e58bdfede1ad9cadf8c8ac8dbe1ac588305049caa2d133a6e34e3f - Sigstore transparency entry: 930137882
- Sigstore integration time:
-
Permalink:
koradon/planhub@ec2daa9a69a0c1c20438b1e58f0135f23ca377b8 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/koradon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec2daa9a69a0c1c20438b1e58f0135f23ca377b8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file planhub-0.2.2-py3-none-any.whl.
File metadata
- Download URL: planhub-0.2.2-py3-none-any.whl
- Upload date:
- Size: 31.3 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 |
492f8b0eb092d36901558ee9f579386099345dc503d576c45c3c99e4af3a5f14
|
|
| MD5 |
a52c4bd6b6b9b85b9aad789e87315c97
|
|
| BLAKE2b-256 |
812cf291e96731ea2b8441e9a70f3ec50dc800f19d1cccfe5621e18b908540ca
|
Provenance
The following attestation bundles were made for planhub-0.2.2-py3-none-any.whl:
Publisher:
release.yml on koradon/planhub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
planhub-0.2.2-py3-none-any.whl -
Subject digest:
492f8b0eb092d36901558ee9f579386099345dc503d576c45c3c99e4af3a5f14 - Sigstore transparency entry: 930137886
- Sigstore integration time:
-
Permalink:
koradon/planhub@ec2daa9a69a0c1c20438b1e58f0135f23ca377b8 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/koradon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ec2daa9a69a0c1c20438b1e58f0135f23ca377b8 -
Trigger Event:
push
-
Statement type: