Skip to content

Releases: crafts69guy/herdr-switchboard

v3.0.0

Choose a tag to compare

@github-actions github-actions released this 03 Sep 14:06

Added

  • A line-coverage gate. bash bin/coverage.sh reports per-file coverage and fails under 90%,
    and CI enforces it on every pull request. It is a separate job from bin/check.sh, which stays
    fast. Coverage went from 78.5% to 90.1%, and closing that gap found and pinned several behaviours
    that were previously untested.

Fixed

  • Concurrent panes no longer lose recency or archive state. Recording an open and archiving a
    saved review each read their file, changed it, and wrote the whole thing back as separate steps,
    so two panes acting at the same moment silently erased each other's change. Both are now a single
    locked transaction, as starring already was. Every durable file also gets a unique temporary
    sibling instead of one fixed name shared by every writer, which could leave a truncated file
    behind. Settings and zen chrome gain the same atomic replace while keeping their existing
    permissions.

Changed

  • One prefix concept, everywhere. Which prefix a key wore used to depend on where it grew up:
    ctrl-s starred a command but sent a repo to an agent, alt-s sorted in Projects but opened
    Settings in the Central Menu, alt-u updated the plugin in Projects and used a Node version in
    the fnm manager, opening a workspace was alt-w here / ctrl-w there / bare w in Normal, and
    the changelog answered to three different letters. Now the prefix names the kind of work, and
    never the mode you are in:

    • ctrl-<key> acts on the selected row — open it, update it, remove it, copy it, send it,
      star it.
    • alt-<key> changes the view or the app — preview, sort, clone, changelog, settings, plugin
      update. It is also the heavier form of a ctrl verb on the same letter, such as Ports'
      ctrl-x TERM and alt-x KILL.
    • enter runs the row's primary action, with ctrl-enter / alt-enter as its variants.

    Every one of those chords now means the same thing in both Projects modes and on every
    picker. Normal mode adds bare aliases — t v o w p — always on the same letter as the
    chord they shorten, and motion keeps the idiom of its mode (readline while typing, Vim while
    navigating).

    The space leader is gone. Space can only be a leader in Normal — while typing it is a
    character you meant — so every verb living there was forced to change prefix with the mode, which
    was the inconsistency itself. space u / space x / space c / space l / space , /
    space U are now simply ctrl-r / ctrl-x / alt-l / alt-h / alt-, / alt-u, in both
    modes.

    What moved, in full: open in a tab ctrl-tctrl-e (Projects and AI Agents), because
    herdr consumes its prefix before a pane sees the key: a binding that is somebody's prefix never
    arrives at all, and ctrl-t is the usual prefix for anyone carrying tmux muscle memory while
    ctrl-b is herdr's own default. The open group avoids both, and nothing here may bind ctrl-b
    any more. Normal's bare alias follows the letter, so it is e. Then: star ctrl-bctrl-s; send to an agent ctrl-sctrl-a
    (Projects and the Git saved-review lists); open in a workspace alt-wctrl-w (Projects
    and AI Agents; Ports already used it); clone alt-enteralt-l; changelog alt-c
    alt-h; delete word ctrl-walt-backspace, which also revives it in the Ports picker
    where ctrl-w had silently killed it; and in Node Versions, alt-u use → ctrl-enter,
    alt-i install → alt-enter, alt-d default → ctrl-d, alt-x uninstall → ctrl-x.
    Commands, Zen, the Git menu and the Central Menu are unchanged.

    Old habits are a config block away — see Remapping in docs/keybindings.md. A Projects
    override now binds into both modes at once, so it cannot reintroduce the split, and the footer
    and ? cheatsheet render whatever you bind.

  • The Central Menu and Node Versions can be rebound. They were the only two pickers with no
    [keys.*] table, so their keys were the ones nobody could move. [keys.menu] and [keys.fnm]
    now work like every other picker's.

  • The empty Starred tab in Commands names the key you actually have. It printed a fixed
    ctrl-s even after [keys.commands] star was remapped, sending you to a key that no longer
    starred anything.

  • A shift bit your terminal adds no longer loses the action. Projects weighed only ctrl and alt
    when resolving a key; every other picker compared the modifier bits exactly. So one press had two
    answers depending on which surface read it — shift-enter ran the selected row in Projects and
    did nothing in Commands, Ports, Agents, Zen, the Menu or Node Versions, and a chord arriving with
    a stray shift bit missed its ctrl- action outright. Both halves now decide the same way.

  • A picker action that collides with a reserved chord is now caught at build time. The shared
    picker answers alt-,, alt-j, alt-k, tab and shift-tab before consulting a picker's own
    actions, so an action declared on one of those was silently swallowed — the way Ports' ctrl-w
    had quietly killed delete-word for that picker alone. Those chords are one table now, and a test
    every picker runs refuses an action that claims one, takes ctrl-c/ctrl-u, uses a bare letter
    (which would make that character untypeable), prints a cap that is not the key it listens for, or
    binds a shared action to a chord it does not carry elsewhere.

  • A modified chord can no longer trigger a Git menu mnemonic. The menu matched a whether or
    not ctrl was held, so ctrl-a pressed one view too early would have started an all-files review
    — a minutes-long read — rather than doing nothing.

  • Projects and the Commands, Ports, Agents and Menu pickers scroll and filter faster. Every
    visible and off-screen row was rebuilt from scratch on each frame; rows now reuse the text they
    already have. Star lookups, tab counts, the name ordering, and field filters no longer redo work
    per keystroke. A burst of wheel or held-key input is drawn once instead of once per event.

  • Projects opens faster on machines with many repositories. Repositories with no linked
    worktrees are recognised from disk instead of costing a git process each, the two Herdr
    catalogue queries run at the same time, and a repository Inspector gathers its branch, status,
    last commit, and file tree concurrently.

  • Pickers with nothing loading no longer wake twenty times a second. Commands, Agents, the
    Menu, and the Zen picker now idle until you press something, matching Projects and Git.

  • Released binaries are built for speed rather than build time. Published archives now use a
    fully optimised profile; building from a linked checkout stays as quick as it was.

