Skip to content
mu-crewPublic

About

tmux, ssh and agent-harness config that wires mu, murmur and mule together

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

26 Commits

Folders and files

Repository files navigation

mu-crew dotfiles

tmux, ssh and harness config that makes mu, murmur and mule work as one setup: agent state in your tab bar and pane borders, a status pill, keys for the picker, side panel and dash, and the hooks that clear an agent's badge when you look at it.

It adds wiring, not a theme. Your status line, colours and other keys stay yours; you place the pieces where you want them.

Requirements

  • tmux 3.3 or newer.
  • murmur, for anything agent-related. Without it the keys print "murmur is not installed" and the formats stay empty.
  • A Nerd Font for the default glyphs. No Nerd Font? See Glyphs.
  • fzf for the workstream picker, Python 3.11 or newer for the poller.

Install

Clone it anywhere and source it from ~/.tmux.conf:

git clone https://github.com/mu-crew/dotfiles ~/.local/share/mu-crew-dotfiles
source-file ~/.local/share/mu-crew-dotfiles/tmux/mu-crew.conf

# Place the pieces:
set -ag status-right '#{E:@mu_crew_pill}'
set -g window-status-format ' #I #W#{E:@mu_crew_window_glyph} '
set -g window-status-current-format ' #I #W#{E:@mu_crew_window_glyph} '

Pin a commit if you manage dotfiles declaratively, and move it forward when you update murmur: both sides read the same tmux options.

What sourcing it does

Each part below is on by default. Set its flag to off before sourcing to skip it; sourcing again with a flag off removes what that part set.

Flag Part
@mu_crew_hooks Focus hooks
@mu_crew_keys a / C-m / G / u
@mu_crew_session_keys Forwarding s / g / T to tsesh
@mu_crew_pane_border Pane border format
@mu_crew_probes Poller probes; none runs no poller (see Poller and probes)
set -g @mu_crew_keys off
set -g @mu_crew_pane_border off
source-file ~/.local/share/mu-crew-dotfiles/tmux/mu-crew.conf

The formats (pill, glyphs, pills from probes) need no flag: they do nothing until you place them.

Focus hooks. Selecting an agent's pane, window or session runs murmur clear for that pane, which acknowledges a done or blocked badge. Without these a badge never clears. Clear runs only when the pane, its window or its session shows done, blocked, error or crashed, so a switch with no badge in sight starts no process. They use hook index 42, so hooks you set yourself are kept.

Keys, under the prefix:

Key Does Option
a Agent picker popup, across every machine murmur peers with @mu_crew_key_pick
C-m Toggle murmur's side panel in this window @mu_crew_key_sidepanel
G Toggle the murmur dash: go to it (opening one if none runs), or back from it @mu_crew_key_dash
u Toggle between a workspace session and its mu workstream session (mu-<name>) @mu_crew_key_workstream
s / g / T tsesh: session picker, last session, session at the pane's directory @mu_crew_key_session_{pick,last,root}

Set an option before sourcing to move a key, or set it to none to leave it unbound. The session keys are passed on to tsesh's own options, and tsesh binds them, so source this file before TPM runs and nothing is bound twice. Most terminals send the same code for C-m and Enter, so prefix Enter opens the side panel too.

Pane border. mu titles each agent's pane with the agent name and its tasks; the border shows that title plus murmur's live state. To keep your own pane-border-format, set @mu_crew_pane_border off before sourcing and add #{E:@mu_crew_pane_glyph} to your format.

Poller. One background Python process per tmux server keeps the enabled remote, memory, CPU, uptime, and muzzle options current. See Poller and probes.

Formats you place

