Skip to content

The Dashboard

Run wf with no command to open the dashboard — an interactive TUI ledger of every project and its workspaces, with live git status, a scrollable diff viewer, and actions wired straight to the engine. It works in any terminal; when stdout isn't a TTY (e.g. wf | cat), wf prints the plain list instead so it stays scriptable.

sh
wf            # open the dashboard (on a TTY)
wf dashboard  # explicit; aliases: wf dash, wf ui

Here's the ledger layout — projects as headers, workspaces beneath, with a legend and a context-sensitive help line:

wf — dashboard
WorkFlow — dashboard
❯ acme-api (2) ~/code/acme-api
branch state behind|ahead diff base
development clean
├─ 🤖 feature/login active ↓0|↑3 +84 -12 * development
└─ fix/cache-key clean ↓1|↑0 +0 -0 development
dotfiles (1) ~/code/dotfiles
branch state behind|ahead diff base
main clean
└─ tmux-theme active ↓0|↑1 +20 -4 main
🤖 working waiting active clean base tmux open +added -removed * uncommitted
↑/↓ move · enter diff/menu · a add · e edit · o config · t term · c copy · m merge · x rm · r refresh · q quit

About the panel above

The panel is a styled, hand-built stand-in for the real layout — the project header, the base row, a workspace with its agent-status icon, and the legend and help line. Genuine captures of the live lipgloss dashboard can be generated with the procedure in docs/capture/ — capture target: dashboard-ledger.

Reading the ledger

Each project is a block: a header line (name (count) path), then the project's base checkout on its own row, then its workspaces as aligned tree children — all under one dim column heading:

ColumnMeaning
(agent)The live agent-status icon — working / waiting — when an agent is active in the workspace; blank when idle
/ active (green) — holds work not yet in base · clean (blue) — merged, nothing outstanding
branchThe workspace's branch name (its identity)
stateThe word active or clean
behind|aheadCommit gap to base: commits on base this branch lacks, commits it has on top
diff+added -removed lines vs base, with a trailing * when the working tree is dirty
baseThe base branch this workspace merges into

A trailing marks a row whose tmux window is open right now — derived live on every refresh. The selected row is highlighted and prefixed with .

The base row

Every project shows its base checkout — the repository root — on its own row, marked with a , listing the branch the root is currently on and its clean/dirty state. (The ahead/behind, diff, and base columns are blank for it.) It makes the trunk a launch target without first creating a worktree: the launch keys act on it just like a workspace —

  • t opens a tmux window on the base branch at the project root,
  • e / o open it in an editor,
  • c copies the root path,
  • Enter shows the root's uncommitted diff.

Merge and remove don't apply to the base row (it isn't a workspace).

Glyph legend

The legend beneath the ledger keys every glyph, including the active agent-status icons (shown here with the emoji preset; the default is Nerd Font):

🤖 working   ⏳ waiting   ● active   ○ clean   ▣ tmux open   ↓behind|↑ahead vs base   +added -removed   * uncommitted

Keybindings

Ledger (default)

KeyAction
/ k, / jMove the cursor
g / Home, G / EndJump to top / bottom
EnterOn a workspace: its diff. On a base row: the root's uncommitted diff. On a project header: the project menu
dView the selected workspace's diff (same as Enter, but no menu on a header)
aAdd a workspace in the selected project (opens a branch-name prompt)
eEdit — open the editor: autolaunch the project default if set, else a picker
oConfigure the editor — always opens the picker (set the default / autolaunch)
tJump to the workspace's tmux window (tmux only)
cCopy the workspace path to the clipboard
mMerge the workspace (asks to confirm)
xRemove the workspace (asks to confirm; f on the prompt forgets instead)
rRefresh status now
q / Ctrl+CQuit

The launch keys (e / o / t / c / Enter) act on the base row too, targeting the project root. The help line at the bottom adapts to your environment — the t term hint only appears inside tmux.

Diff viewer

Selecting a workspace opens a scrollable, syntax-colored diff against its base (additions green, deletions red, hunks cyan, metadata dim):

KeyAction
/ Scroll
rReload the diff
q / EscBack to the ledger

When a workspace has no changes against base, the viewer shows (no changes against base).

Add prompt

Pressing a opens an inline branch-name input: type a name and press Enter to create the workspace, or Esc to cancel.

Confirmations

Merge and remove ask for a y/n confirmation. Remove is risk-aware — it inspects the workspace first and warns in red when removal would discard uncommitted changes or unmerged commits, and reassures in green when the branch is safe to drop:

Remove acme-api/feature-login? This discards uncommitted changes and 3 unmerged commits — work will be lost. Are you sure? [y/n]

The remove prompt also offers f to forget the workspace instead: unregister it but leave its files and branch on disk. It's the way out when a removal is blocked because the worktree holds files wf can't delete (for example root-owned files left by a Docker container) — see Troubleshooting.

Managing projects

Press Enter on a project header row to open a popup action menu for that project:

KeyAction
/ Move between options
EnterChoose the highlighted option
Esc / qDismiss the menu

The two options are:

  • Rename — opens a text input pre-filled with the current name; edit it and press Enter to rename the project (its worktrees are retargeted to the new name). Same as wf project rename.
  • Delete — unregisters the project from WorkFlow (the repository on disk is untouched). It asks to confirm, warning in red when the project still has registered workspaces that would be dropped.

Live refresh

While you're idle on the ledger, the dashboard re-derives git status (and the open-window markers) every 4 seconds, so edits in a workspace show up without pressing r. The cursor stays on the same workspace across refreshes.

Actions run the real CLI

The dashboard isn't a separate code path — its actions invoke the same engine as the CLI. Creating, merging, and removing briefly suspend the TUI to stream git and setup output, then return you to an updated ledger. Anything you can do here, you can also script with the commands.

WorkFlow — orchestrate git worktrees from one cockpit.