gh vibe completion
Prints a tab-completion script for gh vibe. Subcommands, per-subcommand
flags, enum values (--type, --state, --shell), and open PR / issue
numbers are all wired through fish’s and zsh’s completion engines.
gh vibe completion [--shell=<fish|zsh>]Without --shell, the calling shell is auto-detected from $SHELL. If the
detected shell is not yet wired up (e.g. bash today), the command exits 2 —
pass --shell=fish or --shell=zsh explicitly to emit a snippet regardless
of the host shell.
Install
Section titled “Install”# persistent — installs once into fish's completions dirgh vibe completion --shell=fish > ~/.config/fish/completions/gh-vibe.fish
# or, for the current session onlygh vibe completion --shell=fish | sourceSource gh vibe completion --shell=zsh after the official GitHub CLI
completion (eval "$(gh completion -s zsh)"), so the gh-vibe wrapper can
capture the original _gh function before compdef-overwriting it. Reverse
order leaves gh vibe completions inert (or, worse, makes gh’s own zsh
completion stomp the wrapper later).
Pre-requisite: the gh-vibe wrapper delegates every non-
gh vibecompletion request to the saved_gh. If gh’s official zsh completion is not installed at all in your~/.zshrc, thengh vibe …itself will still work, butgh pr <TAB>,gh repo <TAB>, and other stock gh subcommands will fall back to plain filename completion (_files). To get the full experience, always load gh’s completion first; the recommended snippets below already do this.
The first line of the emitted snippet is #compdef gh-vibe gh; zsh treats
this comment specially when the file lives on $fpath, registering the
function for both commands automatically.
# persistent — drop into a dir on $fpath, then re-run compinitmkdir -p ~/.config/zsh/completionsgh vibe completion --shell=zsh > ~/.config/zsh/completions/_gh-vibe
# ~/.zshrc (load order matters: gh first, gh-vibe wrapper second, compinit last)fpath=(~/.config/zsh/completions $fpath)eval "$(gh completion -s zsh)"autoload -U compinit && compinit
# or, current session onlyeval "$(gh completion -s zsh)"eval "$(gh vibe completion --shell=zsh)"After that, every gh vibe ... invocation gets contextual completion (the
same is true under fish):
gh vibe <TAB> # review issue list clean shell-setup completiongh vibe review <TAB> # open PR numbers with titlesgh vibe issue <TAB> # open issue numbers with titlesgh vibe issue --type <TAB> # feat fix docs chore refactor test perfgh vibe clean --state <TAB> # merged closed merged,closedDynamic PR / issue completion
Section titled “Dynamic PR / issue completion”gh vibe review <TAB> and gh vibe issue <TAB> shell out to
gh pr list / gh issue list and surface open items with their titles as
completion descriptions. Errors (offline, non-repo directory, missing auth)
are silenced — TAB simply yields no suggestions rather than spamming stderr.
Results are cached for 30 seconds in a per-repo tmpfile so back-to-back TAB
presses don’t burn a gh round-trip each time. Each repo has its own cache
key (derived from git rev-parse --show-toplevel), so checkouts of different
repos never share suggestions. The cache filename format is shared between
fish and zsh, so users who switch between shells get cache hits across both.
The cache file is chmod 600’d after each write because PR / issue titles
on private repos may contain sensitive context.
Cache-hit latency
Section titled “Cache-hit latency”Even on a cache hit, each TAB still forks a few small processes
(git rev-parse to find the repo toplevel, stat for the cache mtime,
plus the cat of the cache file). zsh additionally uses $EPOCHSECONDS
(from zsh/datetime) when available so the mtime comparison doesn’t fork
date +%s on every keystroke. On modern hardware these costs are
negligible, but on low-power WSL or older macOS they can be felt as a
slight pause. If you want fewer gh round-trips at the cost of seeing
slightly staler PR titles, set _GH_VIBE_COMPLETION_TTL — the snippet
only assigns the 30-second default when the variable is unset, so
exporting it before or after sourcing both work:
# zsh — extend the cache TTL to 5 minutes_GH_VIBE_COMPLETION_TTL=300eval "$(gh vibe completion --shell=zsh)"# fish — same idea (before or after sourcing both work)set -gx _GH_VIBE_COMPLETION_TTL 300gh vibe completion --shell=fish | sourceSupported shells
Section titled “Supported shells”| Shell | Status |
|---|---|
fish | ✅ |
zsh | ✅ |
bash | 🚧 planned |
pwsh (PowerShell 7+) | 🚧 planned |
gh vibe completion --shell=bash (and the other not-yet-wired-up shells)
exits 2 with an explanatory message rather than emitting nothing.
Coexistence with gh vibe shell-setup
Section titled “Coexistence with gh vibe shell-setup”The two integrations are independent and can be loaded together:
gh vibe shell-setup --shell=fish | source
# ~/.config/fish/completions/gh-vibe.fish (or sourced once at startup)gh vibe completion --shell=fish | sourceEach uses its own load-once sentinel (_GH_VIBE_SHELL_SETUP_LOADED vs
_GH_VIBE_COMPLETION_LOADED), and the helper function namespace
(__ghvibe_*) is unique to completion.
Uninstall
Section titled “Uninstall”fish: remove the file from ~/.config/fish/completions/ (or the
| source line from your config) and reload the shell.
zsh: remove the _gh-vibe file from your completions dir (or the
eval "$(gh vibe completion --shell=zsh)" line from ~/.zshrc) and
reload the shell. Stale compdef cache may need rm -f ~/.zcompdump*
followed by a fresh compinit.
The cached PR / issue lookups in $TMPDIR/gh-vibe-completion-* expire on
their own; deleting them manually is safe but unnecessary.
Release-time manual checklist
Section titled “Release-time manual checklist”A few user-visible behaviours can’t be covered by the automated test suite
because they depend on a real interactive shell. Run through these in a real
terminal before cutting a release that touches completion.ts:
- zsh, three entry points: in a zsh session with
eval "$(gh completion -s zsh)"loaded first andeval "$(gh vibe completion --shell=zsh)"loaded second:gh vibe <TAB>lists the six subcommands with descriptions.gh vibe review <TAB>lists open PR numbers with titles (run inside a repo with at least one open PR).gh-vibe <TAB>(the binary invoked directly) lists the same six subcommands.
- zsh, flag and enum completion: in the same session, exercise the
parts most likely to regress when
_argumentsdeclarations are edited:gh vibe list --<TAB>lists--json,--stale,--limit,--allow-no-default-branch.gh vibe clean --state <TAB>offers the three valuesmerged,closed,merged,closed(the composite value is the one most likely to break under future refactors).gh vibe completion --shell <TAB>offers every value inCOMPLETION_SUPPORTED_SHELLS.
- zsh, non-vibe gh fallthrough: in the same session,
gh pr <TAB>,gh repo <TAB>, andgh issue <TAB>should still complete via gh’s own zsh completion — i.e. the wrapper must not have eaten them. - fish, dynamic completion:
gh vibe review <TAB>andgh vibe issue <TAB>should show PR / issue numbers with titles as descriptions, in an actual repo. - fish, —shell enum on completion:
gh vibe completion --shell <TAB>must offer every value inCOMPLETION_SUPPORTED_SHELLS(regression guard for the enum diverging from the canonical list).