hands

Docs · Guides

The TUI

hands ui is the operator’s seat — the whole kitchen in one terminal screen, with a chat plane that talks back and a daemon underneath so the fleet survives the view. Opt-in, never required: bring-your-own-session stays a first-class way to run every role.

Planned

Dev checkout only, for now

Everything below runs today — from a clone of the repo. hands ui and hands daemon are built by cd engine && npm run build:tui, which is not part of the standard build, so neither one ships in the plugin or in the curl | sh install yet.

From a normal install, hands serve is the operator’s view.

The board

The default screen: the line (state · focus · ticket · token-burn sparkline · context · attestation, one row per station), the rail grouped by dish, needs you (escalations, declined attestations, pending approvals), the menu with criteria progress, and an other kitchens panel — every other handle writing to the same books. Captured live — this is a real kitchen, not a mockup:

hands ui — the board




  hands · hands                                           menu: 2 · needs you: 0 · rail: 0 · 21:22

 THE LINE
  expo        idle           ▁▁▁▄▃▁▁█   —  ctx ✓ attested
  sous        idle           ▁▁▁▁▁▁▁▁   —  ctx ✓ attested
  station-1  books                  idle           ▁▁▁▁▁▁▁▁   —  ctx ◷ expired
  station-2  dashboard              idle           ▁▁▁▁▁▁▁▁   —  ctx · unattested
  station-3  bus-core               idle           ▁▁▁▁▁▁▁▁   —  ctx · unattested
  station-4  website                idle           ▁▁▁▁▁▁▁▁   —  ctx · unattested
  station-5  cli                    STATION-5      ▁▁▁▁▁▁▁▁   —  ctx · unattested

 THE RAIL                                      NEEDS YOU
  nothing on the rail                           nothing — have a great shift, chef

 THE MENU                                                    OTHER KITCHENS
  1. site-pages (4/7)                                         just us tonight
  2. crafts-that-compound (1/6)

 24h burn: 1k out  sous 0  s1 0  s2 0  s3 0  s4 0

 ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
  [s]ous  [1-9] station  [b]ook  [t]okens  [q]uit                                                    
 ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
keygoes to
sthe sous pane — the conversation
ethe expo's action feed (+ a steer input)
athe approvals queue — y / n answers the oldest
1–9station drill-in: worktree, tickets, usage, transcript tail
bthe book — today's journal
ttoken burn, context, sub-agent usage
escalways back to the board

The sous pane

The pane that talks back. The sous holds a real bus identity — its tool calls run as agent sous, so composing tickets, reading the board, and escalating to you are the genuine article, not roleplay. Gated tools raise an inline approval card; a verdict is a bus record, answerable from any view, first answer wins. Auth rides your own claude login — hands never holds an API key.

hands ui — the sous pane
 you ▸ whats the state of the kitchen tonight chef
  ⚙ ToolSearch query, max_results
  ⚙ hands_board full
  ⚙ hands_peers 
  ⚙ hands_receive mark_read, wait_seconds
 sous ▸ Quiet line tonight, chef. State of the kitchen:

 **On the pass**
 - Rail is empty — no active tickets, no open questions, nothing in my inbox.
 - Expo is up and alive on main (last active minutes ago). I'm up.
 - All five stations are **dark** — books, dashboard, bus-core, website, cli all offline since Aug 5, 
 inbox monitors dead. Nobody to fire to until stations are relit.

 **The menu** (marked stale — last set a while back)
 1. `site-pages` — 4/7 criteria done
 2. `crafts-that-compound` — 1/6 criteria done

 **Last service** (Aug 5, all merged by expo): CLI launcher + doctor/logs/restart (#101), dashboard 
 token-burn/live MCP log (#95), hosted-mode transport hardening (#93/#85), expo stale-ticket cleanup
 (#94), books MCP server (#66).

 **My read:** kitchen's been cold five days. If we're cooking tonight, two calls to make — refresh the 
 menu (it's stale; site-pages is closest to plated at 4/7), and relight whichever stations the night's
 work needs. Say the word and I'll compose tickets against site-pages' remaining 3 criteria for the
 expo to fire.
 ready · $0.23 this session
 ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
                                                                                                    
 ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯

 ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
  [esc] board  ·  [enter] send  ·  typing goes to the sous                                           
 ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯

The daemon

hands daemon start gives the kitchen a supervisor that must not die with a pane: one wake watcher over the notify files (replacing per-session tail -F monitors and /loop pacing), the timers, a headless expo whose every action lands in the [e] feed — and, with stations.managed: true, your provisioned stations as headless workers: worktree locked, honestly attested through the same dispatch gate as everyone else, cooking on real tickets. Close the terminal; the kitchen keeps cooking.

hands daemon start     # supervisor: wake watcher, timers, managed expo, dashboard
hands ui               # attach the view — killing it never kills the fleet
hands daemon status    # who's managed, last event, log size
hands daemon stop

Station drill-in

Station details are available but obscured by default — one keypress deep: the worktree and branch, held tickets, usage with a compaction ETA, the transcript tail, and the hands attach escape hatch into the real session.

hands ui — station drill-in


  hands · hands                                           menu: 2 · needs you: 0 · rail: 0 · 21:22

 station-1  books  ◷ expired

 the trunk has advanced since it attested

 WORKTREE
 /home/michaelphillips/.hands/worktrees/hands-a7e05ca8/station-1 · ? · pid 1157308

 TICKETS
  none held

 USAGE
 ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 0 out · 0 cache-read (24h)

 RECENT ACTIVITY (idle 5d)
  5d Bash {"command":"grep -rn \"runPublish\\|Stop.*hook\\|\\\"Stop\\\
  5d result engine/src/publish.ts:16: * The Stop-hook workhorse. Derives
  5d Read {"file_path":"/home/michaelphillips/.hands/worktrees/hands-a
  5d result 1 { 2 "description": "hands passive standup: turn-end status
  5d Read {"file_path":"/home/michaelphillips/.hands/worktrees/hands-a
  5d result 1 import { execFileSync } from "node:child_process"; 2 impor
  5d Bash {"command":"echo \"=== handle dir ===\"; ls -la /home/michae
  5d result === handle dir === total 12 drwxrwxr-x 3 michaelphillips mic

 attach your own terminal: hands attach station-1

 ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮
  [esc] board  [s]ous  [b]ook  [t]okens  [q]uit                                                      
 ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