Dashboard view of all open (non-draft) PRs across OmniNode-ai repos — shows CI status, mergeable state, and groups PRs by readiness
Install
npx skillscat add omninode-ai/omniclaude/list-prs Install via the SkillsCat registry.
List PRs
Overview
Scans all open, non-draft PRs across OmniNode-ai repos and prints a grouped dashboard showing
CI status, mergeable state, and review decision. PRs are grouped into five buckets:
READY TO MERGE, FAILING, PENDING, CONFLICTS, and NO CI RUN. Use --repo to focus on one
repo or --ready-only to filter to actionable PRs only. This skill is read-only: it fetches
data via gh but makes no changes to any repo or PR.
Announce at start: "I'm using the list-prs skill to scan open PRs."
Quick Start
/list-prs
/list-prs --repo omniclaude
/list-prs --ready-only
/list-prs --repo omnibase_core --ready-only
/list-prs --include-draftsRepos Scanned (Default)
| Short name | GitHub slug |
|---|---|
| omniclaude | OmniNode-ai/omniclaude |
| omnibase_core | OmniNode-ai/omnibase_core |
| omnibase_infra | OmniNode-ai/omnibase_infra |
| omnibase_spi | OmniNode-ai/omnibase_spi |
| omniintelligence | OmniNode-ai/omniintelligence |
| omnimemory | OmniNode-ai/omnimemory |
| omnidash | OmniNode-ai/omnidash |
| onex_change_control | OmniNode-ai/onex_change_control |
omninode_infra is excluded by default. Pass --repo omninode_infra to include it explicitly.
Execution Steps
Resolve repo list: If
--repois given, resolve it to the fullOmniNode-ai/<repo>
slug (accepting either the short name or the full slug). Otherwise use the default list above.Fetch PR data: For each repo, run:
gh pr list \ --repo OmniNode-ai/<repo> \ --state open \ --json number,title,author,headRefName,isDraft,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,createdAt,url \ --limit 50Use ONLY the exact fields listed above — do not add
baseRepository,headRepository,
or any other fields. TheghCLI available in this environment does not support all GraphQL
fields and will fail with "Unknown JSON field" if extras are added.Fallback: If the
ghversion does not supportmergeStateStatus(returns "Unknown JSON
field"), retry the query without it. In that case, fall back tomergeable == "CONFLICTING"
for CONFLICTS classification (the pre-v1.1.0 behavior).If
--include-draftsis NOT set, filter out any PR whereisDraft == true.Classify each PR using the rules in the Classification section below.
If
--ready-only: discard all PRs except those in the READY TO MERGE bucket.Fetch changed files for CONFLICTS PRs: For each PR in the CONFLICTS bucket (capped
at the first 10 PRs), fetch changed files:gh pr diff --repo OmniNode-ai/<repo> --name-only <pr_number>Store the first 8 file paths per PR. If more than 8 files are changed, note the overflow
count (e.g.,... and 4 more files). Ifgh pr difffails, skip file listing for that PR
and continue.Print output using the format in the Output Format section below.
Print summary line at the end with totals per bucket.
PR Classification
Assign each PR to exactly one bucket (checked in this order):
| Bucket | Condition |
|---|---|
| READY TO MERGE | mergeable == "MERGEABLE" AND all required checks passed AND reviewDecision in ("APPROVED", null, "") |
| CONFLICTS | mergeStateStatus == "DIRTY" (actual merge conflicts). If mergeStateStatus is unavailable (fallback mode), use mergeable == "CONFLICTING" instead. This distinguishes real file conflicts from PRs that are merely blocked by reviews or policies. |
| FAILING | Not CONFLICTS AND any required check has conclusion == "FAILURE" or conclusion == "TIMED_OUT" |
| PENDING | Not CONFLICTS AND at least one required check is in progress or queued (no failures) |
| NO CI RUN | statusCheckRollup is empty or null AND not CONFLICTS |
CI status helpers (apply to required checks only — checks where isRequired == true):
def required_checks(pr):
return [c for c in (pr.get("statusCheckRollup") or []) if c.get("isRequired", False)]
def ci_status(pr):
checks = required_checks(pr)
if not checks:
return "no_ci"
if any(c.get("conclusion") in ("FAILURE", "TIMED_OUT") for c in checks):
return "failing"
if any(c.get("status") in ("IN_PROGRESS", "QUEUED", "WAITING", "PENDING") for c in checks):
return "pending"
if all(c.get("conclusion") == "SUCCESS" for c in checks):
return "green"
return "no_ci"If mergeable == "UNKNOWN", treat as PENDING (GitHub is still computing mergeability).
Output Format
=== Open PRs — OmniNode-ai (2026-02-23) ===
--- READY TO MERGE (2) ---
omniclaude #247 jonah/omn-2345-fix-hook-timeout CI: green Approved
omnibase_core #183 jonah/omn-2290-pydantic-v2-upgrade CI: green (no review)
--- FAILING (1) ---
omniintelligence #91 jonah/omn-2301-drift-classifier CI: failing Approved
failing checks: quality, test
--- PENDING (3) ---
omnibase_infra #134 jonah/omn-2355-kafka-dlq CI: pending (no review)
omnibase_infra #133 jonah/omn-2340-session-store CI: pending (no review)
omnidash #47 jonah/omn-2360-analytics-panel CI: pending (no review)
--- CONFLICTS (1) ---
omnibase_spi #28 jonah/omn-2200-spi-refactor CI: green (no review)
changed files:
src/omnibase_spi/protocols/handler.py
src/omnibase_spi/protocols/registry.py
tests/unit/test_handler.py
--- NO CI RUN (1) ---
omnimemory #62 jonah/omn-2290-ingestion-rewrite CI: none (no review)
TOTAL: 8 open PRs — 2 ready, 1 failing, 3 pending, 1 conflicts, 1 no CIColumn widths:
- Repo name: left-aligned, padded to 18 chars
- PR number: right-aligned, 4 chars (
#247) - Branch name: left-aligned, truncated to 45 chars if longer
- CI badge: one of
CI: green,CI: failing,CI: pending,CI: none - Review:
Approved,Changes requested,(no review),Review required
For FAILING PRs, print a second indented line listing the names of the failing checks
(comma-separated). Limit to the first 5 check names; append ... if more.
For CONFLICTS PRs, print indented lines showing changed files (fetched in step 5). Format:
- First line:
changed files:(6-space indent) - Each file:
<filepath>(8-space indent) - Show at most 8 files per PR; if more, append
... and N more files - If file fetch failed or returned empty, print
(files unavailable)instead
If a bucket is empty, omit its section entirely from the output.
If --ready-only is set, only the READY TO MERGE section is printed (plus the summary line).
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--repo |
string | (all default repos) | Short name or full slug of a single repo to scan |
--ready-only |
bool | false | Print only READY TO MERGE PRs |
--include-drafts |
bool | false | Include draft PRs in all buckets |
Error Handling
| Situation | Action |
|---|---|
gh pr list fails for one repo |
Print [WARN] <repo>: gh fetch failed — skipping under that repo section; continue |
| All repos fail | Print error and exit |
gh not authenticated |
Print actionable message: gh auth login or check GH_TOKEN |
| No open PRs found in any repo | Print No open PRs found across scanned repos. |
See Also
review-all-prsskill — runs local-review on every open PR branch (heavy workflow)merge-sweepskill — merges all READY TO MERGE PRsauto-mergeskill — merges a single PR with a Slack HIGH_RISK gatepr-watchskill — watches a single PR until CI passes or fails