Skip to content

feat: builder tui — a terminal cockpit for agent sessions, tmux, git and machine load - #15

Closed
Lutherwaves wants to merge 5 commits into
mainfrom
feat/tui
Closed

Lutherwaves wants to merge 5 commits into
mainfrom
feat/tui

Conversation

@Lutherwaves

@Lutherwaves Lutherwaves commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds builder-tui (skill tui), a long-running terminal cockpit for a machine that runs many AI coding agents. Closes #14.

One static Go binary for Linux, macOS and Windows (Bubble Tea v2, Lip Gloss v2, Bubbles v2, ntcharts) that you leave open in a tmux window. It has six panels:

  1. Sessions. Every agent process mapped pane → process → worktree, from the pane the agent records in its session file, else TMUX_PANE in its environment, so a re-parented process still finds its pane. Rows name the tmux place as the status bar does (session:window.pane and the window name). Shows busy/idle, idle time, context use from the transcript tail (the window is 1M when the session's model setting ends in [1m]), 30-minute burn, CPU of the whole process tree, and a compact / clear suggestion with its reason.
  2. Machine. Per-core CPU, load, PSI, memory and swap, network and disk rates, a TCP-connect latency probe, package temperature, CPU power limits with drift alerts, GPUs (nvidia-smi), containers, and the CPU share of named container groups.
  3. Procs. Top processes attributed to their owner (pane and session, container, or system). Flags detached busy loops: a shell re-parented to init or a user service manager that burns more than 80% of a core for 30 s. It names the pane that started it.
  4. Git. Per checkout an agent uses: dirty paths, default branch behind its remote, worktrees, and which are merged (PR data via gh, so squash merges count), clean including untracked files, and unused. Also an estimate of the cores agents spend running git there, taken by sampling running git processes per checkout.
  5. Recs. A ranked list. Every item carries its evidence and an action. A finding with no fix stays an alert.
  6. History. 24 h of CPU, load, pressure, temperature, memory and swap. It comes from the cockpit's own append-only CSV, plus any CSV with a ts column.

Safety. Read-only by default. Every action shows its exact argv first. Enter runs only non-destructive ones (jump to a pane, open a shell, git pull --ff-only). Destructive ones need x and then a typed y; any other key cancels. They are: kill, git worktree remove without --force, typing /compact or /clear into a session whose status is exactly idle, and git pull --ff-only (with no terminal prompts and a timeout). Each step carries a guard that is checked again right before it runs: the same pid and start time, a worktree still free of changes and processes, a session still idle. A step whose guard fails is skipped and reported. No shell strings are built from data.

For agents. builder-tui status prints JSON from the snapshot the running cockpit writes each sample, or samples on its own. --text gives a short summary with the exact commands.

Cost. Runs at nice 19. Cheap counters every 2 s, the process table every 10 s, docker and nvidia-smi every minute, git every 5 min. Idle worktrees are re-checked at most every 2 h, since git refuses a dirty removal anyway. The renderer is capped at 15 fps. On a workstation with ~1,100 processes, 25 agent sessions and ~190 worktrees, it used 0.60% of one core itself plus 0.24% for the commands it runs, so 0.84% in total over 10 minutes, with 22 MB RSS. It took four profiling rounds to get there (from 1.7%).

Config. Machine goals live in a local ~/.config/builder/tui.toml, never in the repo. skills/tui/config.example.toml documents every key (thresholds with "for" durations, expected power limits, orphan rules, container groups, git repos, history sources, an alert hook argv).

Packaging, matching the repo. skills/tui/SKILL.md and setup.sh sit beside the tool. setup.sh downloads the release binary for this plugin version and verifies its SHA-256, or builds from source. release.yml gains a tui-binaries job that runs when release-please cuts a release and attaches Linux, macOS and Windows binaries (amd64 and arm64) plus a checksum file. validate.sh (and CI, via setup-go pinned by SHA) now runs gofmt, vet, tests, a fixture smoke run and macOS/Windows cross-builds.

Type of change

  • feat — new feature
  • fix — bug fix
  • docs — documentation only
  • refactor — code change that neither fixes a bug nor adds a feature
  • ci — CI/build change
  • chore — tooling/meta

Checklist

  • PR title follows Conventional Commits
  • bash scripts/validate.sh passes locally
  • Affected skills/*/SKILL.md have valid YAML frontmatter (name + description)
  • README updated if user-visible behavior changed
  • No machine-specific paths, tokens, or personal identifiers committed (test data is a generic fixture machine)
  • Tested locally: installed with setup.sh and run in a tmux window on a live workstation

Notes for reviewer

  • Tests. Unit tests per package run against testdata/machine, a fixture /proc, /sys, home and tmux listing. The orphan, owner and rate tests copy it and change counters between samples. gitscan tests build a real temporary repo with merged, untracked, in-use and open worktrees. A Bubble Tea smoke test runs the real program against the fixtures. The confirm flow is tested so that Enter never runs a destructive action.
  • Verified live before opening: pane mapping for 25 of 25 sessions against an independent ps ancestry walk; a deliberately leaked while :; do :; done re-parented to the user service manager was flagged with its pane, Enter cancelled, and x then y killed it.
  • Platforms. Linux reads /proc and /sys directly. macOS and Windows read through gopsutil (no cgo) behind the same procfs.Host interface; a test checks that it agrees with /proc on Linux. Pressure, power limits, temperature and container CPU are Linux only. Windows has no native tmux, so the Sessions panel needs WSL there. On Linux, gopsutil cost about 20 times the /proc reader per process scan, which is why Linux keeps its own reader; the macOS cost has not been measured on real hardware yet.
  • Git reads each repo's default branch from its remote's HEAD (git.main overrides), so master or develop repos get behind counts and merged worktrees too.
  • An independent adversarial review ran before opening. Every finding is fixed here: the re-checks for a reused pid, a stale worktree and a non-idle pane, a second sample loop after an action, the release tag format, git pull behind confirm, the per-session window guess, and a power zone that appears late.
  • Ignored files go with a removed worktree (git's behaviour). The evidence text says so, and branches and commits stay.
  • Not in this PR: the watch-limits projection inline (the issue's Limits panel). It already runs as its own watcher.

🤖 Generated with Claude Code

Lutherwaves and others added 5 commits October 6, 2026 00:23
…and machine load

A single static Go binary (Bubble Tea v2) that a builder leaves open in a
tmux window: agent sessions mapped to panes with context use, machine load
and power-limit drift, detached busy loops with the pane that leaked them,
git dirt and removable worktrees, a ranked list of what to do with the exact
command for each, and 24 h of history. Read-only by default; destructive
actions need a typed y and re-check their guards right before running.
`builder-tui status` gives agents the same state as JSON.

Closes #14

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pane id (%12) never appears in the tmux status bar, so the Sessions
table now shows session:window.pane, plus the window name when the
terminal is 100 columns or wider. The detail line keeps the pane id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The transcript names the model without its [1m] suffix, so a 1M session
under 200k tokens was measured against 200k and showed about five times
its real context use, with a false compact suggestion. The window now
comes from the model the process was started with: --model, then
ANTHROPIC_MODEL, then the project and user settings, the order Claude
Code uses. The past-200k rule stays as the fallback.

Also widens the tmux column so the selection marker does not cut the
place short.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A repo whose default branch is master, trunk or develop got no behind
count and no merged worktrees, because every git query used refs/heads/main.
The branch now comes from the remote's HEAD per repo; git.main in the
config still overrides it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sampler now reads the machine through a small procfs.Host interface.
Linux keeps the /proc reader (and the fixtures use it on every system);
macOS and Windows get internal/host, built on gopsutil, which reaches the
system APIs without cgo, so every build stays one static binary.

- Sessions find their pane from the agent's own session file first, then
  TMUX_PANE, then the process tree: the session file works where another
  process's environment cannot be read.
- Lowest priority is nice 19 on Unix and the idle priority class on
  Windows.
- Confirmed steps run with a 2-minute timeout and no credential prompts
  inside the cockpit, instead of through `env` and GNU `timeout`, which
  macOS and Windows lack.
- A missing tmux is no error: Machine, Procs, Git and History still work.
- Releases attach linux, darwin and windows binaries for amd64 and arm64;
  setup.sh installs on macOS (shasum when sha256sum is absent); validate.sh
  cross-builds darwin and windows.

A test checks that the gopsutil reader agrees with /proc on Linux. Pressure,
power limits, temperature and container CPU stay Linux-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Lutherwaves

Copy link
Copy Markdown
Owner Author

This gave birth to matchblox.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: builder tui — a long-running terminal cockpit for agent sessions, tmux, git and machine load

1 participant