Option Shows Reads
@mu_crew_pill Robot icon, then <count><glyph> per state, most urgent first, then the crew total. Empty when no agents exist. @murmur_count_*, @mu_crew_remote_*
@mu_crew_window_glyph One glyph for the window's most urgent agent state; the idle glyph for an agent window with no news @murmur_window_state
@mu_crew_pane_glyph · <glyph> for the pane's own state @murmur_pane_state
@mu_crew_muzzle_pill This host's muzzle slots: held/budget, then queued jobs, slow jobs (past their usual run time) and jobs queued 30 s or more, each hidden at zero. Empty when nothing holds or waits. Needs the muzzle probe. @mu_crew_muzzle_*
@mu_crew_mem_pill Memory use or macOS memory pressure @mu_crew_mem
@mu_crew_cpu_pill CPU use @mu_crew_cpu
@mu_crew_uptime Compact system uptime @mu_crew_uptime_*
@mu_crew_host_color This host's accent hex, the color murmur gives it everywhere. A value, not a format: use it in a style, #[bg=#{@mu_crew_host_color}] set once at source time

Read them through #{E:...} so the colour runs inside apply. They set no background, so they take the background of wherever you place them.

murmur also sets @murmur_session_state on each session. Session pickers can colour rows from it; tsesh does.

Glyphs

The defaults are Nerd Font glyphs, the same ones murmur dash draws, so one agent looks the same in every surface:

State Glyph Codepoint
crashed fa-times-circle U+F057
blocked fa-comment U+F075
done fa-check-circle U+F058
working fa-play U+F04B
waiting fa-hourglass-half U+F252
idle fa-moon-o U+F186
crew fa-users U+F0C0
agent md-robot U+F06A9

Without a Nerd Font these render as boxes. Set @mu_crew_ascii 1 before sourcing to use x ! + > - c ai instead.

To change one glyph or colour, set its option after sourcing: @mu_crew_g_<state> for glyphs and @mu_crew_c_<state> for colours (Catppuccin Mocha by default). The defaults sit between THEME BEGIN / THEME END markers, so a theme generator can rewrite them.

Poller and probes

The poller defaults to remote murmur counts, so an existing setup does not start new system probes. To enable more probes, set the space-separated list before sourcing the config:

set -g @mu_crew_probes "murmur_remote memory cpu uptime"
source-file ~/.local/share/mu-crew-dotfiles/tmux/mu-crew.conf

set -ag status-right '#{E:@mu_crew_mem_pill}'
set -ag status-right '#{E:@mu_crew_cpu_pill}'
set -ag status-right '#{E:@mu_crew_uptime}'

Each probe has its own interval. Set @mu_crew_<probe>_interval in seconds to change it. The defaults are 10 seconds for murmur_remote, 5 seconds for memory, cpu and muzzle, and 60 seconds for uptime.

The muzzle probe runs muzzle status --json (muzzle 0.2.3 for the slow counts; an older muzzle shows none) and writes @mu_crew_muzzle_*. muzzle decides what is slow. A failed call, or no muzzle on PATH, clears the options; the probe tries again on its next tick. Place #{E:@mu_crew_muzzle_pill} next to @mu_crew_pill.

Set @mu_crew_mem_min, @mu_crew_cpu_min, or @mu_crew_uptime_min to show a format only above that value. Memory and CPU thresholds are percentages. The uptime threshold is seconds. The formats use @mu_crew_c_mem, @mu_crew_c_cpu, and @mu_crew_c_uptime for their colours.

Linux memory reports used memory from /proc/meminfo. macOS memory reports a pressure score from vm_stat and memory_pressure, including compression and swap rates. CPU uses /proc/stat deltas on Linux and top on macOS.

The pid file is keyed by the tmux socket path. The loop exits when no tmux server answers on that socket; a server restarted on the same socket keeps it. Run tmux/scripts/mu-crew-poller --once to update enabled probes once for tests or debugging.

Why the pill costs nothing

tmux redraws the status line on every pane, window and session event, not only every status-interval. A 14-window session was measured redrawing 1.2 times a second. Anything a status line runs through #(...) runs that often, and murmur status is a Node start: as a #(...) it cost most of a CPU core.

So nothing here runs on a redraw:

  • murmur writes this host's counts into @murmur_count_<state> whenever an agent's state changes. The pill is tmux format arithmetic over those options.
  • Remote peers' counts come from tmux/scripts/mu-crew-poller: one loop per tmux server, started when the config is sourced. It runs murmur status --json every 10 seconds and writes @mu_crew_remote_<state> through tmux options. No peers or no murmur stops that probe without stopping other probes.

