https://github.com/fadymondy/gh-pms
GitHub Issues as a project-management system for Claude Code — plans, features, bugs, evidence-gated lifecycle, PR-driven review. Backed by GitHub primitives.
https://github.com/fadymondy/gh-pms
claude-code claude-code-plugin github-issues orchestra-mcp pms project-management workflow
Last synced: about 1 month ago
JSON representation
GitHub Issues as a project-management system for Claude Code — plans, features, bugs, evidence-gated lifecycle, PR-driven review. Backed by GitHub primitives.
- Host: GitHub
- URL: https://github.com/fadymondy/gh-pms
- Owner: fadymondy
- License: mit
- Created: 2026-04-28T21:17:01.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-04-28T23:10:28.000Z (about 1 month ago)
- Last Synced: 2026-04-29T01:13:06.435Z (about 1 month ago)
- Topics: claude-code, claude-code-plugin, github-issues, orchestra-mcp, pms, project-management, workflow
- Language: Shell
- Size: 79.1 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Security: .github/SECURITY.md
Awesome Lists containing this project
README
# Github PMS Plugin
**GitHub Issues as a project-management system for Claude Code.**
A Claude Code plugin marketplace that turns GitHub Issues into the source of truth for your project: plans, features, bugs, evidence-gated lifecycle, PR-driven review. Inspired by Orchestra MCP and Studio PMS, backed by GitHub's first-class primitives — **Issue Types**, **Projects v2**, **Milestones**, **sub-issues**, and **relationships** — not just labels.
## Why
Most teams use GitHub Issues as a dumb backlog. `gh-pms` adds the structure that real project management needs:
- **Plans** = Milestones with due dates and native progress bars
- **Features / Bugs** use GitHub's native **Issue Types** when available, fall back to labels otherwise
- **Status** tracked in a Projects v2 board's `Status` field (when configured) or `status:*` labels
- **Sub-issues** for plan → feature breakdown, **dependency relationships** (`depends on`, `blocks`, `related to`, `duplicate of`)
- **Evidence-gated lifecycle** — 5 gates with required `## Sections` (file paths, test results, self-review)
- **WIP limits**, **cooldowns**, **kind-specific skips** (bugs auto-skip the docs gate)
- **PR-driven review** — `Closes #N` keyword + `AskUserQuestion` approval + `gh pr merge` closes the loop
Everything lives natively in GitHub. Open the Issues, Milestones, or Projects tab and you see exactly where the project is.
## What's new in v0.8
See [CHANGELOG.md](CHANGELOG.md#080) for the full list. Highlights:
- gh-test-plan skill — generate testcase sub-issues from acceptance criteria (#17, PR #31)
- gh-search skill — ad-hoc issue queries beyond gh-status (#16, PR #30)
- gh-bulk skill — safe batch label / close / reassign / set-severity (#15, PR #29)
See `CHANGELOG.md` for the full v0.8.0 entry.
### From v0.7: (previous release)
See [CHANGELOG.md](CHANGELOG.md#070) for the full list. Highlights:
- gh-metrics skill — time-in-status, gate failure rate, throughput (#13, PR #27)
- Optional AI reviewer on Gate 4 (sub-agent code review before user approval) (#12, PR #26)
- Wire Effort field end-to-end (gh-feature input + gh-status velocity) (#11, PR #25)
See `CHANGELOG.md` for the full v0.7.0 entry.
### From v0.6: (previous release)
See [CHANGELOG.md](CHANGELOG.md#060) for the full list. Highlights:
- gh-triage skill — accept/reject/dedupe the type:request inbox (#8, PR #23)
- CI gate on Gate 4 — refuse review-ready when checks are red (#7, PR #22)
- Per-repo config in .github/gh-pms.yaml (#6, PR #21)
See `CHANGELOG.md` for the full v0.6.0 entry.
### From v0.5: (previous release)
Two skills that close adoption gaps the v0.4 release made obvious — sessions starting blind to the issue tracker, and releases requiring a manual edit-bump-tag dance.
- **`gh-context`** ✨ — compact session-start summary of WIP, pipeline, milestones, recent closes, deferred requests. Auto-runs via the new `SessionStart` hook so the agent picks up where the last session left off (#9).
- **`gh-release`** ✨ — bundle PRs merged since the last tag into a structured CHANGELOG entry, bump `plugin.json`, refresh the README banner, tag, and (optionally) create a GitHub release in one shot. Idempotent; refuses without an anchor (#5).
See [CHANGELOG.md](CHANGELOG.md) for the full list.
### From v0.4: severity first-class
Severity is now a first-class dimension on **every** issue kind, not just bugs. A P0 feature blocking a launch is meaningfully different from a polish item — that signal was previously lost. Closes #2.
- **Canonical scale** — `workflows/default.yaml#severities` is now the single source of truth (`default: medium` + four values, each mapped to a `severity:*` label and a Project v2 `Severity` field option). Per-repo severity scales become a config-only change.
- **`gh-feature`** ✨ — accepts an optional `severity` on every kind (not just hotfix). Applied as label + Project field. Hotfixes still default to `critical`.
- **`gh-task`** — sub-issue tasks inherit the parent feature's severity by default; override when the task is meaningfully more or less urgent. Checkbox tasks inherit implicitly.
- **`gh-bug`** — references the canonical scale instead of defining its own. Same defaults, no behavior change.
- **`gh-status`** — within each Status bucket, issues are sorted Critical → Low so urgent items surface first regardless of kind.
- **Templates** — `feature.md`, `chore.md`, `testcase.md` gain a `## Severity` section. `plan.md` / `prd.md` stay exempt (they aggregate child severities).
Backwards compatible — existing issues without a `severity:*` label remain valid, and skills called without `severity` get `medium`.
### From v0.3: `gh-push` skill + branching policy
The "every feature must end with a linked PR" rule is baked into the lifecycle:
- **`gh-push` skill** — One command to commit, push, open PR with `Closes #N`, post Gate 4 self-review evidence, ask the user to approve, and `gh pr merge`. Mirrors the popular `/push` pattern but PR-aware and lifecycle-integrated. Supports `--message`, `--no-merge`, `--admin`, `--squash` / `--merge` / `--rebase`, `--dry`, `--force`.
- **Branching policy** — `workflows/default.yaml#branching` defines `protected_base` (default: `main` / `master`), `pr_required_kinds` (feature / bug / hotfix / chore / testcase), `branch_template` (default: `{kind_short}/{number}-{slug}`), and `pr_must_close_issue: true`. The rule is enforced in three places: `gh-current` auto-creates the branch on start, `gh-advance` Gate 1 refuses if HEAD is on the protected base, and `gh-push` refuses to ship from the protected base.
- **`gh-current`** records `branch` + `base` in the per-issue state file so `gh-push` finds them later. The "🚧 Work started" comment mentions the branch name.
- **`gh-advance`** Gate 1 has a clear rescue-recipe error if work is on the wrong branch. One-off legacy state can opt out with the `[gh-pms: branch-exception]` marker in the issue body.
### From v0.2: GitHub-native primitives
- **Issue Types** (orgs only): `Feature`, `Bug`, `Task` set via GraphQL, not labels — when the org has them enabled
- **Projects v2** integration: `gh-init --with-project` provisions a `gh-pms` board with `Status`, `Severity`, `Effort`, `Service` custom fields
- **Milestones for plans**: `gh-plan` creates a milestone; `gh-breakdown` attaches every child via `--milestone`; closes auto-progress
- **`gh-relate` skill**: encode `depends_on`, `blocks`, `related_to`, `duplicate_of` between issues
- **Auto-detection**: `gh-init` queries the org for available features and provisions only what's missing; user-account repos gracefully fall back to labels
- **Unified status setter**: `lib/ghcall.sh set-status ""` updates label + project field atomically
See [CHANGELOG.md](CHANGELOG.md) for the full list.
## Install
```bash
# Add the marketplace (one-time)
/plugin marketplace add fadymondy/gh-pms
# Install the plugin
/plugin install gh-pms@gh-pms
```
Requires:
- **GitHub MCP** — already configured in Claude Code (auth via OAuth or PAT)
- **`gh` CLI** — for batch label / project / milestone ops: `brew install gh && gh auth login`
- **`gh` `project` scope** — only if you want Projects v2 integration: `gh auth refresh -s project`
- **`jq`** — for JSON parsing in hooks: `brew install jq`
## Quick start
In any GitHub repo:
```bash
# 1. Bootstrap (creates labels + templates; optionally creates a Project)
/gh-pms:gh-init # labels + templates only
/gh-pms:gh-init --with-project # also create the gh-pms Projects v2 board
# 2. From now on, just talk normally — the plugin auto-classifies prompts
# and ensures every actionable request becomes an issue.
```
Examples:
```text
"Plan the migration of auth flow to the bridge"
→ /gh-pms:gh-plan creates milestone + tracker issue
→ /gh-pms:gh-breakdown creates feature sub-issues, attaches them to the milestone
"Add a /entities endpoint that returns sentiment scores"
→ /gh-pms:gh-feature creates issue, sets Issue Type "Feature" (if org), adds to project
→ /gh-pms:gh-current sets Status: In Progress
→ work happens, gates open, PR opens with Closes #N
→ user approves, PR merges, issue auto-closes
"Build the launch-blocking SSO refresh — this is P0"
→ /gh-pms:gh-feature with severity: critical
→ severity:critical label + Severity = Critical on the project board
"The login page redirects to 404 after 2FA"
→ /gh-pms:gh-bug creates issue, sets Issue Type "Bug", severity:medium
"#42 depends on #38 and #39"
→ /gh-pms:gh-relate updates body sections on all three, posts cross-reference comments
```
## What gets created in your repo
After `gh-init`:
```text
.github/
├── ISSUE_TEMPLATE/
│ ├── feature.md
│ ├── bug.md
│ ├── chore.md
│ ├── plan.md
│ ├── prd.md
│ ├── request.md
│ └── testcase.md
└── PULL_REQUEST_TEMPLATE.md
```
Labels (always created — used directly when native features unavailable, otherwise as a visible-at-a-glance secondary signal):
```text
type: feature, bug, hotfix, chore, plan, prd, testcase, request
status: todo, in-progress, ready-for-testing, in-testing,
ready-for-docs, in-docs, documented, in-review, blocked, done
severity: critical, high, medium, low
svc: app, bridge, studio, edge, db, devops
```
GitHub native (provisioned when available + opted in):
```text
Issue Types (org-level): Feature, Bug, Task — set via GraphQL on creation
Projects v2 (--with-project): gh-pms board with fields Status / Severity / Effort / Service
Milestones (always): one per plan, with optional due date + auto-progress
```
## The lifecycle
```text
todo ──(free)──► in-progress
│
Gate 1 (## Summary, ## Changes [files], ## Verification)
▼
ready-for-testing ──(free)──► in-testing
│
Gate 2 (## Summary, ## Results, ## Coverage)
▼
ready-for-docs
│
(free) │ [auto-skip if bug/hotfix/testcase]
▼
in-docs ──Gate 3──► documented
│
Gate 4 (## Summary, ## Quality, ## Checklist [files], PR with Closes #N)
▼
in-review
│
Gate 5 (user approval via AskUserQuestion)
▼
done
```
## Skills
| Skill | Mirrors |
| ------------------------- | --------------------------------------------- |
| `/gh-pms:gh-init` | (bootstrap) |
| `/gh-pms:gh-plan` | `pms_create_plan` (now creates milestone) |
| `/gh-pms:gh-breakdown` | `pms_breakdown_plan` (attaches to milestone) |
| `/gh-pms:gh-feature` | `pms_create_feature` (sets native type) |
| `/gh-pms:gh-bug` | `pms_create_bug_report` (sets native type) |
| `/gh-pms:gh-task` | `pms_create_task` |
| `/gh-pms:gh-current` | `pms_set_current_feature` (auto-creates feature branch) |
| `/gh-pms:gh-advance` | `pms_advance_feature` (Gate 1 refuses from protected base) |
| `/gh-pms:gh-push` ✨ | (new in v0.3) — commit + push + PR + Gate 4 + Gate 5 in one shot |
| `/gh-pms:gh-validate` | `pms_validate_gates` |
| `/gh-pms:gh-review` | `pms_request_review` + `pms_submit_review` |
| `/gh-pms:gh-relate` | (new in v0.2) — manage issue relationships |
| `/gh-pms:gh-request` | `pms_create_request` |
| `/gh-pms:gh-status` | `pms_list_features` (reads project board) |
| `/gh-pms:gh-context` ✨ | (new in v0.5) — session-start summary |
| `/gh-pms:gh-release` ✨ | (new in v0.5) — version bump + tag + release |
| `/gh-pms:gh-triage` ✨ | (new in v0.5) — drain the type:request inbox |
| `/gh-pms:gh-reopen` ✨ | (new in v0.7) — re-enter a done issue |
| `/gh-pms:gh-metrics` ✨ | (new in v0.7) — flow analytics + velocity |
| `/gh-pms:gh-bulk` ✨ | (new in v0.8) — safe batch ops |
| `/gh-pms:gh-search` ✨ | (new in v0.8) — ad-hoc issue queries |
| `/gh-pms:gh-test-plan` ✨ | (new in v0.8) — testcases from acceptance |
## Hooks
| Event | Behavior |
| ------------------------------------------- | ------------------------------------------------------------------------- |
| `SessionStart` | Injects a `gh-context` summary so the agent isn't blind on a new session |
| `UserPromptSubmit` | Classifies the prompt, injects a context reminder for the agent |
| `PreToolUse` on `mcp__github__create_pull_request` | Blocks PR creation if `Closes #N` is missing from the body |
| `Stop` | Surfaces stale in-progress issues at end of turn |
## Programmatic guardrails
- **WIP limit** — One in-progress issue per assignee
- **Gate cooldown** — 30s minimum between transitions on the same issue (prevents fake batch-advancement)
- **Kind-specific skips** — Bugs/hotfixes/testcases skip Gate 3 (docs)
- **Branching policy** (v0.3) — Feature work must land on a feature branch, not on `main` / `master`. `gh-current` auto-creates the branch; `gh-advance` Gate 1 refuses from the protected base; `gh-push` refuses to ship from the protected base. Bootstrap commits with no issue number are exempt.
- **PR enforcement** — Every feature must end with a PR containing `Closes #N` so merge auto-closes the issue. Gate 4 requires it; `gh-push` injects it automatically.
- **CI gate on Gate 4** (v0.5+) — `documented → in-review` refuses if any required PR check is failing or still pending. `lib/check-pr-checks.sh` is the source of truth. Override only with `--ignore-checks ""`, which records the reason in a `## Check overrides` section of the evidence comment for audit.
- **User-only Gate 5** — Only `gh-push` Step 5 (or `gh-review`'s Phase 2) can move to `done`, and only after `AskUserQuestion` approval
- **Native primitives preferred** — Issue Types, Project Status field, and Milestones are used when available; labels stay as a fallback and visible-at-a-glance signal
## Configuration
The plugin's defaults live in [`plugins/gh-pms/workflows/default.yaml`](plugins/gh-pms/workflows/default.yaml). To override per repo, drop a `.github/gh-pms.yaml` in the repo (an annotated example lives at [`plugins/gh-pms/templates/gh-pms.yaml.example`](plugins/gh-pms/templates/gh-pms.yaml.example) — `gh-init --customize` copies it for you).
The merge is shallow at the top-level key: any section you set in your override **replaces** its default counterpart wholesale. To extend a list, copy the defaults into your override and add yours.
Inspect the merged result anytime:
```bash
${CLAUDE_PLUGIN_ROOT}/lib/load-config.sh 0 | jq .
```
Common overrides:
- **Severity scale** — replace the `severities` block to use blocker/high/medium/nit instead of the default critical/high/medium/low
- **Service taxonomy** — swap `github_features.project_fields[Service].options` to your team's repo set; `gh-init bootstrap-labels` creates the matching `svc:*` labels automatically
- **Gate evidence** — add or remove required sections per gate (e.g. add a `Threat model` section to Gate 1 for security-sensitive repos)
- **Branching policy** — change `protected_base` or `branch_template` to fit non-`main` defaults
- **Custom kinds** — add a new issue kind beyond feature/bug/hotfix/chore/testcase/plan/prd/request
## License
MIT — see [LICENSE](LICENSE)
## Author
[Fady Mondy](https://github.com/fadymondy)