Agent skill

CI Watch

by nubjs in nubjs/nub

Watch GitHub Actions CI correctly with the gh CLI — block until a run / PR check rollup is TRULY terminal, then trust the exit code.

MITAuto-check passedDevOps & Cloud

Install CI Watch

skills CLI
$ npx skills add nubjs/nub --skill ci-watch -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install nubjs/nub ci-watch --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/nubjs/nub.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/ci-watch .claude/skills/ci-watch && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
ci-watch
GitHub stars
4.4k
Token cost
~2.2k tokens
SKILL.md length
1,038 words
Files
1
Skills in repo
31
Repo updated
First seen
Licence
MIT

At a glance

Watch GitHub Actions CI correctly with the gh CLI — block until a run / PR check rollup is TRULY terminal, then trust the exit code.

  • Works in 3 steps: Enqueue: append… → Watch: the orchestrator runs node… → Landing agents PUSH-THEN-EXIT — they…
  • Tasks that involve CI/CD
  • SKILL.md covers The pitfall: raw watchers exit…, The blessed tool:… and Who runs the watcher
  • Calls gh and node

What it does

CI Watch is an agent skill from nubjs/nub. Watch GitHub Actions CI correctly with the gh CLI — block until a run / PR check rollup is TRULY terminal, then trust the exit code. Invoke (via the Skill tool) whenever you need to wait on CI after REQUESTING a pull-request run (gh pr edit <n --add-label ci — PR CI is opt-in, so a push starts nothing), after a push to main, or after a tag, and act on the result (merge-on-green, release-on-green, fail-fast on red). Encodes the premature-exit pitfall (raw gh run watch / gh pr checks --watch exit 0 while the run is…

Its SKILL.md is about 2.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in DevOps & Cloud, covering CI/CD and Pull requests. It works with GitHub Actions. The repository describes itself as: The fast all-in-one Node.js toolkit. The licence is MIT.

When your agent uses it

  • Tasks that involve CI/CD
  • Tasks that involve Pull requests

Example prompts

  • “/ci-watch”

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Enqueue: append {"pr":N,"branch":"…","thread":"…","note":"…"} (optional "hold":true) to .frizz/merge-queue.jsonl. Enqueue UNHELD only once…
  2. Watch: the orchestrator runs node scripts/merge-cascade.ts --max-minutes 40 with run_in_background: true. It gates positively on the…
  3. Landing agents PUSH-THEN-EXIT — they push, request CI with gh pr edit --add-label ci, and report pushed , CI requested, queued. They never…

What it can do on your machine

Read from SKILL.md and the folder at commit 568e73a. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • gh
    • node

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use gh, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

CI Watch loads about 2.2k tokens when it runs. Until then it costs about 217 tokens; SKILL.md has 1,038 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~217
When it runs · the whole SKILL.md, loaded when a task matches
~2.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from nubjs/nub at commit 568e73a, republished under its MIT licence (© nubjs). 1,038 words, ~2,242 tokens.

Download SKILL.mdSave it as .claude/skills/ci-watch/SKILL.md (or your agent's skills folder).
name
ci-watch
description
Watch GitHub Actions CI correctly with the gh CLI — block until a run / PR check rollup is TRULY terminal, then trust the exit code. Invoke (via the Skill tool) whenever you need to wait on CI after REQUESTING a pull-request run (`gh pr edit <n> --add-label ci` — PR CI is opt-in, so a push starts nothing), after a push to main, or after a tag, and act on the result (merge-on-green, release-on-green, fail-fast on red). Encodes the premature-exit pitfall (raw `gh run watch` / `gh pr checks --watch` exit 0 while the run is still QUEUED with no jobs registered, and exit non-zero on a transient API blip) and the blessed fix: `scripts/ci-watch.ts`, which waits for the target to EXIST, polls authoritative terminal status, fails fast on the first failing check, and exits with a status the orchestrator can trust. Run it as a detached run_in_background task.
metadata.internal
true

Watching CI with the GitHub CLI

The pitfall: raw watchers exit early

gh run watch <id> --exit-status and gh pr checks <pr> --watch are not safe to arm right after a push / tag / PR-open:

  • Premature exit while QUEUED. With no jobs registered yet, gh sees "nothing in progress" and returns exit 0 even though the run is still queued.
  • Transient errors read as failure. A mid-watch HTTP 401: Bad credentials (token refresh) or a 5xx exits non-zero, indistinguishable from a real CI failure.
  • No native fix — --interval only tunes the poll cadence.

Never trust a raw watcher's exit code alone. Re-verify terminal status with gh run view <id> --json status,conclusion (done only when status == "completed") or gh pr view <pr> --json statusCheckRollup (done only when every item is terminal). And always fail-fast — act on the first failing check, never wait for all checks to finish.

The blessed tool: scripts/ci-watch.ts

Blocks until the target is truly terminal, then exits with a trustworthy status. Dogfoods nub; runs under plain Node too.

bash
nub  scripts/ci-watch.ts --run <run-id> [--repo o/r] [--timeout <min>]
node scripts/ci-watch.ts --pr  <number> [--repo o/r] [--timeout <min>]
  • --run <run-id> — watch a workflow run (polls gh run view --json status,conclusion,jobs).
  • --pr <number> — watch a PR's check rollup (polls gh pr view --json statusCheckRollup,…).
  • --repo <owner/repo> — defaults to the current repo.
  • --timeout <minutes> — wall-clock cap before giving up as pending (default 45).
  • --required <names> — comma-separated branch-protection check names to gate on (e.g. --required "CI gate"). Success fires the instant every required check is green; a ghost or a non-required check — pending or failed — never blocks, matching branch-protection semantics. Prefer it when you know the required check name.
  • --no-progress <minutes> — how long an unchanged incomplete set (all named checks green, only a ghost left) may sit before exiting 4 STUCK-but-safe (default 8).

What it fixes: waits for the target to EXIST (not-found / no-jobs-yet is "keep polling," never "done"); polls authoritative terminal state; fails fast on the first FAILURE/CANCELLED/TIMED_OUT/ STARTUP_FAILURE; never hangs on a ghost; tolerates transient gh/API errors (retried with exponential jittered backoff, 10s → cap 60s, 90s unauthenticated).

The ghost check — why a strict "all checks terminal" gate hangs

GitHub occasionally registers a check-run that never reports a status: PENDING, nameless, forever. A watcher waiting for every rollup item to be terminal blocks indefinitely even though every real check is green. So a nameless / never-terminating non-required check does not block a green verdict: once every named check is green and the incomplete set has been unchanged for --no-progress minutes, the watcher exits 4 (STUCK-but-safe) and the caller --admin merges. A named pending check is never treated as a ghost, so a real in-flight check is never green-lit early.

Exit-code contract
codemeaning
0completed AND all green
1a check/job failed (the summary names which + the URL)
2required/named checks still NOT green after --timeout (genuinely stuck)
3usage / target-unresolvable / unrecoverable error
4STUCK-but-safe — required/named checks all green, but a ghost check will never terminate; safe to --admin merge (the caller decides)

The final stdout line is a single self-describing summary, e.g. CI-WATCH run 27972328590: SUCCESS (25 job(s) green), CI-WATCH pr 73: FAILURE — check "Test (ubuntu-latest, node 22.13)" → FAILURE (https://…), or CI-WATCH pr 327: STUCK — required/named checks GREEN (51), 1 non-terminal ghost/non-required check(s): (unnamed); safe to --admin merge.

NEVER pipe the watcher — a pipe discards the verdict you gate on

The exit code IS the contract, and a pipeline throws it away: in ci-watch.ts … | tail -20, $? is tail's status, so a FAILED CI reads as SUCCESS. The pipe also buffers stdout until the pipeline ends, so the log stays empty while the watcher runs.

bash
# WRONG — $? is tail's, a red CI looks green, and no interim output
node scripts/ci-watch.ts --pr 604 --repo nubjs/nub | tail -25; echo "exit=$?"

# RIGHT — redirect, then gate on the watcher's OWN status
node scripts/ci-watch.ts --pr 604 --repo nubjs/nub > /tmp/ci604.log 2>&1; rc=$?
tail -15 /tmp/ci604.log; echo "exit=$rc"

main() warns on stderr when it detects a piped stdout (fd 1 is a FIFO for | cmd, not for > file), but redirect by default rather than relying on the warning. Bash ${PIPESTATUS[0]} / zsh ${pipestatus[1]} recover the real status if a pipe is unavoidable.

Cross-check the rollup regardless of what the watcher says. Read gh pr view <pr> --json statusCheckRollup,mergeStateStatus directly and act on any FAILURE. A watcher that has produced nothing for a long stretch is a suspect, not a status.

For a merge-queue drain, prefer scripts/merge-cascade.ts (it gates positively and merges on green); reach for ci-watch.ts when you need to block on one run/PR and branch on the result.

Show full SKILL.md (345 more words)Show less

Who runs the watcher

run_in_background behaves the same for the orchestrator and for a sub-agent: a backgrounded Bash command persists across turns and re-invokes its launcher on exit. Both patterns below are valid.

Merge-on-green (the default). The orchestrator runs the blocking watcher as its own run_in_background Bash task:

  1. Enqueue: append {"pr":N,"branch":"…","thread":"…","note":"…"} (optional "hold":true) to .frizz/merge-queue.jsonl. Enqueue UNHELD only once the PR's FINAL head is pushed AND gh pr edit <n> --add-label ci has requested a run against it — a stale head can be green-but-wrong, and an unrequested one never goes green at all, so the queue would hold it until the cascade times out.
  2. Watch: the orchestrator runs node scripts/merge-cascade.ts --max-minutes 40 with run_in_background: true. It gates positively on the required CI gate (present + SUCCESS) + mergeable, merges --squash --admin, ff-pulls, dequeues, exits → re-invokes the orchestrator. It shares ci-watch's ghost carve-out (scripts/lib/ci-rollup.ts), so a still-running or failed REQUIRED gate always blocks and a red PR is never mis-merged.
  3. Landing agents PUSH-THEN-EXIT — they push, request CI with gh pr edit <n> --add-label ci, and report pushed <sha>, CI requested, queued. They never watch.

Self-contained landing agent (one agent traces push→merge): push the branch; request the run with gh pr edit <n> --add-label ci; launch node scripts/merge-cascade.ts --max-minutes 40 (or ci-watch.ts) for its OWN PR via run_in_background: true; end its turn; it is re-invoked when the command exits, reports merged/red, and iterates. Do not preempt a landing agent's background watch by checking CI yourself and merging manually mid-trace — that impatience is what breaks the flow.

Foreground chunk loop (fallback only) — for an agent that must actively iterate and cannot rest:

bash
# Bash tool: foreground (NOT run_in_background), timeout: 570000  (9.5 min, under the 600000 cap)
nub scripts/ci-watch.ts --pr <N> --chunk          # --chunk caps the watch ~9 min and exits 2 with "RERUN to continue" if still pending
#   exit 0 = green → act    exit 1 = red → fix + re-push    exit 2 = pending → RE-RUN the SAME command    exit 3 = error

While it exits 2, call it again — each chunk completes within the cap (no kill, no orphan). Blocking in the sub-agent's foreground is fine: it is backgrounded relative to the orchestrator. A dispatch prompt for a self-gating landing agent must spell this loop out — a sub-agent won't infer it.

A CronCreate heartbeat (every ~4 min, one non-blocking gh pr view poll per queued PR) is a FALLBACK only if a background shell ever proves unreliable.

© nubjs, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/ci-watch of nubjs/nub.

Open the folder on GitHubat commit 568e73a

Compare with similar skills

CI Watch next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

CI Watch compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
CI Watch this skillnubjs/nub4.4k—~2.2kAutomated safety check: PassMIT
GitHub Workflow AutomationFNOSP/FlyNarwhal4958 repos~5.4kAutomated safety check: PassAGPL-3.0
CIaiblueprinthq/ai-blueprint461—~2.2kAutomated safety check: PassMIT
Michel Monitor Pull Request GitHub ActionsPackmindHub/packmind317—~2.6kAutomated safety check: PassApache-2.0
CIopenJiuwen-ai/sciencediscovery151—~2.2kAutomated safety check: PassApache-2.0
Watch CIsd0xdev/sd0x-harness192—~2.5kAutomated safety check: PassMIT

Similar skills

  • Automate GitHub workflows with AI assistance. An agent skill from FNOSP/FlyNarwhal.

    495 GitHub starsUsed in 8 repos~5.4k tokens
    DevOps & CloudAuto-check passed
  • CI

    aiblueprinthq/ai-blueprint

    Set up or normalize one project Verify command and matching GitHub Actions checks while preserving existing CI, with an optional local pre-push hook.

    461 GitHub stars~2.2k tokensUpdated 2 days ago
    DevOps & CloudAuto-check passed
  • Diagnose a failed, stuck, or never-triggered CI run on a GitHub PR, apply a local fix if possible, push it, and document the result in a single running PR comment.

    317 GitHub stars~2.6k tokensUpdated today
    DevOps & CloudAuto-check passed
  • CI

    openJiuwen-ai/sciencediscovery

    Read, diagnose, and change the CI pipeline: GitHub Actions on pull requests, the nightly schedule and the release tag.

    151 GitHub stars~2.2k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Watch CI

    sd0xdev/sd0x-harness

    Monitor GitHub Actions CI runs until completion. An agent skill from sd0xdev/sd0x-harness.

    192 GitHub stars~2.5k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Diy Netlify

    swyxio/skills

    Build or audit an isolated Netlify/Vercel-style pull-request preview workflow using GitHub Actions and the project's existing hosting provider.

    175 GitHub stars~1.1k tokensUpdated 3 days ago
    DevOps & CloudAuto-check passed

More from nubjs/nub

All 31 skills in this repo
  • Cpu Reduction

    nubjs/nub

    Diagnose and clear CPU, memory, and disk contention on the maintainer's dev host.

    4.4k GitHub stars~2.8k tokensUpdated today
    Auto-check passed
  • Reclaim disk on the maintainer's Mac when the volume is full or filling — ENOSPC, "no space left on device", a failed build or agent harness, or a routine sweep of Rust build residue.

    4.4k GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • Nub Charts

    nubjs/nub

    Build a performance chart for nubjs.com — the SVG bar figures in blog posts, docs pages and social posts (a runtime augmentation against plain node, an install or dispatch comparison, a cross-tool…

    4.4k GitHub stars~4.6k tokensUpdated today
    Auto-check passed
  • Audit Thread

    nubjs/nub

    A skill your agent uses when running a compatibility/parity AUDIT — enumerating where nub diverges from a reference it claims parity with (pnpm CLI grammar, a lockfile format, a Node behavior, a…

    4.4k GitHub stars~1.8k tokensUpdated today
    Auto-check passed
  • Linux Vm Test

    nubjs/nub

    Run ad-hoc Nub tests and debugging probes on real local Linux guests.

    4.4k GitHub stars~986 tokensUpdated today
    Auto-check passed
  • Performance-trace Nub package-manager installs using the existing phase timings, structured diagnostics, and sampling-profiler workflow.

    4.4k GitHub stars~1.3k tokensUpdated today
    Auto-check passed

Works with

Questions about CI Watch

What does CI Watch do?

Watch GitHub Actions CI correctly with the gh CLI — block until a run / PR check rollup is TRULY terminal, then trust the exit code. CI Watch is an agent skill from nubjs/nub. Watch GitHub Actions CI correctly with the gh CLI — block until a run / PR check rollup is TRULY terminal, then trust the exit code.

When should I use CI Watch?

CI Watch fits situations like: tasks that involve CI/CD; tasks that involve Pull requests.

How do I install CI Watch in Claude Code?

Run `npx skills add nubjs/nub --skill ci-watch -a claude-code`. Or copy the skill folder (.claude/skills/ci-watch in nubjs/nub) into .claude/skills/ci-watch in your project. Claude Code loads it when a task matches its description.

How do I install CI Watch in Codex?

Run `npx skills add nubjs/nub --skill ci-watch -a codex`. Or copy the skill folder (.claude/skills/ci-watch in nubjs/nub) into .agents/skills/ci-watch in your project. Codex loads it when a task matches its description.

Can I use CI Watch in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add nubjs/nub --skill ci-watch -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ci-watch, .gemini/skills/ci-watch, .github/skills/ci-watch and .opencode/skills/ci-watch in your project.

What does CI Watch need to run?

Going by SKILL.md and its folder, CI Watch needs the command-line tools its instructions call (gh and node).

Does CI Watch access the network?

SKILL.md contains no URLs. Its commands use gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is CI Watch safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does CI Watch use?

CI Watch is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does CI Watch use?

About 2.2k tokens (SKILL.md is roughly 9k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to CI Watch?

Skills that share tags, products or a category with CI Watch: GitHub Workflow Automation (FNOSP/FlyNarwhal, 495 stars), CI (aiblueprinthq/ai-blueprint, 461 stars), Michel Monitor Pull Request GitHub Actions (PackmindHub/packmind, 317 stars) and CI (openJiuwen-ai/sciencediscovery, 151 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains CI Watch?

nubjs (a GitHub organization) maintains it in nubjs/nub, which has 4,372 GitHub stars. The repository holds 31 skills in this directory. The repository was last updated on October 7, 2026.

Source: nubjs/nub on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.