Keep it that way when you extend the config. A new format reads options; if it needs data from a program, a long-lived loop writes the data into an option. tests/test.sh fails if a format in mu-crew.conf contains #(.

ssh

ssh/mu-crew.conf is an Include for ~/.ssh/config:

  • a shared ControlMaster, so murmur can collect from a host that needs a second factor after you log in once;
  • what to do on a host with MaxSessions 1, where murmur, mule and your shell must not share one master;
  • mule's own socket, so long jobs never take murmur's slot.

Background: murmur's SSH.md.

Host colors

murmur gives every host one accent color: crc32 of its short hostname over eight Catppuccin accents. The dash, side panel and picker paint the host in it, and the notification hook gets it as MURMUR_HOST_COLOR. Sourcing mu-crew.conf runs tmux/scripts/mu-crew-host-color once and stores this host's accent in @mu_crew_host_color, so your status line can paint the host in the same color:

set -ag status-right '#[fg=#11111b,bg=#{@mu_crew_host_color},bold] #H #[default]'

The palette list and the hash are mirrored in murmur's src/dash-paint.ts; both sides pin the same value in a test.

Notifications

murmur/on-attention is a notification hook for murmur, which runs ~/.config/murmur/on-attention once for each new done, blocked, error or crashed. Link it there, or exec it from a hook of your own:

ln -s ~/.local/share/mu-crew-dotfiles/murmur/on-attention ~/.config/murmur/on-attention
OS Sends with Urgency
Linux notify-send -a murmur done is normal; blocked, error and crashed are critical
macOS terminal-notifier with the icon, else osascript none
  • Each notification carries a 128px icon: a rounded frame in the host's accent with the event kind's glyph in its color, so you can tell the host and the severity apart at a glance. murmur supplies all three (MURMUR_HOST_COLOR, MURMUR_GLYPH, MURMUR_KIND_COLOR). The host name in the body is in the same accent, where the notifier renders markup.
  • Icons render once with ImageMagick (magick) and a Nerd Font, and are cached in ~/.cache/murmur/. Without magick, a Nerd Font, or a murmur that sets the colors, the notification goes out without an icon.
  • A done from a crew (orchestrated) agent is skipped: the orchestrator reads it.
  • MURMUR_ICON_BASE overrides the icon's inner fill (default #1e1e2e) and MURMUR_ICON_FONT its font (default JetBrainsMono Nerd Font).
  • The notifier may scale icons down. mako's default is 64px; for a larger one: [app-name=murmur] then max-icon-size=72 in the mako config.
  • Test it: MURMUR_KIND=blocked MURMUR_AGENT=test MURMUR_HOST=$(hostname) MURMUR_HOST_COLOR='#cba6f7' MURMUR_GLYPH=$'\uf075' MURMUR_KIND_COLOR='#fab387' murmur/on-attention.

Codex, Cursor and opencode

pi reports to murmur from inside the agent. Codex and Cursor instead run a command when a turn ends, and opencode runs a plugin:

  • codex/config.toml: the notify line for ~/.codex/config.toml.
  • cursor/hooks.json: a stop hook for ~/.cursor/hooks.json.
  • opencode/plugins/murmur/tui.ts: an OpenCode 2 TUI plugin. Install it as ~/.config/opencode/plugins/murmur/tui.ts. It needs a directory of its own, because opencode skips a bare file in plugins/. It also needs @opencode/plugin 2.x installed in ~/.config/opencode.

These report attention only (done, blocked), not running, idle or crashes. The agent must run inside tmux.

Tests

tests/test.sh

Runs against an isolated tmux server with a fake murmur on PATH: keys and the none opt-out, the side panel key, glyph defaults and ASCII, the pill and window formats, the cheap-tick rule, probe formats, local probes, remote counting, the host color, and exit codes. python3 tests/test_poller.py covers the parsers and probe calculations; python3 tests/test_host_color.py pins the host color against murmur's.

Related

  • mu-crew: the org, with the stance and design rules these files follow.
  • tsesh: a session picker that shows murmur's session state.

Part of mu-crew. Written mostly by AI coding agents, with a human reviewing what ships, and built for running them.

About

tmux, ssh and agent-harness config that wires mu, murmur and mule together

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages