From gh-projects
Open or update the issue-linked PR for the active branch, advance the board Status across the PR lifecycle, surface the PR's check state, and offer a guard-protected non-squash merge once checks are green. Use when the user says "promote the PR", "open the PR for this branch", "move to in review", or "merge when green". Dry-by-default — previews the PR + Status + merge intent and mutates nothing until you re-run with --force. Does NOT route issues or create linked branches (route-issue) and does NOT plan sprints / set dates (plan-sprint); does NOT author specs (spec-ops).
How this skill is triggered — by the user, by Claude, or both
Slash command
/gh-projects:promote-pr --owner <org> --number <project#> --repo owner/name --issue <n> (add --force after the dry run)--owner <org> --number <project#> --repo owner/name --issue <n> (add --force after the dry run)claude-opus-4-8This skill is limited to the following tools:
Bash${CLAUDE_PLUGIN_ROOT}/hooks/guard.shThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Open/update the issue-linked PR for the active branch, advance the board
Open/update the issue-linked PR for the active branch, advance the board
Status across the PR lifecycle, surface the PR's check state, and offer a
guard-protected non-squash merge once checks are green. This skill is a thin
orchestrator over the deterministic engine — every load-bearing operation is a
checked-in verb in ${CLAUDE_PLUGIN_ROOT}/lib/gh.py, dispatched through
${CLAUDE_PLUGIN_ROOT}/lib/engine.sh's dry-by-default / --force rail. Leave
no decision logic in this prose; orchestrate the verbs and render their output.
Let ENGINE=${CLAUDE_PLUGIN_ROOT}/lib/engine.sh. The PreToolUse guard above
(hooks/guard.sh) is active only while this skill runs (AC-25): it
hard-blocks any --squash and any prod deploy/release without provably-green
checks, and fails open on everything else. Never work around it.
--force, the engine prints the intended write
command and mutates nothing — PR, Status, and merge all stay previews
(AC-20). Only --force after the user confirms.Relates to #N — never
Closes/Fixes/Resolves (auto-close stays the prod-time board-status job's
job, AC-30). The open_or_update_pr verb rejects a smuggled-in closer (exit 2).Backlog < Ready < In Progress < In Review < On Staging < Done (advance_status); it never sets intake fields (route-issue)
or scheduling fields (plan-sprint), and never regresses Status (AC-17).pr_check_state reads green, with the reason stated (AC-18).--merge or --rebase (merge_pr), never
--squash (AC-19) — and the guard hard-blocks --squash even if attempted.GH_APP_TOKEN, or APP_ID+APP_PRIVATE_KEY),
never GITHUB_TOKEN (AC-28). The token is never printed.You need the org login (--owner), the project number (--number), the
owner/name repo (--repo), and the issue number (--issue) whose
linked branch this PR promotes. The active head branch is the issue's
authoritative linked branch (created by route-issue); the base is the
repo's default branch unless the user names another. If any input is missing, ask
with AskUserQuestion. Confirm the App token is available (GH_APP_TOKEN or
APP_ID+APP_PRIVATE_KEY); the engine fails with a usage error (exit 2) if not.
Preview the three intents — open/update PR, the Status target, the merge intent — without mutating anything:
# (a) PR open/update preview (non-closing Relates to #N)
bash "$ENGINE" open-pr --repo <owner/name> --head <linked-branch> \
--base <default-branch> --number <issue> [--draft]
# (b) PR check state (read-only — runs even in dry mode)
bash "$ENGINE" pr-checks --repo <owner/name> --pr <pr#>
Then determine the Status target from the PR's lifecycle and present it as a preview:
| PR lifecycle state | Status target (monotonic) |
|---|---|
| draft PR | hold In Progress (do not advance) |
| ready (non-draft) PR | In Review |
| merged on green | On Staging is the consuming pipeline's job, not this skill |
Show the user the full preview verbatim: the PR action (created/updated) +
its Relates to #N body, the green/red/pending check verdict, the Status
target, and the merge intent. If checks are not green, state plainly that the
merge step is withheld and why (AC-18) — do not offer merge.
Use AskUserQuestion to confirm (this mutates the repo + board). Run each verb
without --force first (dry preview), then re-run the identical command with
--force appended to execute. A no-diff re-run is a clean no-op (AC-33).
(a) Open/update the non-closing PR (open-pr — edits in place if a PR for the
branch already exists, never a duplicate-PR 422):
bash "$ENGINE" open-pr --repo <owner/name> --head <linked-branch> \
--base <default-branch> --number <issue> [--draft] --force
(b) Advance board Status monotonically to the PR-lifecycle target
(advance-status — advance_status writes only a forward move; an item already
at/past the target is a no-op, no write — AC-17). Use the target from the §2
lifecycle table — In Review on a ready PR; hold In Progress while draft:
# ready (non-draft) PR -> In Review
bash "$ENGINE" advance-status --owner <org> --number <project#> --repo <owner/name> --issue <issue> --to "In Review" --force
# draft PR -> hold at In Progress (no advance past it)
bash "$ENGINE" advance-status --owner <org> --number <project#> --repo <owner/name> --issue <issue> --to "In Progress" --force
(c) Merge only on green. Offer the merge only when pr-checks reads
green (re-confirm with the read-only check verb, which runs even in dry mode):
bash "$ENGINE" pr-checks --repo <owner/name> --pr <pr#> # must read "green"
On the user's explicit confirm and a green verdict, perform a non-squash merge:
# non-squash ONLY — --merge (or --rebase); the guard hard-blocks --squash
bash "$ENGINE" merge-pr --repo <owner/name> --pr <pr#> --method merge --force
Never pass --squash (the verb rejects it, exit 2; the guard blocks it too). If
checks are red/pending, do not run merge-pr — re-check after CI settles.
State: the PR action (created/updated) + number/URL and its non-closing
Relates to #N link, the check verdict (green/red/pending), the Status
target written (or held, with the monotonic reason if no advance), and the merge
outcome (merged via --merge/--rebase, or withheld because checks were not
green). If you re-ran on an already-promoted PR, confirm it was a no-op (PR edited
in place, no Status rewrite, no re-merge).
--force only after the user confirms.gh to mutate the PR/board directly for a Project write — go through
engine.sh so the --force rail and App-token path hold. (gh pr checks is a
read; the engine runs it even in dry mode.)Relates to #N, never Closes/Fixes/Resolves
(AC-30). Closure stays the prod-time board-status job.--squash (AC-19) — the guard
enforces both.0 ok · 2 usage / no App token · 3 PR or project not found ·
1 unexpected.npx claudepluginhub zakattack9/agentic-coding --plugin gh-projectsGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.