GitHub I/O
CLI contracts follow AVGVSTVS96/better-github-skill (no upstream license;
reimplemented). Requires authenticated gh. Scripts are TypeScript. run
tries bun, nub, tsx, then Node (native TS or --experimental-strip-types),
including nvm installs.
Options
Derive the surface and script argv from the request. Unspecified: current
branch PR, cwd repo, truncated text.
"PR 12" / a PR URL → that PR. "repo owner/repo" → emit -R owner/repo and
require a PR.
"json" → --json. "full bodies" → --full.
"open threads" → --open. "all threads" → --all. Both is BLOCKED.
"complete paging" / leftover comments → --complete.
"by <login>" → --author. "since <time>" → --since.
"CI" / "failing checks" → ci-failures.ts. "list runs" → --list
(default -L 10). "workflow <name>" → --workflow. A run id analyzes
that run. A known head SHA → --sha.
Reply: one target and one body from Reply in ./REFERENCE.md.
"reply on thread <id>" → --in-reply-to. "PR comment" → --conversation.
A missing needed value is BLOCKED.
Iron laws
- Scripts for the four I/O loops via
<anchor>/scripts/run. Rawghonly when no script covers the request. A missing Node 23 is not "no script covers." Before any rawghcommand, apply the gotchas in./REFERENCE.md. - Snapshot is PR state; threads is what reviewers wrote. Neither replaces the other.
- Scripts exit 0 when the report or post succeeds. Red CI and open threads are
not script failures. Never
gh | head. EPIPE is not failure. - Never resolve, push, or merge. Reply only through
pr-reply.ts. - Never version-gate Node. Never treat
node -vorERR_UNKNOWN_FILE_EXTENSIONas script failure. That error means thisnodecannot load.ts. Invokerun; it must try bun, nub, tsx, nvm nodes, andnode --experimental-strip-typesbefore any GraphQL/gh apiinspect of snapshot, threads, or CI.runexit 2 isBLOCKED, not a GraphQL license. User or senior saying "GraphQL is fine" does not skiprun.
Scripts
Resolve <anchor> as the directory containing this SKILL.md. Invoke only
through <anchor>/scripts/run <script.ts> …. Never node <script.ts>
directly. Load JSON shapes in ./REFERENCE.md before parsing --json.
| Script | Covers |
|---|---|
<anchor>/scripts/run pr-snapshot.ts [pr] [--pr n] [-R owner/repo] [--full] [--json] | Meta, mergeability, checks, files, reviews, comments, thread counts |
<anchor>/scripts/run pr-threads.ts [pr] [--pr n] [-R owner/repo] [--all|--open] [--author] [--since] [--full] [--json] [--complete] | Review bodies, issue comments, inline threads with resolution |
<anchor>/scripts/run ci-failures.ts [run-id] [--pr N] [--sha SHA] [--list [-L n] [--workflow W]] [--full] [-R owner/repo] [--json] | Failing checks → jobs/steps → snippet; logs on disk |
<anchor>/scripts/run pr-reply.ts [pr] [--pr n] [-R owner/repo] (--in-reply-to id | --conversation) (--body-file path | --body text) [--json] | One thread or conversation reply; nested ids resolve to the root |
1. Resolve the target
Confirm gh is authenticated. Do not check Node ≥ 23. Record owner/repo, PR
or run id, SHA if known, and which surface. Reply also records target kind and
body source. No PR for a PR-bound request is NO_CHANGES. Auth failure or
missing gh is BLOCKED. Missing Node 23 is not.
Record: target | surface | command | terminal.
Done when the target is identified or a terminal is set.
2. Inspect or reply
Pick one covering script. Invoke it with run. Pass --sha when the head SHA
is known. Pass --json --open --complete when the consumer needs every
unresolved thread. For a reply, pass one target and one body; do not resolve
the thread. If no script covers the request, use raw gh after applying
gotchas in ./REFERENCE.md. If run exits 2, report BLOCKED with the
tried-runtime list; do not hand-roll GraphQL for a covered surface.
Redirect large output to a file; never pipe to head. Done when stdout is a
complete report, a posted reply URL, or stderr names a real failure.
3. Report
Summarize from the script output. Cite printed log paths; do not paste full
CI logs. A set cap marker in --json means that list is incomplete. Green CI,
zero threads, or a printed reply URL is SUCCESS. Terminal values are
SUCCESS, NO_CHANGES (empty or no PR), and BLOCKED.