@jaggerxtrm/xtmux
tmux-native coordination, messaging, hooks, and Pi extensions for coding agents
Package details
Install @jaggerxtrm/xtmux from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@jaggerxtrm/xtmux- Package
@jaggerxtrm/xtmux- Version
0.2.3- Published
- Jul 28, 2026
- Downloads
- 264/mo · 264/wk
- Author
- jaggerxtrm
- License
- MIT
- Types
- extension
- Size
- 744.7 KB
- Dependencies
- 2 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./extensions/pi-agent-state.ts",
"./extensions/pi-auto-monitor.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
xtmux
xtmux is a Bash/tmux toolkit centered around an fzf-driven session + pane
picker. It is designed for people and agents who keep many tmux sessions open at
once: repos, worktrees, long-running agents, specialist sessions, shells, and
monitoring panes.
The picker is intentionally small and local: Bash + tmux + fzf, with git
used for repo annotations. bd/Beads is optional but unlocks richer task context
in previews and multiplexing workflows.
What xtmux offers today
Interactive tmux picker
- session and pane picker with fzf
- switch to a session/pane with
Enter - open a target in a popup client with
Alt-Enter - preview session/pane contents without attaching
- compact modes for smaller displays
- sessions-only vs expanded nesting toggle
- rename session/window inline
- kill pane/session with safety prompt for sessions
- bulk multi-select kill with
Space+Alt-X - root-level attention jumps
Alt-1..Alt-5and jump-back
Agent awareness
- pane-scoped
@agent_statewritten by hooks:runningneeds-inputdoneidleoff
- state badges in list rows:
[wait],[run],[done],[idle] - attention ranking keeps waiting/running agents at the top
- agent state is read live; list output is never cached as a whole
- optional fallback UI inference via
TMUX_PICKER_AGENT=1
Git/worktree awareness
- per-row repo/status annotations via
scripts/git-pane-status.sh - branch/status/path hints in session and pane rows
- idle/stale badge from tmux activity
- preview enrichment:
- conservative bead id derivation from dot-number names/paths such as
xtmux-rib.16 - bounded
bd showcontext when a bead is known - git branch + dirty count
- bounded
git diff --stat
- conservative bead id derivation from dot-number names/paths such as
- shared-worktree detection and
[shared-wt]warnings
Specialist session awareness
- detects
sp-*specialist sessions by name + live pane pid - groups specialists in a dedicated bottom section
- shows
[sp]and specialist role in the hot list path - enriches specialist preview with job/bead/role/state when discoverable
- avoids
sp ps,pgrep, andpsin the hot list path
Rich filters and list modes
- attention presets:
all,waiting,running - content filters:
repo:<substr>branch:<name>cmd:<agent|shell|bun>grep:<text>
- comma-separated clauses are ANDed
- unknown filter clauses are ignored defensively
- active
Ctrl-ffilter survives refresh/cache invalidation Tabtoggles nesting:- expanded = session rows + child pane rows
- sessions-only = dense session-only overview
Multiplexing/orchestrator primitives
These features were added for /multiplexing-style inter-agent coordination.
They do not replace Beads; they make it safer to discover, monitor, hand off,
and clean up tmux-based agent work.
- standardized
@agent_*metadata:@agent_state@agent_bead@agent_task@agent_prompt_file@agent_parent_session@agent_last_transition
wait-agent: requester-owned SQLite wait that blocks until an agent pane leaves working/running state;--consumeclaims a terminal wake once. A completed wake is replayed only while the target is idle — re-arming against a target that is working again always opens a fresh waitmonitor-agent/monitor-list/monitor-kill: durable background monitors linked to requester session and pane identitysafe-send-pointer: dry-run-first safe wrapper aroundtmux send-keys;--reply-to <messageKey>records a correlated reply only after successful injection; Claude targets receive the required delayed second Enterhandoff: generate/tmpprompt file + exact safe-send command for a beaddashboard: agent-readable TSV inventory for orchestratorsaudit: read-only hygiene report separating warnings from cleanup candidatesworktree-collisions: report sessions sharing one git checkout- opt-in command telemetry wrappers for
git,bd, andgh practions mux-help: concise multiplexing safety cheatsheet, also available with?inside the picker- typed SQLite state plus an append-only event journal for state/message/handoff/monitor/audit events
- SQLite-backed message channel between sessions/panes, with receipt ack separate from reply fulfilment
Operator quickstart
xtmux-obs health
xtmux dashboard sessions-only
xtmux message-send --to '$42' --to-pane '%7' --bead xtmux-demo.1 --text 'status' --json
xtmux message-list --for "$(tmux display-message -p '#{session_id}')" \
--pane "$TMUX_PANE" --expects-reply --json
A bead implies expectsReply:true; use --expects-reply=false for FYI-only
messages. message-ack records receipt only. Option A reads SQLite rows and
acks only after the Pi continuation is queued; a crash before ack replays the
message. The original recipient fulfils an obligation with message-reply --in-reply-to <messageKey> --text ..., or with safe-send-pointer --reply-to <messageKey> after successful pane injection.
SQLite is the source of truth at
${XDG_STATE_HOME:-$HOME/.local/state}/xtmux/observability.db. Set
XTMUX_OBS_V2=0 only for temporary legacy rollback or XTMUX_OBS_V2=shadow for
comparison; neither mode makes runtime marker files authoritative.
Files
| path | role |
|---|---|
bin/tmux-session-picker |
picker, preview, CLI commands, orchestration helpers |
scripts/git-pane-status.sh |
stable per-path git status line; also usable from tmux status bar |
scripts/agent-state.sh |
shared hook target that writes @agent_state and optional @agent_* metadata |
scripts/xtmux-monitor.sh |
opens a tmux monitoring terminal for dashboard/audit/events/messages/turns/telemetry |
extensions/pi-agent-state.ts |
pi extension for writing @agent_state on pi lifecycle events |
docs/agent-state-hooks.md |
hook setup and orchestration metadata reference |
docs/keys.md |
tmux keybinding snippets and collision notes |
docs/perf-audit.md |
performance notes and cache rationale |
git-pane-status.sh has a stable CLI/output contract. The picker calls it for
repo rows, and the tmux status line can call it directly.
Install
npm install --global @jaggerxtrm/xtmux
This installs the command suite, grouped Pi extensions under ~/.pi, and owned
Claude hooks under ~/.claude, including Stop-time parent FYIs and bounded inbox
reminders. Existing unrelated settings and xtrm-managed hooks are preserved. The
installer is idempotent and never opens a browser.
For upgrade, uninstall, conflict behavior, optional aicommit2 setup, and the
reusable changelog command, see docs/INSTALL.md.
A checkout can use the same installer directly:
./install.sh
The xtmux name
xtmux <subcommand> and tmux-session-picker <subcommand> are the same program:
same subcommands, same flags, byte-identical output. xtmux is the name to use in
new docs, skills and hooks; tmux-session-picker keeps working indefinitely, so no
existing call site, hook or live tmux pane needs to change.
Both entries must live in the same directory. The picker derives its repo root
from its own path as ${self%/bin/*} and does not resolve symlinks, so it looks for
the observability backend beside the installed command as xtmux-obs — which only resolves when
the entry sits in ~/.local/bin/ alongside ~/.local/bin/xtmux-obs. An xtmux placed
anywhere else resolves root to the wrong directory and cannot find the adjacent backend. The npm and checkout installers place both entries together; do not hand-copy only one entry.
Optional tmux cache-invalidation hooks:
./install.sh --tmux-hooks
Equivalent hook snippet:
set-hook -g 'session-created[90]' "run-shell '~/.local/bin/tmux-session-picker clear-cache'"
set-hook -g 'session-closed[90]' "run-shell '~/.local/bin/tmux-session-picker clear-cache'"
set-hook -g 'window-linked[90]' "run-shell '~/.local/bin/tmux-session-picker clear-cache'"
set-hook -g 'window-unlinked[90]' "run-shell '~/.local/bin/tmux-session-picker clear-cache'"
Suggested tmux bindings:
bind s display-popup -E -w 99% -h 97% "$HOME/.local/bin/tmux-session-picker"
# optional compact modes
bind g display-popup -E -w 99% -h 97% "TMUX_PICKER_MODE=compact-wrap $HOME/.local/bin/tmux-session-picker"
bind G display-popup -E -w 99% -h 97% "TMUX_PICKER_MODE=compact-nowrap $HOME/.local/bin/tmux-session-picker"
# optional root-level attention jumps
bind -n M-1 run-shell '~/.local/bin/tmux-session-picker attn-jump 1'
bind -n M-2 run-shell '~/.local/bin/tmux-session-picker attn-jump 2'
bind -n M-3 run-shell '~/.local/bin/tmux-session-picker attn-jump 3'
bind -n M-4 run-shell '~/.local/bin/tmux-session-picker attn-jump 4'
bind -n M-5 run-shell '~/.local/bin/tmux-session-picker attn-jump 5'
bind -n M-` run-shell '~/.local/bin/tmux-session-picker jump-back'
See docs/keys.md for copy-paste snippets and collision notes.
Tmux keys
| key | action |
|---|---|
prefix s |
open picker, default mode |
prefix g |
open picker, compact-wrap mode |
prefix G |
open picker, compact-nowrap mode |
Alt-1..Alt-5 |
jump to the 1st..5th waiting/attention pane |
Alt-` |
jump back to pane active before the last attention jump |
The attention jumps intentionally use root-level bind -n for one-keystroke
triage. If a foreground TUI needs Alt-digit, use the prefix-gated alternative
from docs/keys.md.
Fzf keys inside the picker
| key | action |
|---|---|
Enter |
switch client to highlighted session/pane |
Alt-Enter |
attach target in a popup client |
Ctrl-y |
approve/waiting-agent micro-action (y Enter) |
Alt-i |
interrupt pane (C-c) |
Ctrl-o |
prompt for one-line message and send it to pane |
Alt-r |
rename highlighted session/window |
Alt-x |
kill pane immediately; prompt before killing session |
Space |
mark/unmark row for bulk actions |
Alt-X |
bulk kill marked rows; session kills prompt, pane kills immediate |
Tab |
toggle nesting: expanded vs sessions-only |
Alt-p |
toggle wide preview window |
Ctrl-a |
all sessions/panes |
Ctrl-w |
waiting/needs-input attention preset |
Ctrl-e |
running/done attention preset |
Ctrl-f |
filter submenu: repo / branch / command / grep |
Ctrl-r |
refresh list; keeps active filter and nesting mode |
Ctrl-/ |
toggle preview pane |
? |
show multiplexing-safe delegation cheatsheet in preview |
CLI reference
Listing, filtering, preview, navigation
tmux-session-picker list [all|waiting|running|repo:..|branch:..|cmd:..|grep:..]
tmux-session-picker list-active
tmux-session-picker preview <type> <sid> <name> <target>
tmux-session-picker popup <type> <sid> <target>
tmux-session-picker jump <type> <sid> <target>
tmux-session-picker attn-jump <n>
tmux-session-picker jump-back
Filter grammar:
all | waiting | running
repo:<substr>
branch:<name>
cmd:<agent|shell|bun>
grep:<text>
Comma-separated clauses are ANDed:
tmux-session-picker list 'repo:xtmux,cmd:agent'
grep: captures pane text lazily only when the grep clause is active.
Picker UI helpers
tmux-session-picker filter-menu
tmux-session-picker filter-clear
tmux-session-picker prompt-label
tmux-session-picker mode-toggle
tmux-session-picker border-label
tmux-session-picker mux-help
filter and list-mode UI state live outside the git cache under the picker
state dir, so lifecycle cache invalidation does not reset the active UI state.
Act, rename, kill
tmux-session-picker act <type> <sid> <target> <approve|interrupt|message>
tmux-session-picker rename <type> <sid> <target>
tmux-session-picker rename-apply <type> <target> <name>
tmux-session-picker kill <type> <sid> <target>
tmux-session-picker kill-confirm <sid> <answer>
tmux-session-picker bulk-kill <rows...>
tmux-session-picker bulk-kill-confirm <answer> <sid...>
Orchestrator/multiplexing commands
# agent-readable inventory
tmux-session-picker dashboard sessions-only
tmux-session-picker dashboard expanded
# read-only hygiene report
tmux-session-picker audit
# wait for one target to complete a fresh working cycle and consume its wake once
tmux-session-picker wait-agent %42 --wait-for-transition --consume --timeout 30m --interval 30s
# requester-owned background waits
tmux-session-picker monitor-agent %42 --wait-for-transition --timeout 30m --interval 30s
tmux-session-picker monitor-list --json
tmux-session-picker monitor-kill <id>
# safe handoff primitives
tmux-session-picker safe-send-pointer %42 'leggi /tmp/task.txt e seguilo'
tmux-session-picker safe-send-pointer --yes %42 'leggi /tmp/task.txt e seguilo'
# Claude Code target: auto-double-Enter. Force one-Enter behavior with --no-double-enter:
tmux-session-picker safe-send-pointer --yes --no-double-enter %42 '/compact'
# Bypass the slash/tmp payload check for a short course-correction. Multiline and
# shell-substitution guards STILL enforced. Without --yes, prints a confirmation banner
# showing exactly what is bypassed:
tmux-session-picker safe-send-pointer --force-freeform %42 'stop and check the migration order first'
# Correlate only after successful injection:
tmux-session-picker safe-send-pointer --yes --reply-to msg-123 %42 'leggi /tmp/reply.txt e seguilo' --json
tmux-session-picker handoff --target %42 --bead xtmux-mux.9 --note 'NO push'
tmux-session-picker handoff --yes --target %42 --bead xtmux-mux.9 --note 'NO push'
# worktree collision report
tmux-session-picker worktree-collisions
# runtime identity, session/window/pane inventory, and agent output
tmux-session-picker context --current --json # who am I? (xtrm.runtime-origin.v1)
tmux-session-picker topology --json # complete host/session/window/pane snapshot
tmux-session-picker pane capture --pane %42 --lines 200 --json # live terminal tail
tmux-session-picker agent-last %42 # completed full agent turn
tmux-session-picker agent-last '$1495' --json # turn + runtime/bead metadata
# read-only NDJSON bridge over ssh — inspect a remote xtmux host with your own auth
ssh peer-host xtmux bridge --stdio # remote server, exchanges JSON-RPC on stdio
# event log
tmux-session-picker log emit custom.event pane=%42 bead=xtmux-team.1 text=hello
tmux-session-picker log tail 50
tmux-session-picker log query --type message.sent --bead xtmux-team.4 --since 1h
tmux-session-picker log query --after-id 1234 --limit 100 --json # cursor-paged
tmux-session-picker log follow --after-id 1234 --json # NDJSON stream
# SQLite-backed message channel: ack receipt, then reply explicitly
tmux-session-picker message-send --to worker --bead xtmux-team.4 --text 'blocked on data' --json
tmux-session-picker message-list --for worker --pane %42 --expects-reply --json
tmux-session-picker message-list --for worker --message-key <messageKey> --json
tmux-session-picker message-get <messageKey|messageId> --json # read-only body
tmux-session-picker message-ack <messageKey> --by worker --json
tmux-session-picker message-reply --in-reply-to <messageKey> --text 'resolved' --json
tmux-session-picker message-cancel --message-key <messageKey> --json
tmux-session-picker message-status <messageKey> --json
tmux-session-picker unread-count --for worker --pane %42 --json
tmux-session-picker obligations list --pane %42 --json # active reply obligations owned by this pane
# opt-in command telemetry; does not shadow git/bd/gh unless you alias it yourself
tmux-session-picker telemetry git -- commit -m 'message'
tmux-session-picker telemetry git -- push
tmux-session-picker telemetry bd -- close xtmux-team.7 --reason 'done'
tmux-session-picker telemetry gh -- pr create --fill
Important safety defaults:
safe-send-pointeris dry-run unless--yes/--sendis given.safe-send-pointerrejects:- working/running/busy/thinking targets
- multiline payloads
- backticks /
$()shell substitution - inline instructions that do not reference
/tmp/...or a slash command (bypass with--force-freeform; multiline + shell-substitution guards still enforced)
safe-send-pointerauto-appends a second Enter after 2s when the target'spane_current_commandisclaudeorclaude-*, because Claude Code's paste-detection consumes the first. Override with--no-double-enter(never send a second), or force it on other pane types with--double-enter.handoffis dry-run unless--yes/--sendis given.handoffrefuses working targets before writing the prompt-file.auditis read-only.message-sendcommits a message and receipt to SQLite and updates tmux unread options only as a best-effort projection. It does not inject text into panes.--beadimplies a reply obligation unless explicitly disabled. Acking the receipt never fulfils that obligation; only a correlated reply or owner cancellation does.- Reply and wait mutations require the live requester session and pane. A monitor owned by another pane, or one older than the obligation it is meant to cover, cannot satisfy the gate. Timeouts return
124; ownership, pane, endpoint, and duplicate-reply conflicts are structured errors with no partial mutation. telemetry git|bd|ghis explicit opt-in and forwards to the real command while logging start/end events.
Maintenance
tmux-session-picker clear-cache
tmux-session-picker install-hooks [picker-path]
Agent state hooks and metadata
See docs/agent-state-hooks.md.
scripts/agent-state.sh writes pane-scoped tmux options. Existing hooks can keep
calling only the state argument:
~/.tmux/scripts/agent-state.sh running
~/.tmux/scripts/agent-state.sh needs-input
~/.tmux/scripts/agent-state.sh done
~/.tmux/scripts/agent-state.sh idle
~/.tmux/scripts/agent-state.sh off
Optional metadata env vars:
| env | tmux option | meaning |
|---|---|---|
XTMUX_AGENT_BEAD |
@agent_bead |
current durable Beads task contract |
XTMUX_AGENT_TASK |
@agent_task |
short human-readable task summary |
XTMUX_AGENT_PROMPT_FILE |
@agent_prompt_file |
/tmp/... prompt file used for handoff |
XTMUX_AGENT_PARENT_SESSION |
@agent_parent_session |
orchestrator tmux #{session_id} (e.g. $3) — stable, per-instance, never recycled; do not use #S (session name) |
| automatic | @agent_last_transition |
ISO timestamp for last state transition |
off keeps @agent_state=off for compatibility and clears optional task
metadata so reused panes do not display stale bead/task pointers.
Claude Code can emit running, needs-input, done, and off via hooks. Pi is
supported through extensions/pi-agent-state.ts for running, done, idle,
and off; pi currently has no documented needs-input extension event. Both
runtimes log agent.turn.done with a compact last_message and send a reply-free
turn done: FYI when @agent_parent_session is set. Claude's Stop hook also
prints bounded pending inbox keys without reflecting message summaries.
Preview enrichment
Session and pane preview can show:
- session/root/cwd basics
- pane command/state/geometry
- capture-pane tail
- specialist metadata for
sp-*sessions agent-meta bead=... task=... parent=... prompt=... last=...- bounded
bd showcontext for explicit or confidently derived bead ids git-worktree branch=<branch> dirty=<count>- bounded
diff-statfor dirty worktrees
Bead derivation is conservative: it only derives dot-number ids such as
xtmux-rib.16 from session names or worktree/path conventions. Loose numeric
slugs are ignored.
Event journal and message channel
Typed tables in observability.db are authoritative; event_journal is the
append-only forensic stream queried by log tail, log query, and log follow.
Message bodies are not copied into coordination lifecycle events.
Useful coordination events include messages.sent, messages.ack,
messages.reply.linked, messages.reply.rejected, messages.cancelled,
wait.registered, wait.monitor.armed, wait.terminal,
wait.wake.delivered, wait.wake.consumed, wait.wake.orphan, and
wait.validation_failed.
CLI:
tmux-session-picker log emit <type> key=value ...
tmux-session-picker log tail [n]
tmux-session-picker log query [--type t] [--pane %42] [--session s] [--bead id] [--since 1h] [--limit n]
tmux-session-picker message-send --to <session|pane> [--from sender] [--bead id] --text 'short update'
tmux-session-picker message-list --for <session|pane> [--pane %N] [--message-key <key>] [--unacked] [--expects-reply] [--since 1h]
tmux-session-picker message-get <messageKey|messageId> [--json] # read one body, no ack
tmux-session-picker message-ack <messageKey> [--by session]
tmux-session-picker message-reply --in-reply-to <messageKey> --text 'result'
tmux-session-picker message-cancel --message-key <messageKey>
tmux-session-picker telemetry git -- <git-args...>
tmux-session-picker telemetry bd -- <bd-args...>
tmux-session-picker telemetry gh -- <gh-args...>
Use the message channel for short status updates between orchestrator/team panes
without scraping capture-pane or injecting text into another pane. Beads remain
the durable task contract. Pending replies and unconsumed wakes survive process
restart because Pi and Claude re-query SQLite; no runtime marker directory is
read, written, or cleaned during steady-state coordination.
Command telemetry is intentionally explicit. xtmux does not install aliases or
shadow git, bd, or gh. If an operator wants automatic logging in a pane,
they can opt in with shell aliases such as alias git='tmux-session-picker telemetry git --'.
Dashboard TSV
dashboard sessions-only is the primary agent-readable inventory for
orchestrators:
dashboard mode sessions-only
session sid name state bead task repo branch dirty shared idle path
dashboard expanded also emits pane rows:
pane sid session_name pane_id state bead task command path
This output is intended for scripts/agents. Use the interactive picker for human navigation.
Audit TSV
audit emits a read-only hygiene report:
audit read-only warnings-and-cleanup-candidates
warning dirty-worktree ...
warning shared-worktree ...
warning working-do-not-kill ...
warning agent-pane-without-bead ...
warning naming-convention ...
cleanup missing-path ...
cleanup stale-specialist ...
Warnings require operator judgment. Cleanup rows are candidates, not automatic actions.
Caches and state
| path | purpose |
|---|---|
${TMPDIR:-/tmp}/tmux-picker-cache-$UID/git-table |
path->git-root and root->status cache |
${TMPDIR:-/tmp}/tmux-picker-state-$UID/filter |
active Ctrl-f content filter |
${TMPDIR:-/tmp}/tmux-picker-state-$UID/list-mode |
expanded / sessions-only nesting mode |
${XDG_STATE_HOME:-$HOME/.local/state}/xtmux/observability.db |
authoritative messages, receipts, reply links, waits, monitors, and event journal |
The list output itself is never cached. Agent state and attention ranking are always read fresh.
Tuning
| env | default | effect |
|---|---|---|
TMUX_PICKER_GIT_CACHE_TTL |
30 |
seconds the git table is reused |
TMUX_PICKER_STALE_MINS |
60 |
idle threshold for stale session styling |
TMUX_PICKER_NO_CACHE |
0 |
1 bypasses git cache; used by refresh |
TMUX_PICKER_AGENT |
0 |
1 enables capture-pane agent-state inference fallback |
TMUX_PICKER_MODE |
default |
default, compact-wrap, compact-nowrap |
TMUX_ASCII_ICONS |
0 |
1 uses ASCII br/path instead of nerd font glyphs |
TMUX_GIT_TOPLEVEL |
— | caller-supplied repo root for git-pane-status.sh fast path |
XTMUX_AGENT_STATE_LOG |
0 |
1 logs agent-state transitions for hook debugging |
XTMUX_AGENT_STATE_LOG_FILE |
~/.cache/xtmux/agent-state.log |
legacy transition log path |
XTMUX_INBOX_POLL_INTERVAL_S |
30 |
Pi coordination SQLite refresh interval |
XTMUX_AUTO_MONITOR_TIMEOUT |
8h |
Pi auto-monitor timeout |
XTMUX_AUTO_MONITOR_INTERVAL |
60s |
Pi auto-monitor poll interval |
Full monitoring terminal
Use the helper script to open a tmux monitoring layout:
scripts/xtmux-monitor.sh --full
# after install.sh:
xtmux-monitor --full
Useful flags:
xtmux-monitor --session muxmon --interval 2 --kill-existing
xtmux-monitor --messages docs --turns
xtmux-monitor --log /tmp/xtmux-events.jsonl --no-attach
Default layout shows dashboard, monitor/audit, and raw event log. --full adds
recent agent.turn.done events and git/bd/gh telemetry; if run inside tmux it
also adds unacked messages for the current session.
Testing
make test
# regenerate status-line goldens after intentional output-contract changes:
make test-regen
Current validation at the time of this README update:
116 pass, 0 fail
test/contract.sh covers:
- git status snapshots: clean, dirty, stash, ahead, non-repo, fast-path
- cache clearing and hook installation
- filter grammar and active filter state
- nesting mode state
agent-state.shno-op, validation, pane option, metadata, and clearingwait-agent, monitor registry, safe-send-pointer, handoff, dashboard, audit- event log and log-backed message channel
- rename/kill/bulk-kill/act helper contracts
- live picker TSV shape and preview smoke
- specialist grouping/preview/waiting filter
- richer filter integration against live tmux sessions
Some legacy rename checks can print intermediate FAIL rename: ... lines inside
an isolated subshell in certain tmux environments, but the final suite summary is
the source of truth.
Performance
See docs/perf-audit.md. Current measured headline from
that audit:
- warm list: ~122 ms
- cold build: ~484 ms
- preview: ~95 ms
Only the expensive git half is cached. Agent state, attention sort, badges, filters, and dashboard/audit views are rendered from live tmux state.
Current implementation status
Completed major epics/work:
xtmux-ribv0.2 foundation and actionable picker work:- contract test harness
- agent-state hooks
- act-on-preview micro-actions
- specialist awareness
- cache invalidation
- staleness badge
- confirm-before-kill
- inline rename
- bulk multi-select
- richer filters
- sessions-only/expanded nesting
- preview enrichment substrate
- performance/cache split work
- attention jump bindings
- specialist section grouping
xtmux-muxmultiplexing-safe orchestration primitives:@agent_*metadatawait-agentsafe-send-pointer- bead-aware preview
- worktree collision detector
- dashboard TSV
- monitor registry
- audit report
- handoff prompt workflow
mux-help/?cheatsheet
Known reverted/abandoned historical work:
- a
Ctrl-ncreate-flow over worktrees/recent dirs was tried and reverted by operator request because it was noisy/confusing. It is not currently exposed.
Remaining open roadmap in Beads:
xtmux-rib.13live preview: manual tap-to-refresh (ctrl-t) and optional auto-tick modextmux-rib.14frecency: recent/frequent sessions rank higher below the attention headxtmux-rib.15general picker help overlay (distinct from the multiplexingmux-helpcheatsheet)xtmux-team.5multiplexing-teamdelegated-agent skill is maintained by xtrm; the npm package does not install skillsxtmux-team.6pi runtime turn-done publishing viaagent.turn.done+ parent messagextmux-team.7opt-ingit/bd/gh prtelemetry wrappers- deeper Claude last-message hook integration remains future work if needed
Beads are the source of truth for current planning/status.