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
First Run (Required)
Run planhub setup immediately after installation to create the global config
at ~/.planhub/config.yaml (created only if missing):
planhub setup
Without this setup step, sync defaults and other CLI behavior may be missing.
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 setup- Creates the global config file at
~/.planhub/config.yaml(if missing). - Use
--dry-runto preview what would be created.
- Creates the global config file at
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. - Imports existing GitHub issues into
.plan/when credentials and a GitHubremote.origin.urlare available. - Prints explicit operation counts for import/create/update/archive/delete.
- Writes the GitHub
numberback into each file after creation. - GitHub is the source of truth for issue state during sync.
- GitHub is also the source of truth for milestone
stateduring sync; local milestone files are reconciled from GitHub before archive moves run. - For existing issues, sync does not push local
stateorstate_reasonto GitHub; it reconciles those fields from the GitHub response. - Sync runs in three phases: parse files, build a sync plan, then apply it.
- Use
--dry-runto validate files without writing changes. - Use
--verbosefor path-level planned changes, or--compactfor concise output. CLI flags override config. - Creating issues or milestones also requires credentials and a GitHub
remote.origin.url. - Closed synced root issues are archived under
.plan/archive/issuesby default (or deleted whensync.closed_issues.policy: deleteis configured). - Milestone issues remain inside their milestone folder. When
milestone.mdhasstate: "closed", sync moves the whole milestone directory to.plan/archive/milestones. If set back tostate: "open", sync moves that directory back under.plan/milestones.
- 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".
Config
~/.planhub/config.yamland.plan/config.yamlare layered (repo overrides global).- Set
sync.behavior.verbositytocompact(default) orverbose.
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.
License
Planhub is licensed under the GNU Affero General Public License v3.0
(AGPL-3.0). See LICENSE for the full text.
Next Steps
- Implement the parsing + GitHub sync logic.
- Add CI to validate file formats.
Metadata
Release files for planhub 0.3.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| planhub-0.3.4.tar.gz | 108.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| planhub-0.3.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 149.9 kB
Release files / planhub-0.3.4.tar.gz
| Download URL | planhub-0.3.4.tar.gz |
|---|---|
| Size | 108.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
75e9a6edaafa9a8160674b4b4eac876a3c4421c6140bf336a24d3d6b2783a6a3
|
|
BLAKE2b-256 checksum How to use checksums |
ef64dd0f31cd7909953f03471cdde20a554c3c1e85b7626df5e98d9b42712387
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency logRelease files / planhub-0.3.4-py3-none-any.whl
| Download URL | planhub-0.3.4-py3-none-any.whl |
|---|---|
| Size | 41.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4a12bed40e010fa23aee8881525af4bf9e353972501c680547276624c116b3d9
|
|
BLAKE2b-256 checksum How to use checksums |
fcc10007437c1aa7500546acaf5fdedc2f8c4e6a600d1efb95f54773fae5eecb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency logSecurity for planhub 0.3.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for planhub-0.3.4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.