Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

4. The TUI cockpit

Everything you’ve done at the command line has a home: a live, keyboard-driven cockpit — your mission control for the whole fleet. It’s in the spirit of k9s or htop: a full-screen terminal UI where you see the fleet, drill into any repo or PR or CI run, and act — merge, approve, checkout — without ever leaving the terminal.

You met it for a moment in Chapter 1. Now that you have a real fleet, let’s take the full guided tour. Open it and follow along.

The hawser TUI cockpit dashboard

Mission control for the whole fleet — read, drill, and act without leaving the terminal.

🎯 In this chapter, you’ll learn to…

  • Open the cockpit with bare haw (or haw dash –demo to explore offline).
  • Read the live fleet grid — the same columns as haw status, refreshing themselves.
  • Work the core loop: read → drill (Enter) → act → back (Esc).
  • Act from the home row: sync, mark, run, filter, browse files, and jump to the PR / CI / governance views with the digits 17.
  • Open a view’s context actions menu with a — merge, approve, checkout, request-PR, land — each confirm-gated.
  • Browse any repo’s files at any branch, tag, or SHA — local or straight from the forge, no checkout.
  • Use the command bar (:) that mirrors the CLI you already learned.

Your mission control: the fleet grid, drill-downs, PR/CI views, and keyboard actions — all in the terminal.

🚁 1. Open it

Run haw with no subcommand:

haw

Just want to explore without a real workspace or network? Use the built-in demo controller — it’s populated with canned repos, PRs, and CI runs, so every view has something to show:

haw dash --demo

Either way you land on the fleet grid — the cockpit’s home screen.

📋 2. Read the fleet grid

 haw ▸ ~/work/gateway ───────────────────────── stack: gateway   lock: ✓   repos: 3/3
──────────────────────────────────────────────────────────────────────────────────────
   REPO        BRANCH ▲      HEAD       DIRTY   DRIFT   ↑ / ↓    MERGE
   kernel      v6.1.2        a1b2c3d4     ·       ·      0 / 0     —
 ◉ hal         main          9f8e7d6c    yes      ·      2 / 0     —
▸⚠ app-mqtt    release/2.x   4d5e6f7a     ·      DRIFT   0 / 5     —
──────────────────────────────────────────────────────────────────────────────────────
 hal  ›  path hal/   branch main (ahead 2)   dirty   locked 9f8e7d6c   grp firmware
──────────────────────────────────────────────────────────────────────────────────────
 [s]ync [f]iles [x]shell [!]exec [/]filter [p]roblems [a]ctions [1-7]views [:]cmd [?]help

This is haw status, alive. Each row is a repo; the columns are the same ones you already know — branch, HEAD, dirty, drift, ahead/behind. The is your cursor, marks a selected repo, and flags a problem (like the drift on app-mqtt). The grid auto-refreshes about every 5 seconds while idle — never while you’re typing — and F5 / Ctrl-R refresh on demand.

Move with / (or k/j), exactly like Vim.

🔬 3. Drill in — the core loop is read → drill → act

Put the cursor on a repo and press Enter. You drill into that repo’s Git detail: branch, SHA, working-tree status, recent log, diffstat, remotes. Press Esc (or b) to come back up a level.

That’s the rhythm of the whole cockpit: read the grid → drill into a thing → act on it → back out. You’re never more than a keystroke from detail or from action.

⌨️ 4. Act on the fleet from the home row

Single keys on the cursor row do things. The essentials:

KeyDoes
ssync — the marked repos if any, else the cursor repo, else the stack
fbrowse the repo’s files — local disk or straight from the forge
xdrop into a shell in that repo (exits the cockpit)
!run one command (exec) in the repo, in its detail view
/fuzzy filter the grid live — /knl narrows to kernel
pproblems-only view — just the repos that need attention
Spacemark / unmark the cursor repo ()
rrun a command — across the marked repos if any, else the whole fleet
ggoto — quit and print the cursor repo’s path (cd "$(haw dash)")

Git-fetch, switch-stack, and lock moved to the command bar — :fetch, :stack (picker) or :stack NAME, and :lock. One key you’ll use everywhere is a — the actions menu. It opens a little popup listing exactly the actions the current view supports, each with its own sub-key; pick one and any write action (merge, land, …) still asks you y/n first. Views with no actions just say so.

Tip: Marks are the cockpit’s superpower. Press Space on a few repos, then s (sync) or r (run) acts on just that set. It’s how you do a surgical fleet operation without touching a manifest.

🌐 5. The network views — PRs, CI, and acting on them

View-switching is one keystroke: the digits 17 jump straight to a view from any top-level list. The network ones load on demand (nothing hits the network until you ask):

KeyView: alias
1fleet:fleet
2changesets:changesets
3PR/MRs — every open PR/MR across the fleet:prs
4CI runs — recent runs, live progress:ci
5tree:tree
6governance — plugins, SBOM, findings:governance
7plugins:plugins

Inside the PR/MR (3) or CI (4) views, Enter drills into detail — a PR’s reviewers and checks, or a CI run’s jobs and live progress. Press d to read a PR’s diff, l for a CI run’s logs, and f to browse a PR’s changed files. (A CI log that the forge has aged out — GitHub returns 410 — renders honestly as “logs unavailable — expired or empty” rather than an error.)

To act, press a for the actions menu. In the PR/MR view it offers:

Sub-keyDoes
mmerge the PR/MR on its forge
aapprove the PR/MR
ccheckout the PR branch locally

Every write is confirm-gated with a y/n so you never merge by fat-finger. o opens the cursor row in your browser. So the full cross-forge flow from Chapter 5 — see PRs, approve, merge — is right here, keyboard-only, all under a.

📂 6. Browsing files & branches — any ref, local or forge

Press f on any repo to open its file browser — a read-only view (it never stages or commits, only reads). Three keys turn it into a proper code explorer:

KeyDoes
Ttoggle the flat one-directory list ⇄ a navigable tree (/ to expand/collapse, /Enter expand, collapse)
rref picker — pick a branch or tag from the list, or type any SHA; the view reloads as of that ref and the header shows @ <ref>
eedit the file under the cursor in your $EDITOR (local files only)
Rtoggle local disk ⇄ the forge

The payoff: with r you can read a file as it exists on any branch of the remote — across GitHub, GitLab, or Bitbucket — without checking anything out. Point at a colleague’s feature/x branch, read the file straight from the forge API, and never touch your working tree. e is the one exception to read-only: it hands the file to your editor for a quick local fix, then reloads the listing.

💬 7. The command bar — one language for CLI and TUI

Press : to open the command bar (the command palette). Its verbs mirror the CLI you already learned, and the status line echoes the exact command each one runs — so the cockpit doubles as a way to discover the CLI:

:sync              sync the current stack
:grep TODO         fleet-wide grep
:switch platform   switch to another stack
:change land FEAT-42
:theme nord        change the skin live

Learn one, know both. :name also jumps the cursor to a repo by name.

🎨 8. Two more views, and themes

  • 7 (:plugins) — the Plugins view: every available plugin (manifest [plugins] keys unioned with haw-* executables on your PATH); Enter runs one and shows its output in a panel. You’ll build one that lands here in Chapter 8.
  • :errors (:err) — the Errors view: a rolling log of this session’s failures, so a transient error never scrolls away before you can read it.

Themes. Seven built-in skins — classic, catppuccin (default), dracula, nord, gruvbox, solarized, monochrome. classic is a neutral, standard-ANSI look that reads on light and dark terminals alike. Type :theme with no argument to open an interactive picker (j/k to move, Enter to apply); the chosen skin is applied live and saved to your config. :theme nord still switches directly. Set one at startup with HAW_THEME=nord haw, and NO_COLOR forces monochrome.

Make it yours — ~/.config/haw/config.toml. Optional and forgiving (a missing or partial file just uses defaults). Set a startup theme, the e-key editor, a collapsed header, and the idle-refresh cadence — plus remap a safe subset of action keys:

[ui]
theme = "classic"        # startup skin
editor = "nvim"          # the `e` key's editor ($VISUAL/$EDITOR still win)
compact_header = false   # start with the one-line header
refresh_secs = 5         # idle auto-refresh cadence (2–60)

[keys]                   # remap: sync, goto, run, shell, files, problems, watch
sync = "s"

The pickers write this file for you: :editor (no arg) lists the editors on your PATH, and :compact toggles the collapsed header — each persists your choice. The frozen globals (j, k, :, /, ?, q, b, space, g, w, digits) can’t be rebound; an invalid remap is dropped with a startup note, and the header hints always show the key that’s actually live.

Press ? any time for the help overlay, and q (or Ctrl-C) to quit.

Tip: Every heavy action runs on a background worker, so the UI never freezes while a sync, a fetch, or a forge call is in flight. Keep navigating.

🙌 Your turn

No workspace or network needed — the demo controller has everything to poke at:

  • Launch haw dash –demo. Move with /, then press Enter to drill into a repo and Esc to come back — feel the read → drill → act → back rhythm.
  • Press Space to mark a couple of repos (watch the ), then / to fuzzy-filter the grid. Press 3 for PRs and 4 for CI, then a to see the actions menu. Press ? for the help overlay.
  • Press f on a repo to browse its files, then T for the tree and r to read a file as of another branch or tag. Press b to come back.
  • Press : and type :theme nord. The skin changes live — and the status line echoes the exact command, so the cockpit is teaching you the CLI as you go.

✅ Recap

  • Bare haw (or haw dash --demo) opens the cockpit — a live haw status you can act on.
  • The loop is read → drill (Enter) → act → back (Esc).
  • Fleet keys: s sync, f files, x shell, ! exec, / filter, p problems, Space mark, r run, g goto, a actions.
  • View jumps are the digits 17: 1 fleet, 2 changesets, 3 PRs, 4 CI, 5 tree, 6 governance, 7 plugins. In PRs/CI, a (actions) does merge/approve/checkout (confirm-gated), d diff, l logs, f PR files.
  • File browser (f): T toggles tree, r picks a branch/tag/SHA (read any ref, local or forge, no checkout), e edits locally, R toggles local ⇄ forge.
  • : is a command bar (palette) mirroring the CLI; :plugins and :errors reach those views; seven themes (incl. classic) via :theme / HAW_THEME, an interactive :theme/:editor picker, and a ~/.config/haw/config.toml for themes, editor, display options, and custom keybindings.

👉 Next

You’ve seen the whole cockpit read the fleet. Now the signature move it drives — shipping one feature across many repos as a single coordinated changeset → 5. Changesets across repos.