Issue & PR Triage
Coco's triage workflow (#882) brings issue and pull-request review into the same terminal-native muscle memory as the rest of the workstation. Two complementary surfaces:
- CLI:
coco issuesandcoco prsprint formatted, filterable lists to stdout — composable withgrep,jq, and other pipeline tools. - TUI:
gi(issues) andgP(PR triage) insidecoco uiopen list-on-left / inspector-on-right surfaces with full action keys.
Both surfaces work across GitHub, GitHub Enterprise, and GitLab. Coco auto-detects the forge from the git remote host and drives the matching CLI — gh for GitHub / GitHub Enterprise, glab for GitLab. On GitLab the views operate on merge requests and issues with the same keybindings. Anything that works from the shell works inside the workstation; authentication is whatever your gh auth status / glab auth status reports — no separate token setup.
Requirements
- The matching CLI installed and authenticated:
- The current repository has a GitHub or GitLab remote (origin or fallback)
Coco surfaces a friendly empty state when either requirement is missing, so the failure mode is discoverable rather than a stack trace. For self-hosted vanity hostnames, see forgeHosts.
CLI
coco issues
List issues in the current repository.
1# Open issues (default)
2coco issues
3
4# Filter by state, assignee, author, labels
5coco issues --state closed
6coco issues --assignee @me # shorthand: coco issues --mine
7coco issues --author gfargo
8coco issues --label bug,critical
9coco issues --search "auth flow"
10
11# Tune the page size
12coco issues --limit 50
13
14# JSON output for pipelines
15coco issues --json | jq '.[] | .title'
16
17# Disable / force-refresh the on-disk cache
18coco issues --no-cache
19coco issues --refreshEvery option maps 1:1 to the corresponding gh issue list flag, so anything gh accepts here works the same way.
coco prs
Same shape, for pull requests.
1# Open PRs (default)
2coco prs
3
4# State (PRs have a merged variant distinct from closed)
5coco prs --state merged
6coco prs --state all --limit 5
7
8# Targeting
9coco prs --draft
10coco prs --mine # = --author @me
11coco prs --base main
12coco prs --head feature/auth
13
14# Free-form search syntax
15coco prs --search "is:open is:public-good"Disk cache
Both commands cache responses on disk under ~/.cache/coco/github/ (or $XDG_CACHE_HOME/coco/github/) with a 5-minute TTL. Triage is bursty — you tend to run coco issues a dozen times in a few minutes, then not touch it for hours — so the cache pays for itself quickly.
1# Force a fresh gh call (writes through to cache)
2coco issues --refresh
3
4# Skip the cache entirely (no read, no write)
5coco issues --no-cache
6
7# Clear the entire triage cache directory
8coco cache clear-githubThe repo header tag on cache hits reads cached Ns ago so you can always tell when a list is fresh vs warm.
TUI
Inside coco ui:
| Chord | Surface |
|---|---|
g i | Issues triage list |
g P | Pull-request triage list (capital P; lowercase g p keeps targeting the existing single-PR action panel for the current branch) |
The two triage surfaces are independent of the single-PR view — g p continues to show the rich action panel for the current branch's PR with status checks, reviews, and merge buttons. Use g P when you want to triage across many PRs.
Layout
Each surface follows the standard workstation chrome:
- List (main panel): rows of
#number state glyphs author branch title [labels]with color-coded state, draft/mergeable glyphs, and review-decision markers. Cursor withj/kor arrows;PageUp/PageDownpage through. - Inspector (right pane): metadata for the cursored row — state, author, branches, labels, assignees, mergeable status, review decision, timestamps, URL.
- Inspector hydration: when the cursor rests on a row for ~250ms, Coco fetches the item's body, comments, and (for PRs) reviews and status checks. Rapid j/k navigation never fires a
ghcall — only intentional rests. The hydrated detail caches per session, so cursoring back to a previously-viewed item shows instantly.
The header shows a ▼ <preset> indicator next to the row count — press f to cycle.
Action keys
Both views support the same scanning + acting flow. Destructive actions (close, reopen, merge, approve, request-changes) route through Coco's standard y-confirm prompt.
Common (both views)
| Key | Action |
|---|---|
j / k / arrows | Move the cursor |
PageUp / PageDown | Page through the list |
/ | Filter the visible list by free text (title, author, labels, assignees) |
f | Cycle through canned filter presets (see below) |
O | Open the cursored item's URL in the browser |
y | Yank the cursored item's URL to the clipboard |
c | Add a comment (multi-line prompt; Ctrl+D to submit) |
L | Add a label (single-line prompt) |
A | Add an assignee (single-line prompt; defaults to @me) |
< / Esc | Pop the view, returning to the previous surface |
Issues view only
| Key | Action |
|---|---|
x | Close the cursored issue (y-confirm) |
X | Reopen the cursored issue (y-confirm — useful to undo a stray close) |
PR triage view only
| Key | Action |
|---|---|
m | Merge — prompts for strategy (merge / squash / rebase), then y-confirm |
x | Close without merging (y-confirm) |
a | Approve (y-confirm) |
R | Request changes — multi-line review body prompt (Ctrl+D to submit), then y-confirm |
These match the chord set on the single-PR action panel (g p) exactly, so muscle memory carries over. The triage view targets the cursored PR by number rather than the current branch. Every mutating action — merge, approve, close, comment, label, assign for MRs; comment, label, assign, close, reopen for issues — works the same on GitLab as on GitHub.
GitLab nuance: GitLab has no native "request changes" review verb, so
Rposts a note prefixedRequested changes:instead of a formal review event. Merge (m) on GitLab offers the squash / rebase strategies. See Multi-Forge Support for the full list of forge differences.
Filter presets
f cycles through canned filters that compile to the same --state / --assignee / --author / etc. knobs the CLI accepts. The active preset shows in the surface header (▼ open, ▼ mine, ...).
Issues: open → closed → mine (open + assigned to me) → assigned → wrap
Pull requests: open → draft → mine (open + authored by me) → assigned → closed → merged → wrap
The presets aren't 1:1 across the two surfaces by design:
- Issues have no draft / mergeable concept, so those presets are skipped on the issue list.
- PRs have a
mergedstate distinct fromclosed; issues don't. minesemantics differ: for issues it means I'm the assignee (issues are tasks people pick up); for PRs it means I authored it (PRs are work people post).
Inspector content
Pre-hydration, the inspector renders the metadata available from the list payload — title, state, author, branches, labels, mergeable / review markers, timestamps, URL.
Post-hydration (250ms cursor rest), the inspector gains:
Issues
- Body excerpt (first 6 non-empty lines, with a
… N more linestrailer) - Comments section — total count + 3 most recent in
@author: bodyform
Pull requests
- Body excerpt
- Status checks summary —
pass / fail / pendingcounts - Reviews section — per-reviewer state (
approved/changes requested/commented) with inline body excerpt - Comments section
Empty sections are omitted — a low-activity issue or PR doesn't pad the right pane with empty headings.
Cache behavior across mutations
When you mutate a row through one of the action keys (c, L, A, x, m, etc.), Coco:
- Drops the in-memory list cache for the active surface so the next render refetches with fresh state.
- Drops the mutated item's detail entry from the per-session detail cache so the inspector hydrates fresh on the next cursor rest.
- Wipes the on-disk cache (
~/.cache/coco/github/) so any subsequentcoco issues/coco prsCLI call sees the change immediately.
This is intentionally aggressive — the cost of a refetch is much smaller than the cost of showing stale data right after an action.
Tips
- Pair the views. Cycle
gi↔gPto triage issues that gate PRs and PRs that close issues. The breadcrumb in the header shows the path. /andfcompose. Set a preset withf, then/to narrow within it. Filter survives across navigation.- Use
--jsonfor one-offs. A quickcoco issues --label bug --json | jq '.[] | "\(.number) \(.title)"'is faster than launching the workstation for read-only spelunking. - Open in browser, then come back.
Oopens the cursored URL; the workstation keeps running. Close the browser tab and your cursor is exactly where you left it.
Related
- Coco UI — the umbrella workstation guide
- TUI Navigation — chord set + navigation stack semantics
- Command Reference — full CLI flag reference for
coco issues/coco prs - Multi-Forge Support — forge detection, the
gh/glabrequirements, and GitLab specifics