From pr-jangler
PR Jangler GitHub-to-queue sync. Use when the orchestrator dispatches the discovery sweep (on cadence or empty queue) or when the user runs 'prj-discover' for manual debug.
How this skill is triggered — by the user, by Claude, or both
Slash command
/pr-jangler:prj-discoverThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill is the GitHub-state synchronizer for the PR Jangler module. One invocation reads the configured `prj_repo` via `gh`, diffs its open-PR set against the persisted queue at `{project-root}/_bmad-output/pr-workflow/state.json`, and writes back additive changes: new PRs land at phase `Discovered`, closed PRs flip to `Archived`, fresh comments bump `new_comments_since_triage` and queue a `...
scripts/__pycache__/gh_client.cpython-314.pycscripts/__pycache__/reconcile.cpython-314.pycscripts/__pycache__/run.cpython-314.pycscripts/gh_client.pyscripts/reconcile.pyscripts/run.pyscripts/tests/__pycache__/test_gh_client.cpython-314.pycscripts/tests/__pycache__/test_reconcile.cpython-314.pycscripts/tests/__pycache__/test_run.cpython-314.pycscripts/tests/test_gh_client.pyscripts/tests/test_reconcile.pyscripts/tests/test_run.pyThis skill is the GitHub-state synchronizer for the PR Jangler module. One invocation reads the configured prj_repo via gh, diffs its open-PR set against the persisted queue at {project-root}/_bmad-output/pr-workflow/state.json, and writes back additive changes: new PRs land at phase Discovered, closed PRs flip to Archived, fresh comments bump new_comments_since_triage and queue a prj-triage --mode comment follow-up, and PRs idle longer than 14 days get needs_retriage: true. Per-PR cache directories are created on first discovery with a meta.json snapshot. Rate-limit aware: defers cleanly if GitHub's core quota dips below 100 remaining.
Act as a careful diffing librarian. Never silently drop a PR or a comment. Treat additive writes as the contract: existing phases are only flipped to Archived (closed upstream) or annotated with needs_retriage (idle); the rest of the state machine is owned by the phase skills.
scripts/run.py) resolve from the skill root.{project-root}/... resolves from the project working directory.[modules.prj] in {project-root}/_bmad/config.toml.prj-orchestrator's state_io module (imported via sys.path); this skill never touches state.json directly.Load configuration from {project-root}/_bmad/config.toml (the [modules.prj] block). The required key is prj_repo (owner/name). If absent, exit early with status misconfigured and a clear run-log entry; do not call gh.
Execute the sweep:
python3 scripts/run.py
That single script handles the full sweep: rate-limit check, gh calls, reconciliation, atomic state save, per-PR cache creation, run-log append. Flags:
--dry-run compute the diff and log the would-be changes, do not write state or cache--verbose emit progress diagnostics to stderr--project-root <path> override autodetectSee python3 scripts/run.py --help for full detail.
Three Python modules, each with a single concern. Determinism lives in the scripts; the LLM activation context exists so the orchestrator's Skill-tool dispatch resolves cleanly when the cadence fires.
| Concern | Lives in |
|---|---|
| Shared state I/O (atomic load, validate, save, runlog) | state_io (imported from prj-orchestrator/scripts) |
gh CLI wrapping: list, view, diff-stats, rate-limit | scripts/gh_client.py |
| Pure-function reconciliation (state-vs-GitHub diff) | scripts/reconcile.py |
| Orchestration: config, sweep, cache writes, runlog | scripts/run.py |
The sibling import is intentional: state ownership belongs to prj-orchestrator, and rewriting it here would fork the contract.
This skill writes to:
{project-root}/_bmad-output/pr-workflow/state.json (via state_io.save_state, atomic){project-root}/_bmad-output/pr-workflow/prs/{pr_number}/meta.json (created on first discovery; never overwritten silently after that){project-root}/_bmad-output/pr-workflow/logs/{YYYY-MM-DD}.jsonl (append-only run-log)This skill reads from:
{project-root}/_bmad/config.toml (config){project-root}/_bmad-output/pr-workflow/state.json (prior queue state)gh (open PRs, comment payloads, diff stats, rate-limit)Codified in scripts/reconcile.py; summarized here for activation review.
phase: "Discovered", contributor_login from author.login, next_action: {skill: "prj-triage", mode: "pr"}, seen_comment_ids set to whatever ids the PR already carries.new_comments_since_triage is bumped by the delta count; last_action_at advances. If the PR's phase is past initial triage (anything other than Discovered or Triaged), next_action flips to {skill: "prj-triage", mode: "comment"}. Otherwise the existing prj-triage --mode pr action wins.Archived, next_action → null. Skill skips PRs already at Archived.last_action_at older than 14 days) — needs_retriage: true set. The orchestrator picks up the flag on the next heartbeat via its existing priority bump.Before any other gh call, the script invokes gh api rate_limit and reads resources.core.remaining. If remaining < 100, the sweep is deferred: a run-log entry with status: "deferred-rate-limit" is appended, state is left untouched, and the script exits 0. The orchestrator's next cadence fire will retry.
state_io.save_state. Direct file writes to state.json are forbidden.Smoke-test against a configured project (requires gh auth):
python3 scripts/run.py --dry-run --verbose
Expected on a fresh project with PRs open: exit 0, run-log entry with status: "dry-run", report.new_prs listing every open PR number. No state changes on disk.
Run the unit tests (no gh calls; all subprocess invocations mocked):
python3 -m unittest discover scripts/tests
npx claudepluginhub delorenj/pr-jangler --plugin pr-janglerGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.