v2.1.0

Choose a tag to compare

@github-actions github-actions released this 28 Aug 05:13

Changed

  • Projects opens without a blank flash while its catalogue loads. The final dashboard appears
    immediately with Standing by…; Settings Apply keeps the old rows visible under Refreshing….
    Repository discovery now shares one ghq snapshot with up to four concurrent worktree probes.

  • Cancelling repository removal now preserves its local state. An aborted confirmation leaves
    recency and stars untouched, and a failed delete is reported instead of being treated as success.

  • The central menu is roomier and standalone Settings has one frame. The menu now opens at
    a fitted 112x28, with its complete action bar balanced across two rows separated by a gap.
    Standalone Settings relies on the
    frame Herdr already draws, while the in-Projects Settings overlay keeps its floating card.

Added

  • Projects can keep starred repos and worktrees. Press ctrl-b in Insert mode or space b in
    Normal mode to star the selection, then open the persistent ★ Starred group by keyboard or
    mouse. Compact group labels keep that tab clickable in medium panes; concurrent panes serialize
    changes so completed stars are not lost. Stars stay private on disk, retain every normal project
    action, and can be selected as projects.default_tab.

  • Commands can keep a local starred list. Press ctrl-s to star or unstar a command, then use
    the History and Starred tabs from the keyboard or mouse. Starred rows carry a peach that
    remains visible on the selected row, keep every existing command action, persist privately on
    disk, and stay available beyond the ordinary history limit.

  • Node Versions is a full fnm manager. Open it from the Switchboard menu to search installed
    and remote Node.js versions, use one in the originating pane, install it, make it the default,
    refresh the catalogue, or uninstall it after typing the exact version to confirm.

  • Projects can activate repository Node versions through fnm. Enable [fnm].enabled to show
    .nvmrc, .node-version, or package.json Node requirements in the Inspector and carry an
    already-installed match into new workspaces, tabs, and splits. Missing versions never install
    themselves or block the open; Switchboard warns and keeps the inherited Node environment.

  • Navigator paths can be copied or handed to a running agent. Select an Agent, Repo, or
    Worktree in Projects, then press ctrl-y to copy its absolute path or ctrl-s to share that
    path as context. Agent delivery uses the origin agent when it shares the worktree, otherwise
    offers matching promptable agents and falls back to all running agents; Workspace rows remain
    disabled because they do not have one unambiguous path.

  • Saved tuicr reviews can be archived without deleting review data. Press ctrl-d in the Git
    menu's saved-review list to hide a session, open R archived reviews to find it, and press
    ctrl-d again to restore it. Reading comments and sending them to an agent remain available in
    both lists.

  • Saved tuicr reviews can be handed directly to a running agent. Press ctrl-s in the Git
    menu's saved-review list: Switchboard uses the origin agent when it still shares the worktree,
    otherwise offers matching agents and then all available agents. The handoff preserves tuicr's
    structured comment IDs and locations, closes back to the agent on success, and stays retryable
    when delivery fails.

