Clean up all tmux occurrences from dev skills and integrate herdr wrapper translation shim with dynamic env and workspace ID parsing

This commit is contained in:
2026-07-19 16:57:00 +09:00
parent 42b54d7643
commit 30e606b0fa
20 changed files with 480 additions and 396 deletions
+18 -18
View File
@@ -1,14 +1,14 @@
---
name: multi-agent-mux-status
description: "Read-only instant snapshot of all agent tmux sessions — name, YAML status, tmux alive, pane cmd/cwd, resume UUID on disk, and any drift. No Kanban, no mutation. Reuses reconcile.sh --dry-run for the diff logic. Use when you want to know 'what's running RIGHT NOW' without spinning up a Kanban monitor worker."
description: "Read-only instant snapshot of all agent herdr sessions — name, YAML status, herdr alive, pane cmd/cwd, resume UUID on disk, and any drift. No Kanban, no mutation. Reuses reconcile.sh --dry-run for the diff logic. Use when you want to know 'what's running RIGHT NOW' without spinning up a Kanban monitor worker."
version: 1.0.0
author: godopu
license: MIT
platforms: [linux, macos]
environments: [terminal, tmux]
environments: [terminal, herdr]
metadata:
hermes:
tags: [agent, tmux, claude, antigravity, agy, status, read-only, snapshot]
tags: [agent, herdr, claude, antigravity, agy, status, read-only, snapshot]
related_skills: [multi-agent-mux-create, multi-agent-mux-resume, multi-agent-mux-stop, multi-agent-mux-monitor]
prereq_skills: [multi-agent-mux-create, multi-agent-mux-monitor]
---
@@ -16,19 +16,19 @@ metadata:
# Multi-Agent Status — Read-Only Instant Snapshot
> **Companion skills**: `multi-agent-mux-create` (start), `multi-agent-mux-resume` (re-attach), `multi-agent-mux-stop` (terminate), `multi-agent-mux-monitor` (live polling).
> **Tmux Isolation**: `status` 명령은 YAML에 등록된 모든 세션의 격리 서버(`tmux_server` 필드)를 자동으로 조회하여 상태를 확인하므로, `TMUX_SERVER_NAME` 환경변수를 수동으로 지정하지 않아도 모든 격리 서버의 세션 상태를 통합 조회합니다.
> **Herdr Isolation**: `status` 명령은 YAML에 등록된 모든 세션의 격리 서버(`herdr_server` 필드)를 자동으로 조회하여 상태를 확인하므로, `HERDR_SERVER_NAME` 환경변수를 수동으로 지정하지 않아도 모든 격리 서버의 세션 상태를 통합 조회합니다.
> **Single source of truth**: `./.mam/agent-sessions.yaml`.
## What this skill does
Print a single table of every agent tmux session, comparing YAML state to actual tmux state. **No mutation. No Kanban. No polling loop.**
Print a single table of every agent herdr session, comparing YAML state to actual herdr state. **No mutation. No Kanban. No polling loop.**
This is the "what's running right now?" answer — faster than dispatching `multi-agent-mux-monitor` (which polls every 30s) and safer than `reconcile.sh --once --emit-diff` (which mutates as a side effect).
## Pre-flight
```bash
command -v tmux
command -v herdr
command -v python3
test -f .mam/agent-sessions.yaml
```
@@ -45,19 +45,19 @@ The script:
1. Calls `reconcile.sh --once --emit-diff --dry-run` (read-only; no YAML mutation) for the drift snapshot
2. Loads `agent-sessions.yaml` (read-only) to enrich the table
3. For each row in `tmux_sessions[]`:
- tmux alive? (via `tmux has-session -t <name>`)
- pane cmd, cwd (via `tmux list-panes`)
3. For each row in `herdr_sessions[]`:
- herdr alive? (via `herdr has-session -t <name>`)
- pane cmd, cwd (via `herdr list-panes`)
- resume UUID on disk? (claude: `$CLAUDE_PROJECT_DIR/<key>/<uuid>.jsonl` with default `~/.claude/projects/`; agy: `$HOME_DIR/.gemini/antigravity-cli/conversations/<uuid>.db` with default `~/.gemini/...`)
4. For each tmux session matching `*-creator-*` not in YAML → flag as "unregistered"
4. For each herdr session matching `*-creator-*` not in YAML → flag as "unregistered"
5. Prints a table (default) or JSON (with `--json`)
## Output format (default = aligned table)
```
agent-sessions status — 2026-06-19T14:20:00Z (tmux_confirmed=True)
agent-sessions status — 2026-06-19T14:20:00Z (herdr_confirmed=True)
========================================================================================================================================
NAME SERVER YAML TMUX CMD RESUME JOB_ID JOB_STATUS DRIFT
NAME SERVER YAML HERDR CMD RESUME JOB_ID JOB_STATUS DRIFT
----------------------------------------------------------------------------------------------------------------------------------------
lab-landing-page-creator-claude default running alive claude yes - - -
lab-landing-page-creator-agy default terminated dead agy yes 5fe09ba8 completed -
@@ -70,13 +70,13 @@ lab-paper-pdf2md-creator-claude default running alive clau
```json
{
"yaml_path": "...",
"tmux_sessions_alive": ["..."],
"herdr_sessions_alive": ["..."],
"yaml_entries": [...],
"rows": [
{
"name": "lab-landing-page-creator-claude",
"yaml_status": "running",
"tmux_alive": true,
"herdr_alive": true,
"pane_cmd": "claude",
"pane_cwd": "/home/.../refer_landing_page",
"resume_uuid_on_disk": true,
@@ -85,7 +85,7 @@ lab-paper-pdf2md-creator-claude default running alive clau
{
"name": "lab-landing-page-creator-agy",
"yaml_status": "terminated",
"tmux_alive": false,
"herdr_alive": false,
"drift": "yaml-says-terminated-but-disk-uuid-still-present"
}
],
@@ -98,15 +98,15 @@ lab-paper-pdf2md-creator-claude default running alive clau
| Class | Detection | Meaning |
|---|---|---|
| `A` | YAML `running`, tmux dead | session died without going through `multi-agent-mux-stop`. *Could* auto-terminate but won't — that's `multi-agent-mux-monitor`'s job. |
| `B` | tmux alive, not in YAML | ad-hoc session someone started without `multi-agent-mux-create`. Suggest: "use multi-agent-mux-create to register, or tmux kill-session to clean up." |
| `A` | YAML `running`, herdr dead | session died without going through `multi-agent-mux-stop`. *Could* auto-terminate but won't — that's `multi-agent-mux-monitor`'s job. |
| `B` | herdr alive, not in YAML | ad-hoc session someone started without `multi-agent-mux-create`. Suggest: "use multi-agent-mux-create to register, or herdr kill-session to clean up." |
| `C` | YAML has `claude_session_id_own: null` AND a new *.jsonl exists | new session id materialized; suggest: "run multi-agent-mux-resume or reconcile to register it." |
| `D` | YAML has UUID in `agent_identities`, but the on-disk artifact is gone | stale UUID; user should `multi-agent-mux-stop --purge-conversation` to clean up. |
## Pitfalls
- **Do NOT use this skill to drive mutations** — the output is a snapshot, not a call to action. If you need to fix drifts, dispatch `multi-agent-mux-monitor` (Kanban worker) or run `multi-agent-mux-resume` / `multi-agent-mux-stop` manually.
- **Read-only is enforced by script** — `status.sh` opens the YAML with `open(path)` (no `'w'`), never calls `tmux kill-session`, never writes anywhere. The `reconcile.sh --dry-run` mode is the same path.
- **Read-only is enforced by script** — `status.sh` opens the YAML with `open(path)` (no `'w'`), never calls `herdr kill-session`, never writes anywhere. The `reconcile.sh --dry-run` mode is the same path.
- **If `agent-sessions.yaml` is malformed** — print the YAML error verbatim and exit 1. Do NOT attempt recovery (that's `multi-agent-mux-stop --purge-conversation` or manual edit's job).
- **Sessions outside the `<workspace>-creator-*` naming convention** are still shown but tagged `ad-hoc` — they didn't go through `multi-agent-mux-create` and aren't tracked in YAML.
@@ -25,7 +25,7 @@ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../" && pwd)"
if [ "$JSON" = "1" ]; then
# D8: --json historically only carried reconcile.sh's drift subset (timestamp/
# yaml_path/tmux_sessions_alive/tmux_confirmed/drifts/actions), not the enriched
# yaml_path/herdr_sessions_alive/herdr_confirmed/drifts/actions), not the enriched
# per-row fields (RESUME/JOB_ID/JOB_STATUS/CMD/attach_command/pane.cwd/...) that
# only this script's text-mode block computed. Fixed additively below via a
# 'sessions_detail' key — every existing key is passed through untouched, so
@@ -42,7 +42,7 @@ try:
except Exception:
d = {}
alive = set(drift.get('tmux_sessions_alive', []))
alive = set(drift.get('herdr_sessions_alive', []))
drift_by_name = {}
for dr in drift.get('drifts', []):
drift_by_name.setdefault(dr['name'], []).append(dr['class'])
@@ -91,9 +91,9 @@ def get_job_status(s):
sessions_detail = []
for s in d.get('tmux_sessions', []):
for s in d.get('herdr_sessions', []):
name = s.get('name', '?')
server = s.get('tmux_server') or 'default'
server = s.get('herdr_server') or 'default'
jid, jstatus = get_job_status(s)
pane = s.get('pane') or {}
sessions_detail.append({
@@ -103,7 +103,7 @@ for s in d.get('tmux_sessions', []):
'name': name,
'server': server,
'status': s.get('status', '?'),
'tmux_alive': f"{name}|{server}" in alive,
'herdr_alive': f"{name}|{server}" in alive,
'cmd': pane.get('cmd'),
'role': s.get('role'),
'resume_state': resume_on_disk(s),
@@ -138,7 +138,7 @@ try:
except Exception:
d = {}
alive = set(drift.get('tmux_sessions_alive', []))
alive = set(drift.get('herdr_sessions_alive', []))
drift_by_name = {}
for dr in drift.get('drifts', []):
drift_by_name.setdefault(dr['name'], []).append(dr['class'])
@@ -188,8 +188,8 @@ def get_job_status(s):
return (jid, 'unknown')
sessions = d.get('tmux_sessions', [])
print(f"agent-sessions status — {drift['timestamp']} (herdr_confirmed={drift['tmux_confirmed']})")
sessions = d.get('herdr_sessions', [])
print(f"agent-sessions status — {drift['timestamp']} (herdr_confirmed={drift['herdr_confirmed']})")
print("=" * 136)
print(f"{'NAME':<44} {'WORKSPACE':<12} {'YAML':<10} {'HERDR':<6} {'CMD':<6} {'RESUME':<8} {'JOB_ID':<10} {'JOB_STATUS':<12} DRIFT")
print("-" * 136)
@@ -197,7 +197,7 @@ if not sessions:
print("(no sessions registered)")
for s in sessions:
name = s.get('name', '?')
server = s.get('tmux_server') or 'default'
server = s.get('herdr_server') or 'default'
status = s.get('status', '?')
herdr = 'alive' if f"{name}|{server}" in alive else 'dead'
cmd = (s.get('pane') or {}).get('cmd', '?')