Add plugin tmux-agents-mom to monitor AI agents and create powerkit plugins to update status bar

This commit is contained in:
Yax
2026-07-21 16:49:56 +02:00
parent c4e61d2a65
commit adfc04c0f9
5 changed files with 163 additions and 1 deletions
+6 -1
View File
@@ -124,7 +124,7 @@ bind r source-file ~/.tmux.conf \; display-message "tmux config reloaded!"
# plugin powerkit
set -g @powerkit_theme 'nord'
set -g @powerkit_theme_variant 'dark'
set -g @powerkit_plugins 'ssh,memory,datetime'
set -g @powerkit_plugins 'ssh,memory,group(agents_blocked,agents_working,agents_idle),datetime'
set -g @powerkit_session_icon 'auto'
set -g @powerkit_status_position 'bottom'
set -g @powerkit_keybinding_conflict_action 'skip'
@@ -139,10 +139,15 @@ set -g @tpad-scratch-dir "#{pane_current_path}"
set -g @tpad-scratch-width "70%"
set -g @tpad-scratch-height "70%"
# plugin agents-mon
set -g @agents-mon-key 'e'
set -g @agents-mon-display 'popup'
# Plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'fabioluciano/tmux-powerkit'
set -g @plugin 'azorng/tmux-smooth-scroll'
set -g @plugin 'snirt/tmux-agents-mon'
# tmux-tpad
set -g @plugin 'Subbeh/tmux-tpad'
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# =============================================================================
# Plugin: agents_blocked (managed by chezmoi)
# Description: Number of tmux-agents-mon agents in the "blocked" state.
# Type: conditional (hidden when the count is 0)
# Part of the group(agents_blocked,agents_working,agents_idle) segment.
# =============================================================================
POWERKIT_ROOT="${POWERKIT_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
. "${POWERKIT_ROOT}/src/contract/plugin_contract.sh"
plugin_get_metadata() {
metadata_set "id" "agents_blocked"
metadata_set "name" "Agents Blocked"
metadata_set "description" "Count of blocked Claude agents"
}
plugin_declare_options() {
declare_option "icon" "icon" "⣿" "Glyph shown for blocked agents"
declare_option "cache_ttl" "number" "2" "Cache duration in seconds"
}
plugin_get_content_type() { printf 'dynamic'; }
plugin_get_presence() { printf 'conditional'; }
plugin_collect() {
plugin_data_set "count" "$("$HOME/.local/bin/agents-mon-count" blocked)"
}
plugin_get_state() {
local n
n=$(plugin_data_get "count")
[[ "${n:-0}" -gt 0 ]] && printf 'active' || printf 'inactive'
}
# error -> nord error-base (#bf616a, red)
plugin_get_health() { printf 'error'; }
plugin_render() { printf '%s' "$(plugin_data_get "count")"; }
plugin_get_icon() { printf '%s' "$(get_option 'icon')"; }
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# =============================================================================
# Plugin: agents_idle (managed by chezmoi)
# Description: Number of tmux-agents-mon agents in the "idle" state.
# Type: conditional (hidden when the count is 0)
# Part of the group(agents_blocked,agents_working,agents_idle) segment.
# =============================================================================
POWERKIT_ROOT="${POWERKIT_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
. "${POWERKIT_ROOT}/src/contract/plugin_contract.sh"
plugin_get_metadata() {
metadata_set "id" "agents_idle"
metadata_set "name" "Agents Idle"
metadata_set "description" "Count of idle Claude agents"
}
plugin_declare_options() {
declare_option "icon" "icon" "⣿" "Glyph shown for idle agents"
declare_option "cache_ttl" "number" "2" "Cache duration in seconds"
}
plugin_get_content_type() { printf 'dynamic'; }
plugin_get_presence() { printf 'conditional'; }
plugin_collect() {
plugin_data_set "count" "$("$HOME/.local/bin/agents-mon-count" idle)"
}
plugin_get_state() {
local n
n=$(plugin_data_get "count")
[[ "${n:-0}" -gt 0 ]] && printf 'active' || printf 'inactive'
}
# good -> nord good-base (#a3be8c, green). NB: 'ok' would be dark grey, not green.
plugin_get_health() { printf 'good'; }
plugin_render() { printf '%s' "$(plugin_data_get "count")"; }
plugin_get_icon() { printf '%s' "$(get_option 'icon')"; }
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# =============================================================================
# Plugin: agents_working (managed by chezmoi)
# Description: Number of tmux-agents-mon agents in the "working" state.
# Type: conditional (hidden when the count is 0)
# Part of the group(agents_blocked,agents_working,agents_idle) segment.
# =============================================================================
POWERKIT_ROOT="${POWERKIT_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
. "${POWERKIT_ROOT}/src/contract/plugin_contract.sh"
plugin_get_metadata() {
metadata_set "id" "agents_working"
metadata_set "name" "Agents Working"
metadata_set "description" "Count of working Claude agents"
}
plugin_declare_options() {
declare_option "icon" "icon" "⣾" "Glyph shown for working agents"
declare_option "cache_ttl" "number" "2" "Cache duration in seconds"
}
plugin_get_content_type() { printf 'dynamic'; }
plugin_get_presence() { printf 'conditional'; }
plugin_collect() {
plugin_data_set "count" "$("$HOME/.local/bin/agents-mon-count" working)"
}
plugin_get_state() {
local n
n=$(plugin_data_get "count")
[[ "${n:-0}" -gt 0 ]] && printf 'active' || printf 'inactive'
}
# warning -> nord warning-base (#ebcb8b, yellow)
plugin_get_health() { printf 'warning'; }
plugin_render() { printf '%s' "$(plugin_data_get "count")"; }
plugin_get_icon() { printf '%s' "$(get_option 'icon')"; }
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Count tmux-agents-mon agents in a given state, for the powerkit segments.
#
# Usage: agents-mon-count <blocked|working|idle>
# Prints the number of agents currently in that state (0 if none).
#
# Uses `agents-mon scan` (always live TSV, one line per agent, state in field 4)
# rather than `agents-mon status` — the latter serves a cache up to 6s stale.
# The three powerkit plugins (agents_blocked/working/idle) each call this on every
# status refresh, so we cache the parsed counts for ~2s in a shared tmp file to
# avoid running three full `tmux list-panes -a` + `capture-pane` scans per cycle.
set -u
state="${1:-}"
case "$state" in
blocked | working | idle) ;;
*) printf '0'; exit 0 ;;
esac
BIN="${AGENTS_MON_BIN:-$HOME/.tmux/plugins/tmux-agents-mon/target/release/agents-mon}"
[ -x "$BIN" ] && command -v tmux >/dev/null 2>&1 || { printf '0'; exit 0; }
cache="${TMPDIR:-/tmp}/agents-mon-counts-$(id -u)"
# Refresh the cache when it is missing or older than ~2 seconds.
if [ -z "$(find "$cache" -newermt '-2 seconds' 2>/dev/null)" ]; then
"$BIN" scan 2>/dev/null | awk -F'\t' '
{ c[$4]++ }
END { printf "blocked=%d\nworking=%d\nidle=%d\n", c["blocked"], c["working"], c["idle"] }
' >"$cache.tmp.$$" 2>/dev/null && mv -f "$cache.tmp.$$" "$cache" 2>/dev/null
fi
# Emit the requested count (0 if the cache is unreadable for any reason).
awk -F= -v s="$state" '$1==s { print $2; found=1 } END { if (!found) print 0 }' "$cache" 2>/dev/null || printf '0'