Fixed

  • New workspaces, tabs, and splits no longer print Switchboard's fnm activation command around the
    shell greeting. Matching Node versions are supplied only through the target's launch environment.

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 16:44

Changed

  • Switchboard backgrounds now follow one explicit policy. Set
    common.transparency = "transparent" (the default) to show the terminal through Projects,
    mode pickers, Git, Usage, Settings, Changelog, the review splash, and their nested cards; set it
    to "opaque" to fill every surface and gutter with panel_bg. The old
    auto/enabled/disabled values are removed so parent panes and floating cards cannot silently
    choose different behavior.

  • Switchboard is now Vim-first and adapts as a persistent dashboard. Projects opens in Normal
    mode by default; i or / enters filtering, and common.keymode = "insert" restores the old
    type-first start. Wide panes show a context rail beside the navigator and inspector, medium panes
    keep the navigator/inspector split, and compact panes reserve the available space for navigation.

  • Every terminal surface now runs through one lifecycle host. Projects, mode pickers, Git,
    Usage, Changelog, and Settings share terminal claiming, mouse capture, polling, redraw, and
    guaranteed teardown. Keybinding overrides also use the same chord parser everywhere, so accepted
    syntax and displayed key caps cannot drift between pickers.

  • Usage donuts now separate spent quota from what remains. The used arc and its percentage use
    the theme's semantic red, while the available arc uses semantic green. Loading and unavailable
    cards remain muted, and the per-window bars keep their existing provider severity and configured
    warning thresholds.

Fixed

  • The local-build cat is centred in the real plugin pane. Bootstrap now reads the Herdr PTY
    size directly instead of falling back to terminfo's 80x24 dimensions, and its vertical padding
    uses terminal rows rather than spaces on the first line.

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 03:17

Added

  • A renews row on every Usage card. A window reset says when you may work again; a renewal
    says when the plan is charged and its allowance starts over — the question that decides whether
    pacing is worth it at all. Codex states it, so the row reads renews 13 Sep · in 25d, taken
    from the same ~/.codex/auth.json ID token the account line already decodes: no extra request,
    no extra file, one read for both labels.

    Anthropic states it nowhere readable — not in the usage endpoint, not in ~/.claude.json — so
    the Claude card says unknown instead of counting a month from the day the subscription was
    created. A date already in the past reads as unknown too: the Codex claim only refreshes while
    Codex runs, and a stale date under a heading that says renews reads as one that is coming.

  • The mouse reaches every surface, not just the switcher. The pointer worked in the projects
    picker and nowhere else: --usage and --changelog never turned mouse reporting on at all,
    --settings read only keys, the Git pane took the wheel and ignored every click, and the mode
    pickers moved the selection without ever running it. Now the wheel scrolls the changelog, moves
    the selection in the Git menu and its sub-lists, walks the settings form, and scrolls a mode
    picker's preview card when the pointer is over it — and a click reaches rows, tabs and
    command-bar pills on all of them.

    One rule everywhere, because terminals report no double-click: a click selects, a click on the
    row already selected does what Enter would, and a click on a pill does what the key printed on
    its cap does. So no stray click ever launches a review or writes a setting, and a pill's label
    cannot drift from its behaviour — the label is the behaviour. Each zone is still measured by
    the loop that draws the thing it points at; what is shared is the lookup, not the measurement.
    Clicking outside the settings card now discards the draft as esc does, instead of closing over
    a staged edit and leaving it alive.

Changed

  • A reset that is not today now names the day it falls on. The status line reads
    resets 08:53 Wed 19 Aug and the window's own bar row reads 1d 12h · 19 Aug. A weekday is
    unambiguous inside a seven-day window but it is not legible: mapping Thu onto a calendar six
    days out is arithmetic you had to do in your head, and the weekly bucket is exactly the one that
    lands far enough away to need it.

    A window rolling over later today stays as short as it was — resets 15:59 Thu, 2h 40m — so
    the presence of a date is itself the signal that the rollover is not today. The countdown keeps
    its place beside it: it is the only "how long do I wait" figure a window that missed the donut
    gets.

  • More air between the Usage cards. The pane paints no background and draws no divider
    between providers, so whitespace is the only thing separating them — and with the columns
    butted together the two cards read as one wide table of rows rather than two independent
    answers. They now get a gutter, which yields back to one column on a pane too narrow to seat
    the cards' own rows. The columns also fill the pane exactly, instead of 100 / n leaving the
    remainder dark on the right.

  • The Git menu asks before an all-files review of a large repo. a runs tuicr -A, which
    reads every tracked file — and because the pane deliberately keeps the screen, draws one static
    splash and execs the review over itself, a checkout big enough to keep tuicr busy for minutes
    is indistinguishable from a hang: no frame, no spinner, nothing to cancel. On a 7,600-file tree
    it was two solid minutes of a cat that never moved.

    The row now counts the tree first — one git ls-files, taken on activation rather than on open,
    so the menu's first frame still costs nothing — and over git.all_files_warn (1,500 by default)
    it spends a screen saying what it found: 6,699 files tracked in this repo, tuicr reads every one of them before its first frame. Enter opens it anyway, esc goes back to the menu. Under the
    threshold nothing changed, and all_files_warn = 0 never asks. A count git refuses to give
    opens the review rather than standing in front of it: a broken number must not become a locked
    door.

  • The Git pane stopped painting itself opaque. Its menu card, its sub-list card and that
    list's search box each filled themselves with panel_bg and drew their borders in the accent.
    All three were hand-rolled Blocks — exactly the drift tui::boxed exists to prevent — and the
    result was one pane that looked like a solid dialog sitting next to five that the terminal shows
    through. They go through the helper now: borders recede in overlay0, captions keep
    title_color, and nothing paints a fill, so a translucent terminal stays translucent under the
    Git pane too.

    panel_bg keeps the places it belongs: as ink on key caps and pills, and as the fill of the
    changelog, settings and cheatsheet popups, which float over the live picker and genuinely have
    to occlude it. The switcher's own list panel was hand-rolling a Block as well — its caption
    slot holds the tab strip rather than a word — so tui grew framed, the captionless half of
    boxed, and both panels build from it. Three render tests now assert the absence of a fill,
    because the one that existed only covered the mode pickers.

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 19 Aug 06:43

Added

  • A conflicts row in the Git menu. x lists every path git status reports as unmerged,
    each with what actually happened to it — both modified, deleted by them, both added
    and opens the one you pick in tuicr. It is always offered: with no merge in progress the list
    says so, rather than the row appearing and disappearing under the mnemonic.

    The pick opens with tuicr --file, which shows the file itself with its conflict markers
    intact, not a diff. That is on purpose: git diff on an unmerged path emits a combined
    diff (diff --cc), which is not the two-sided shape a review tool reads. This is the row
    retired in 0.10.0 for exactly that reason, back now that the sub-list picker the pull-request
    and saved-review rows already use gives it a way to name one file at a time.

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 18 Aug 15:48

Added

  • A Usage popup. Bind switchboard.usage or open it from the central menu to see how much of
    each AI subscription is spent and when it resets. Each agent gets a donut for the window closest
    to running out, a bar for every other window, and the numbers that give the percentage its
    context: what the session spent, how much of the context window the last turn used, whether
    credits are on. Every card dates itself — as of 12m ago — because Codex reports whatever its
    last session wrote, and a two-day-old percentage read as current is the mistake this popup exists
    to prevent. Resets are given both ways, in 1d 12h and resets 08:53 Wed.

    Codex reads the exact numbers OpenAI returns, straight out of its own session log, with no
    network at all. Claude Code publishes nothing to disk, so its card asks the same endpoint the
    in-session /usage command asks, using the OAuth token Claude Code already stores; that request
    runs on a worker with a timeout, so the popup opens instantly with Codex on screen and fills
    Claude in when it lands. Claude also grades its own limits, and the card colours them the way the
    provider grades them rather than by a threshold of ours; anything ungraded falls back to
    usage.warn_percent and usage.alert_percent.

    Each card names the account it is reporting on — the two agents are routinely signed in as two
    different people, and a quota means little without knowing whose it is. Codex's address comes
    from the ID token it stores, Claude's from the profile Claude Code caches, and that profile is
    also where the Claude card gets its plan, since the usage endpoint names none.

    Press r to read both again. Any agent that cannot be read says why on its own card and leaves
    the other one alone. Choose the providers and thresholds under [usage], or from the settings
    overlay.

  • Zen can hide Herdr's own chrome. The new zen.chrome setting (off by default, or
    panes / full) suppresses the pane borders and gaps, the scrollbar column, the tab row and
    the sidebar for the length of a zen session. None of those have a per-pane switch, so anything
    but off rewrites the matching [ui] keys in Herdr's own config.toml and reloads Herdr,
    then restores them exactly on the way out: comments and unmanaged keys survive, keys already at
    the wanted value are left alone, and your untouched config is copied to
    $XDG_STATE_HOME/herdr-switchboard/herdr-config.backup.toml before the first write. If a
    restore fails or Herdr is killed mid-session, herdr-switchboard zen chrome-restore puts it
    back. Herdr only applies sidebar_start_collapsed on its next launch, so full may leave the
    sidebar in place — zen measures that and says so rather than failing silently.

  • Zen mode. switchboard.zen-toggle gives the current pane the screen: it moves to a tab of
    its own, centred at zen.width (default 70%) between two dimmed gutters, and toggling again
    puts it back where it was. switchboard.zen opens a picker to zen any pane instead of the
    current one. The gutters are dimmed by painting over them through Herdr's graphics API, which
    needs [experimental] kitty_graphics = true; without it the gutters are simply blank. Tune it
    with zen.width, zen.scrim, and zen.scrim_color, or from the settings overlay. Neighbouring
    panes are never touched — only the zen'd pane moves, and its running process survives the move.
    Leaving zen restores a two-pane tab exactly; a more deeply nested tab gets every pane back beside
    its former neighbour, with a notification when the split nesting could not be reproduced.

  • An AI Agents picker. Bind switchboard.agents or open it from the central menu to list the
    AI integrations installed in Herdr. enter starts the selected AI in the origin pane, ctrl-t
    starts it in a new tab, and alt-w starts it in a new workspace; failed starts clean up any
    tab or workspace Switchboard created. The focused picker opens as a compact centered popup rather
    than a mostly empty full-screen overlay. This requires Herdr 0.8.0 or newer.

Changed

  • The README is now a concise entry point instead of a monolithic reference. Quick start,
    feature discovery, core actions, and namespaced configuration stay on the front page; detailed
    keybindings, safety behaviour, Zen, Git, configuration, and architecture now live in focused
    guides under docs/. Stale pre-1.0 wording, flat configuration names, dependency scope, popup
    placement, update-version examples, and contributor checks were corrected at the same time.

Fixed

  • Opening AI Agents or another popup from the Central Menu now waits for the menu popup to close,
    so Herdr no longer rejects the replacement as popup already open.
  • The AI Agents picker now closes immediately after a selection while startup readiness is checked
    in the background; failed starts still clean up new tabs or workspaces and report the error with
    a notification.
  • Linked development checkouts now rebuild their release binary when Rust sources or Cargo metadata
    are newer, instead of silently running an old same-version binary after source changes.

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 05:50

Breaking

  • Removed the old ghq configuration/state migration and flat-config compatibility path;
    Switchboard now reads only namespaced configuration from its own plugin directory.

Changed

  • The Menu, Commands, and Ports pickers now render in the Projects picker's visual
    language: borders recede in overlay0 instead of shouting in the mode accent, every
    panel caption uses title_color, and the selected row is a subtle surface1 bar
    rather than a full-width inverted accent block.
  • Those three panes no longer repeat their name: herdr already draws the pane frame and
    its title, so the pane title is now a single icon (as Projects and Git already were)
    and the mode name moved onto the list panel.
  • All three panels are transparent, so the terminal shows through consistently. The
    Search and Preview panels previously painted an opaque panel_bg while the list did
    not, which read as two different themes inside one pane.
  • The Preview panel gained the Projects picker's ⌥jk n/total scroll indicator, shown
    only when the card runs past the fold, and its scroll now clamps to the content.
  • Picker rows are laid out against the panel's real width. A row longer than the panel
    now ends in an ellipsis instead of being cut mid-word wherever the border fell, and a
    row's trailing tag sits in its own right-hand gutter instead of a column that went
    ragged as soon as one entry ran long.
  • Commands stopped printing shell on every row — it was the source of all but a handful
    of entries. The badge now appears only for a preset or a Switchboard command, and the
    right-hand gutter carries how long ago the command was last used (2h, 3d), which is
    what the list is sorted by.
  • Commands draws each row's leading word — the program — in the entry's colour, bold, so
    a wall of history has something to scan down, and gives the list 58% of the body rather
    than 42, since its rows are long and its preview card is short.
  • The Commands preview reports last used as a relative age plus a readable UTC date
    instead of a raw unix timestamp, and labels the selection count as n ×.

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 03:55

Breaking

  • Renamed the package, binary, plugin id, release assets, runtime environment variables, and state
    directory from herdr-ghq / ghq to herdr-switchboard / switchboard. Existing flat
    configuration and state are migrated once, validated, and then removed; no legacy alias or backup
    is retained. Change ghq.menu bindings to switchboard.projects.

Added

  • Added the searchable switchboard.menu central menu and direct actions
    switchboard.projects, switchboard.commands, switchboard.ports, and
    switchboard.settings, so every picker can have its own Herdr key binding.
  • Added a Commands picker that merges shell history, presets, and Switchboard selection history;
    supports quoted/negated field filters; excludes likely secrets; and can fill, run, copy, or forget
    an exact command. Multiline execution requires typed confirmation.
  • Added a native Ports picker for live TCP listeners with process metadata, automatic refresh,
    URL/copy/workspace actions, and identity-checked TERM/KILL confirmations.
  • Added four package Settings tabs (Common / Projects / Commands / Ports) and semantic Herdr
    notifications for command-delivery and listener-signal outcomes.

Changed

  • Configuration is typed, namespaced TOML. Commands and Ports share a colorful picker engine with
    stable selection, mode-specific remaps, inline filter diagnostics, mouse support, preview, and a
    live command bar.

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 03 Aug 06:39

This release replaces hunk with tuicr and moves the git
menu out of the switcher into a pane of its own. It is a breaking change: keys move, two menu rows
are gone, and tuicr is now a hard requirement (brew install tuicr, ≥ 0.20.0). Themes for it come
from hue-theme — install that first, or reviews open in
tuicr's own colours.

Removed

  • ⌥g no longer opens a git menu in the switcher. The menu is a herdr pane now, reached only by
    the ghq.git action (bind it to prefix+g). What you lose with it: reviewing an arbitrary repo
    you fuzzy-jumped to. cd there (^o) and press prefix+g. Two entry points would have drifted
    apart, and only one of them could be the fast one.
  • s review staged — tuicr has no staged-only flag, d (tuicr -w) already covers staged and
    unstaged together, and lazygit is the better pre-commit surface.
  • x resolve conflicts — tuicr's -p takes a single path prefix, so hunk diff -- <files>
    has no translation.
  • The commit history browser — the scrolling, fuzzy-filterable git log list behind h. tuicr
    has a commit panel of its own, so h now opens that directly.
  • The startup animation. The switcher no longer animates a cat while it loads.
  • hunk is no longer used or configured, and the plugin writes nothing into tuicr's config.

Added

  • A dedicated git menu pane. prefix+g opens it straight onto the repo the pane is sitting in;
    it loads no agents, no workspaces, no repository index, and no preview on the way. Picking a row
    takes over that pane, and quitting the review returns you to where you started.
  • a — review all files (tuicr -A).
  • p — review a pull request: gh pr list in a fuzzy-filterable list, then tuicr pr <n>. The
    row is hidden when gh is not installed.
  • r — saved reviews: the sessions from tuicr review list, with their comment counts. Note
    this reads comments only — tuicr's TUI cannot reopen a session, so there is no way back into a
    half-finished review yet.
  • GHQ_TRACE=1 writes tab-separated timings to $XDG_STATE_HOME/herdr-ghq/trace.log (or
    $GHQ_TRACE_FILE) — first list, keystroke-to-frame, and preview render, each measured
    separately. Never to stdout or stderr. See the README.

