AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
A fast, focused TUI that hunts down your CI
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗gh-hound is a gh extension and standalone CLI/TUI for GitHub Actions. It opens where developers actually work: the current repository, the current branch or repo-wide scope, the latest runs, the selected job, the failing step, the full log, and the rerun/cancel/dispatch action surface.
The TUI is for humans. The structured output is for agents and scripts. Both paths share the same usecase core, so CI state, failures, annotations, excerpts, and exit codes stay consistent.
Because "open Actions, click run, click job, expand logs, search, scroll, open another tab, forget which branch this was" is not a debugging workflow. It is a browser obstacle course.
gh-hound gives you the CI loop you wanted:
| Question | One terminal answer |
|---|---|
| Is my branch green? | gh hound opens the scoped run list with status, age, event, rate budget, and cache/live state. |
| What failed? | Enter drills into jobs and steps; n jumps to the next failure. |
| Where is the useful log line? | l opens the full log with folds, search, line numbers, highlights, and a scrollbar. Repeating lines (polls, retries, progress, repeated stack traces) fold into one row that says how many, for how long and what changed; c shows the full log. |
| Can I retry safely? | r, R, x, and dispatch flows are local, visible, and confirmation-gated. |
| Can an agent consume this? | --no-tui --json returns schema-stable CI objects and deterministic exit codes. |
Short version: your browser has enough tabs. Keep CI triage beside the code.
The top image is the gallery. Use these source frames when you want to inspect the pixels:
| Frame | What it proves |
|---|---|
| ASCII banner | The first impression is branded, terminal-native, and rendered by the real binary. |
| OpenClaw live runs | Repo-wide high-volume Actions feed with run numbers first, event names, sparklines, scope, and rate budget. |
| Full log viewer | Real CI log rendering with line numbers, folds, scrollbar, search count, and highlighted matches. |
| Run detail | Jobs and step timeline from a live run, not fixture data. |
| Guarded rerun | Mutation flows are present, but confirmation-gated. |
| Context help | Help is generated from the active keymap and overlays the current screen. |
The GIF is deliberately secondary: static shux captures are the visual truth; VHS is the quick motion tour.
| Web UI friction | gh-hound behavior |
|---|---|
| Multiple page loads to reach the failing step. | One terminal launch, then Enter / n / l. |
| Browser log pages can feel heavy on large logs. | The TUI renders only the visible log window and keeps folding/search state local. |
| A job that polls for two hours buries its failure under thousands of near-identical lines. | The full log opens compact: ⋯ ×720 2-line block · 16:12:11 → 18:12:02 · 3 changing ids … 1,436 lines hidden, on its own band so it never looks like a step group, and ]/[ jump between folds. Rare or changed values (exit code 137) stay visible, and search and time jumps open the fold they land in. |
| Scope gets lost across tabs. | Header keeps branch/repo scope, loaded count, rate budget, and cache/live state visible. |
| Rerun/cancel lives away from diagnosis. | Actions are available in context and guarded by explicit confirmation. |
| Agents get raw pages or raw logs. | --no-tui --json returns schema-stable runs, failures, annotations, and excerpts. |
| Downloading an artifact means a browser trip. | List artifacts in run detail and download/extract with one confirmed keystroke, or gh hound artifacts --download. |
| Finding when a step hung means scrolling a 10k-line log. | t opens a time modal: step picker, slowest-gap detection, jump to 17:43, or filter to 17:42-17:44. |
gh-hound is built around the parts of the GitHub Actions API that matter for fast CI triage:
The local gate includes race-enabled Go tests, large-log performance tests, and shux visual/interaction audits across 80x24, 120x40, and 200x60.
/actor:@me (or : → My runs) narrows to runs you started, resolved from the credentials gh-hound already uses — never git config. Filters combine (actor:@me status:failure branch:main), reach past the first page, and survive f, s, refresh, paging, and detail round-trips. Run detail names who started a run and who re-ran it.$GH_HOUND_ARTIFACT_DIR or the working directory), the row streams live progress (byte counter, then extracting…), and a finished download keeps a ✔ verdict with its path inline — o opens the extracted folder, y copies its path, and re-downloading into an existing destination offers a guarded overwrite instead of a dead-end error.A opens the gate overlay — pick environments, approve or reject with confirmation — and the approvals pipe verb does the same for agents. The gh CLI has no equivalent.caches verb and palette screen show Actions cache pressure against the 10 GB eviction cap — themed gauge, sortable list (biggest or stalest first), key filter, and confirm-gated deletes by ID or key with the match count shown before anything is dug up. Past 90% the kennel warns before GitHub starts evicting.t modal on the log screen with a landmark picker (step boundaries, the failure window, the slowest gaps), typed jumps (17:43, +30s, -2m), and A-B range filtering.f on the runs screen cycles the status: token (failure / in progress / success / all) and keeps the rest of the filter.runs --run <id> --attempt <n> triages a specific attempt after a re-run -- failed jobs, clean excerpts, exit codes.diff walks a workflow's history to the last-green → first-red boundary and names the suspect commits -- the answer re-runs builds for is already in the run history. TUI screen via , JSON verdict for agents, bounds the spend.git clone https://github.com/indrasvat/gh-hound.git
cd gh-hound
make build
./bin/gh-hound --version
make install
gh-hound --version
After the first tagged release is published:
gh extension install indrasvat/gh-hound
gh hound --version
After the first tagged release is published:
curl -sSfL https://raw.githubusercontent.com/indrasvat/gh-hound/main/install.sh | bash
Pin a version or custom install directory:
curl -sSfL https://raw.githubusercontent.com/indrasvat/gh-hound/main/install.sh \
| bash -s -- --version v0.1.0 --dir ~/.local/bin
# Human TUI path
gh hound
gh hound -A
gh hound -R openclaw/openclaw -A
gh hound watch
# Agent/script path
gh hound runs --no-tui --json
gh hound runs --status failure --no-tui --json
gh hound runs --actor @me --status failure --no-tui --json # my failing runs on this branch
gh hound runs --all --no-tui --json # branch miss / release or tag discovery
gh hound watch --json
gh hound watch --group --no-tui # blocks until the hunt settles
gh hound watch --group --no-tui --timeout 10m # bounded for unattended agents (timed_out summary; exit 3 in-flight / 1 if lost)
gh hound queue --run <run-id> --no-tui --json # why is this pending?
gh hound rerun --run <id> --failed-only --debug --no-tui --json
gh hound cancel --run <id> --no-tui --json
gh hound diff --workflow CI --no-tui --json # who broke main?
gh hound flakes --workflow CI --no-tui --json # flaky or real?
gh hound workflows --no-tui --json # every workflow + state (why did my cron stop?)
gh hound workflows --enable ci.yml --no-tui --json # wake it: back on duty
gh hound workflows --disable 290736476 --no-tui --json # muzzle it (id or file path)
gh hound artifacts --no-tui --json
gh hound artifacts --run <run-id> --download <name> --dir <path> --no-tui --json
gh hound runs --run <run-id> --attempt 2 --no-tui --json # forensics on a re-run
Local deterministic scenarios are available for docs, tests, and agent harnesses:
./bin/gh-hound runs --no-tui --json --fake-scenario green
./bin/gh-hound runs --no-tui --json --fake-scenario failure
./bin/gh-hound runs --no-tui --json --fake-scenario pending
./bin/gh-hound watch --json --fake-scenario failure
./bin/gh-hound diff --workflow CI --no-tui --json --fake-scenario regression
./bin/gh-hound watch --group --no-tui --fake-scenario pack # staggered 3-run pack
Fixture scenarios are intentionally restricted to non-interactive/test paths. The real TUI does not fall back to sample data.
| Context | Keys |
|---|---|
| Global | ? help, : palette, T theme, q/Ctrl+C quit, Esc back |
| Runs | j/k or arrows move, g/G top/bottom, s scope, Enter open, f status cycle, / filter, l logs, w watch, A approvals (waiting runs) |
Filter / | type a query, Enter apply, Esc cancel (restores the applied filter), Ctrl+U clear; Esc on the list clears the applied filter |
| Actions | r rerun, R rerun failed, x cancel, X force cancel, D dispatch |
| Detail | Tab focus, n next failure, l logs, w watch (follows a running job step by step), a artifacts, d download (overwrite-guarded re-download), o/y open folder / copy path on a downloaded artifact (browser / run URL otherwise), J/K next/previous run |
| Failure | l full log, o browser, y copy excerpt, r rerun job |
| Log | / search, t time jump/range, n/N matches, z/Z fold, c compact/full, ]/[ next/previous repeat fold, w wrap, g/G top/bottom |
| Watch | f follow, d debug, x cancel, Esc detach — a running job shows its current step and elapsed time; GitHub serves its log once the job finishes |
| Hunt board | j/k move, Enter drill into one run, f follow worst, x cancel, Esc back |
| Dispatch | Tab next, arrows/select controls, Enter run, Esc cancel |
| Token | Finds |
|---|---|
actor:@me | runs you started (the login your token authenticates as) |
actor:<login> | runs a login started; bots like dependabot[bot] work |
status:<s> | failure, success, in_progress, queued, … (failing, running, passed also work) |
branch:<ref> / event:<e> / sha:<sha> | head branch, trigger event, head commit |
| a lone status or event word | the same as status: / event: (failing, push) |
| anything else | text search over the loaded rows (workflow, title, branch, actor, run number); feat: bump is text too |
Qualifiers are answered by GitHub and combine; text narrows what is loaded. A known key with a bad value (actor:, status:sideways) is rejected inline and nothing changes. The summary says which: · 12 runs for a server query, · 3 of 30 loaded for a text search.
Config lives at ~/.config/gh-hound/config.toml (or under $XDG_CONFIG_HOME). Environment variables override file values, and flags override both. A bad file stops the launch with an error naming it.
default_scope = "branch"
auto_watch = false
per_page = 30
diff_max_pages = 10
watch_group_max = 10
theme = "bramble"
A [keybindings] table moves actions to other keys (cancel = "c"); footers and help follow. See docs/configuration.md for all supported values, the remappable actions and precedence rules.
Use JSON for automation:
gh hound runs --status failure --no-tui --json | jq '.runs[0].failed[0]'
gh hound runs --all --no-tui --json # widen when branch-scoped runs are empty
gh hound diff --workflow CI --no-tui --json | jq '{status, verdict, suspects: .total_suspects}'
--actor <login|@me> (or HOUND_ACTOR) narrows runs to one actor; the flag beats the variable, and an explicit --run always shows that run (--actor with --run is refused; HOUND_ACTOR is ignored). If @me cannot be resolved the command exits 2 with the reason instead of listing everyone's runs. Every run carries actor and triggering_actor (the latter differs after a re-run by someone else).
Branch-scoped runs stays the default for normal PR work. When that scoped query is empty, JSON may include diagnostic.kind: "target_mismatch" with concrete next commands for release/tag workflows: widen with --all, pass an explicit --branch <ref>, or target --run <id>.
The diff verdict is a JSON object agents can branch on: status is located (exit 1 -- a regression exists), green, or inconclusive (both exit 0), with last_good, first_bad, suspect_commits[], and compare_url when the boundary is found.
gh hound flakes --workflow CI --no-tui --json | jq '{status, verdict}'
The flakes verdict is the rerun-vs-investigate decision: status is flaky or suspect (exit 1 -- rerun or look closer; per-job flake_score, signal counts, and evidence[] say why) or clean / insufficient_data (exit 0 -- chase the failure for real). Thresholds are documented in docs/agent-surface.md.
Exit codes:
| Code | Meaning |
|---|---|
| 0 | all good |
| 1 | CI failure/action needed |
| 2 | API/network/config/render error |
| 3 | pending/running |
Schema and fixtures live under internal/render/testdata/. Full agent docs are in docs/agent-surface.md; the repo-local skill handoff is skills/gh-hound/SKILL.md (installable with npx skills add indrasvat/gh-hound).
cmd/gh-hound Cobra CLI and gh extension entrypoint
internal/usecase Shared CI workflows for TUI and pipe surfaces
internal/adapter GitHub REST port, fake adapter, cache, poller
internal/render JSON/Markdown/XML agent renderers
internal/tui Bubble Tea-style app shell and screen renderers
internal/logs Log parsing, folds, annotations, excerpts
internal/logs/fold Folding repeating lines: shapes, detectors, refiners, plans
.claude/automations shux VQA and interaction audit harness
The boundary is deliberate: usecases do not depend on the concrete GitHub client or the TUI. That keeps fake scenarios, agent JSON, and local tests deterministic while the live TUI stays wired to the real GitHub path.
make tools
make hooks
make check
make vqa
make docs-check
make demo
See docs/development.md for the TDD workflow, Makefile target map, lefthook guardrails, shux VQA, and release-prep notes.
diff — the trail; flake detection shipped as flakes — the scent check.)serve mode for lifecycle events and multi-agent CI fix loops.MIT
git bisect:diffdiff_max_pagesflakes answers "real failure or flake?" with a scored, evidenced verdict -- attempt flips, cross-run flapping, and retry-wrapper masking over the last flake_window runs. The failure screen recognizes the scent (seen this one before: flaked 2 of last 50 runs) with evidence drill-down, known flakers wear a ~ badge on the runs list, and agents branch on status: flaky -> rerun, clean -> investigate.queue explains pending runs and jobs through GitHub Actions concurrency groups -- target, blockers, positions when GitHub exposes them, and a decision.action agents can branch on. A proved concurrency block exits 3, not 1: it is a wait state, not a red CI state.:workflows lists every workflow with its state badge -- ✔ active, ◌ asleep (fell asleep after 60 quiet days, the classic "my cron stopped" mystery), ⊘ muzzled (disabled by hand), ⊘ fork-disabled, ✗ deleted -- and e wakes or muzzles the toggleable ones, confirm-gated. The workflows pipe verb lists states and flips them by id or file path. Disabled workflows are named on the empty screen, and the dispatch picker badges them instead of hiding them.c toggles the full log, z/Z close and open every fold, and log_compact = false opens full logs by default. Folding never hides a line without a visible example of it, and falls back to the full log if it cannot finish within its time limit.w watches the selected run's whole event group — one row per workflow, the hunt: 3 running · 1 home · 0 lost header, drill into any run, follow-worst mode — on one runs-list call per poll. watch --group streams the same hunt as NDJSON for agents, and dispatch/rerun can hand off straight into watch (auto_watch).workflow_dispatch workflows and inputs rendered as a keyboard-driven form. Foreign -R targets pre-fill their own default branch (never your local checkout's), and refs are validated as a real branch or tag before anything fires.0/1/2/3. The leash works both ways: rerun, cancel, and caches --delete-id/--delete-key act from the same surface (--failed-only, --job, --debug, --force, --ref).make vqa captures every primary screen and interaction through shux.| Trail (diff) | j/k move suspects, Enter open first bad run, o compare in browser, Esc back |
| Scent check (flakes) | j/k move evidence, Enter open that run, Esc back; on the failure screen Tab toggles excerpt/panel focus |
| Kennel (workflows) | j/k move, e wake/muzzle (confirm-gated), o browser, Esc back |