Changed

  • The switcher opens about 10× sooner — roughly 35 ms to the first list where it used to be
    430 ms. Almost all of that was the animation's own 420 ms minimum-visible floor, not the work: the
    sources are now read synchronously before the terminal is claimed, so the first thing painted is
    the list. A machine with thousands of repositories will see a blank pane for slightly longer
    before it appears.
  • Reviews open in tuicr, not hunk: dtuicr -w, btuicr -r <base>.. -w,
    htuicr. Every launch passes --no-update-check.
  • The preview card is about twice as fast — roughly 50 ms on average where it used to take
    90 ms, and 65 ms at the tail where it used to reach 214 ms. The branch now comes from reading
    .git/HEAD rather than spawning git symbolic-ref, and the dirty check no longer walks untracked
    files. Behaviour change: a repository whose only changes are untracked files now reads as
    clean.
  • The git menu is sized to fit its command bar, so a short menu no longer clips esc close to
    esc clo, and every row carries an icon.

Fixed

  • Enter on an agent now actually switches to it, and the agent preview loads again. herdr keys
    agent focus/agent get on the pane id, but the switcher was passing the terminal id, so every
    agent focus failed silently (agent_not_found) — the picker closed and left you on the current
    agent — and the preview card came up empty. Agents now carry their pane id as the target.
  • Opening the git menu no longer prints a stray commit SHA onto the screen beneath the card.
    Base-branch detection ran git rev-parse --verify through the terminal-inheriting status path,
    and rev-parse echoes the resolved SHA on success; it now captures the output instead.
  • The Kitty/herdr graphics startup splash (the animated GIF cat) is gone, along with the
    [experimental].kitty_graphics dependency. herdr 0.7.5 changed its socket API to serve one
    request per connection and close it on reply, which stranded the image on screen.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 22 Jul 05:12

Added

  • An animated typing cat now appears as soon as the switcher opens: compatible
    Kitty/Ghostty/WezTerm panes use the embedded cat-typing.gif frames when Herdr's experimental
    Kitty graphics proxy is enabled, while small or unsupported panes automatically keep the
    theme-coloured pixel-art fallback. Both paths preserve the terminal's transparent background;
    the image is cleaned up before picker content appears and
    its first frame is always shown for a 420 ms minimum, making 2–3 animation steps visible even
    when loading finishes immediately. Agents, workspaces, repositories, and linked worktrees
    load in the background. Inside Herdr, frames use its acknowledged pane-graphics API so a
    rejected image immediately reveals the pixel-art fallback instead of leaving an empty splash;
    direct terminal launches retain standard Kitty commands. Managed
    installs fetch a checksummed native binary for macOS/Linux on arm64/x86_64, so first open no
    longer waits on Cargo; offline and linked checkouts still fall back to a local build, with
    the same cat keeping the pane responsive. esc or ctrl-c cancels either loading stage.
  • Launching a ⌥g review now shows the same typing cat while it opens. A hunk review used to
    hand the pane a frozen screen while hunk diff walked a large repository; the review launcher
    now plays a short branded pre-roll that animates the cat (Kitty frames or the pixel-art fallback)
    while it warms the exact diff hunk is about to read, so the review opens onto the splash instead
    of a stall and hunk itself starts faster off the warmed cache. The cat stays up until the warm-up
    finishes (a 420 ms floor keeps it visible on an already-warm repo, a 5 s cap keeps a pathological
    one from stalling); esc, enter, or ctrl-c skips straight to the tool. The pre-roll hands off
    without a blank flash: it freezes a static “Opening review…” frame and leaves the screen in place
    for hunk to paint straight over, rather than tearing the terminal down between the two. Only hunk
    reviews get it — lazygit and custom menu.conf commands bring their own startup.
  • A Worktrees tab now lists linked Git worktrees across every ghq repository without
    duplicating the main checkout already shown under Repos. Worktrees open in a workspace,
    tab, split, or pane and use the built-in Git menu at their own path; repo-only update and
    remove actions stay hidden. include_worktrees controls the source and defaults to true.
  • default_tab chooses the active startup group (all, agents, workspaces, repos, or
    worktrees). Applying it in the settings overlay switches immediately; an empty, disabled,
    or unrecognised group safely falls back to All.

Changed

  • The Workspaces preview is now a dashboard. Instead of a bare tab list, it shows a
    pane/agent summary with a colour-coded status breakdown, the running agents with their
    status and current task, and the distinct repositories their panes sit in with each one's
    branch and a dirty marker — read from pane list so it reflects what the workspace is
    actually running.