refactor: rename skills from tmux-agent-orchestrate-* to multi-agent-mux-* in backplane scripts and documents
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# lib.sh — shared library for the tmux-agent-orchestrate-* skills.
|
||||
# lib.sh — shared library for the multi-agent-mux-* skills.
|
||||
#
|
||||
# Single source of truth for the four things that were inconsistently
|
||||
# re-implemented across create/resume/delete/monitor (REVIEW.md §4.1):
|
||||
@@ -646,7 +646,7 @@ PYEOF
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# tmux-agent-orchestrate-delegate-job integration helpers
|
||||
# multi-agent-mux-delegate-job integration helpers
|
||||
#
|
||||
# All paths are resolved relative to lib.sh's own location (BASH_SOURCE), so the
|
||||
# skill tree is relocatable — no hardcoded absolute paths (review item 6).
|
||||
@@ -671,26 +671,26 @@ _delegate_py_bin() {
|
||||
printf '%s\n' "$AGENT_PYTHON_BIN"
|
||||
}
|
||||
|
||||
# _delegate_script <name> — echo the path to a tmux-agent-orchestrate-delegate-job script, resolved
|
||||
# _delegate_script <name> — echo the path to a multi-agent-mux-delegate-job script, resolved
|
||||
# relative to .agents/skills/ (lib.sh dir). Empty if not found.
|
||||
_delegate_script() {
|
||||
local name="$1" skill_dir cand
|
||||
skill_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cand="$skill_dir/tmux-agent-orchestrate-delegate-job/scripts/$name"
|
||||
cand="$skill_dir/multi-agent-mux-delegate-job/scripts/$name"
|
||||
if [ -f "$cand" ]; then printf '%s\n' "$cand"; return 0; fi
|
||||
printf '%s\n' "$(find "$skill_dir" -name "$name" 2>/dev/null | head -n 1 || true)"
|
||||
}
|
||||
|
||||
# delegate_submit_job <prompt> <agent> <agent_session>
|
||||
#
|
||||
# Register a job in the tmux-agent-orchestrate-delegate-job registry. Prints the new JID on stdout.
|
||||
# Register a job in the multi-agent-mux-delegate-job registry. Prints the new JID on stdout.
|
||||
delegate_submit_job() {
|
||||
local prompt="$1" agent="$2" session="$3"
|
||||
local py_bin registry_py
|
||||
py_bin="$(_delegate_py_bin)"
|
||||
registry_py="$(_delegate_script registry.py)"
|
||||
if [ -z "$registry_py" ] || [ ! -f "$registry_py" ]; then
|
||||
echo "ERROR: tmux-agent-orchestrate-delegate-job registry.py not found under .agents/skills/" >&2
|
||||
echo "ERROR: multi-agent-mux-delegate-job registry.py not found under .agents/skills/" >&2
|
||||
return 1
|
||||
fi
|
||||
"$py_bin" "$registry_py" register \
|
||||
@@ -701,7 +701,7 @@ delegate_submit_job() {
|
||||
|
||||
# delegate_publish_event <job_id> <event> [detail]
|
||||
#
|
||||
# Publish a lifecycle event to the tmux-agent-orchestrate-delegate-job registry. Consolidates the
|
||||
# Publish a lifecycle event to the multi-agent-mux-delegate-job registry. Consolidates the
|
||||
# inline .venv-walk + publish_event.py blocks that were duplicated across
|
||||
# create/delete/resume (review item 7). Non-fatal by contract: an empty job id,
|
||||
# a missing script, or a broker failure never aborts the caller.
|
||||
@@ -723,7 +723,7 @@ delegate_publish_event() {
|
||||
start_watchdog() {
|
||||
local job_id="$1"
|
||||
local workdir="${2:-$PWD}"
|
||||
local watchdog_script="$workdir/.agents/skills/tmux-agent-orchestrate-monitor/scripts/watchdog.sh"
|
||||
local watchdog_script="$workdir/.agents/skills/multi-agent-mux-monitor/scripts/watchdog.sh"
|
||||
local log_file="$workdir/.mam/jobs/${job_id}.watchdog.log"
|
||||
|
||||
if [ ! -x "$watchdog_script" ]; then
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: tmux-agent-orchestrate-create
|
||||
name: multi-agent-mux-create
|
||||
description: "Create a new agent session (claude, antigravity/agy) in a dedicated tmux session for context-preserving long-running work. Always creates a tmux session — never backgrounds with nohup/disown. Writes the new session to .mam/agent-sessions.yaml. Use when you want to start a fresh agent (no prior UUID) for a new project workspace."
|
||||
version: 1.0.0
|
||||
author: godopu
|
||||
@@ -9,18 +9,18 @@ environments: [terminal, tmux]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [agent, tmux, claude, antigravity, agy, multi-agent, context, session]
|
||||
related_skills: [tmux-agent-orchestrate-resume, tmux-agent-orchestrate-stop, tmux-agent-orchestrate-monitor, claude-code]
|
||||
related_skills: [multi-agent-mux-resume, multi-agent-mux-stop, multi-agent-mux-monitor, claude-code]
|
||||
prereq_skills: [claude-code]
|
||||
---
|
||||
|
||||
# Multi-Agent Create — Start a Fresh Agent in a tmux Session
|
||||
|
||||
> **Companion skills**: `tmux-agent-orchestrate-resume` (resume an existing UUID), `tmux-agent-orchestrate-stop` (terminate), `tmux-agent-orchestrate-monitor` (live status).
|
||||
> **Companion skills**: `multi-agent-mux-resume` (resume an existing UUID), `multi-agent-mux-stop` (terminate), `multi-agent-mux-monitor` (live status).
|
||||
> **Single source of truth**: `./.mam/agent-sessions.yaml` (this skill writes to it; never read it ad-hoc — go through this skill).
|
||||
|
||||
## What this skill does
|
||||
|
||||
Spawn a new agent (`claude` or `agy`/antigravity-cli) in a **dedicated tmux session** for context-preserving long-running work. The tmux session is the *container*; the agent's session ID is *data* inside the container. **This skill creates the container + starts the agent — but does not resume an old conversation** (use `tmux-agent-orchestrate-resume` for that).
|
||||
Spawn a new agent (`claude` or `agy`/antigravity-cli) in a **dedicated tmux session** for context-preserving long-running work. The tmux session is the *container*; the agent's session ID is *data* inside the container. **This skill creates the container + starts the agent — but does not resume an old conversation** (use `multi-agent-mux-resume` for that).
|
||||
|
||||
For all agents: the tmux session name is produced by **`lib.sh::derive_session_name`** — the single source of truth shared by create/resume/stop/status/monitor (P0-A). The rule (verbatim from the function):
|
||||
|
||||
@@ -103,7 +103,7 @@ SESSION_NAME="$(derive_session_name "$WORKSPACE" "$AGENT")"
|
||||
|
||||
# 1. If session already alive, fail fast
|
||||
tmux has-session -t "$SESSION_NAME" 2>/dev/null && {
|
||||
echo "ERROR: tmux session '$SESSION_NAME' already exists. Use tmux-agent-orchestrate-resume to attach or tmux-agent-orchestrate-stop first."
|
||||
echo "ERROR: tmux session '$SESSION_NAME' already exists. Use multi-agent-mux-resume to attach or multi-agent-mux-stop first."
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ After spawn, append a new `tmux_sessions[]` entry to `.mam/agent-sessions.yaml`:
|
||||
Use the `agent-sessions-yaml-edit` script in `scripts/` to safely append (preserves comments + format):
|
||||
|
||||
```bash
|
||||
bash .agents/skills/tmux-agent-orchestrate-create/scripts/create_session.sh \
|
||||
bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \
|
||||
--workspace "$WORKSPACE" --agent "$AGENT" --session "$SESSION_NAME"
|
||||
```
|
||||
|
||||
@@ -184,7 +184,7 @@ The script handles the YAML append, pane capture, and the `last_visible_status`
|
||||
- **Don't trust `--session-id <uuid>` flags blindly** — claude/agy may not accept a fixed session id on first spawn. The session id is *assigned* on first user message; you can read it back from `~/.claude/projects/.../session.jsonl` headers or `~/.gemini/.../cache/last_conversations.json` AFTER the first message.
|
||||
- **Wrapper script MUST NOT be created via `hermes profile alias`** — that command writes a `hermes -p <profile>` wrapper that destroys the tmux behavior. Create wrappers manually (see `lab-landing-page-creator-claude` template).
|
||||
- **Always use the workspace-relative path** in tmux `cwd` — relative paths break when tmux respawns in a different shell context.
|
||||
- **The first `claude` message generates the session id** — `tmux-agent-orchestrate-create` only sets up the *container*. If you need a known session id for later resume, send a placeholder message (e.g. "init") and read it back, then call `tmux-agent-orchestrate-resume` later.
|
||||
- **The first `claude` message generates the session id** — `multi-agent-mux-create` only sets up the *container*. If you need a known session id for later resume, send a placeholder message (e.g. "init") and read it back, then call `multi-agent-mux-resume` later.
|
||||
|
||||
## Verification
|
||||
|
||||
@@ -214,7 +214,7 @@ tmux capture-pane -t "$SESSION_NAME" -p -S -20
|
||||
|
||||
## When NOT to use this skill
|
||||
|
||||
- **Resuming an old conversation** → `tmux-agent-orchestrate-resume`
|
||||
- **Killing an existing session** → `tmux-agent-orchestrate-stop`
|
||||
- **Resuming an old conversation** → `multi-agent-mux-resume`
|
||||
- **Killing an existing session** → `multi-agent-mux-stop`
|
||||
- **Just attaching to an existing session** → `tmux attach -t <name>` (no skill needed)
|
||||
- **One-shot print mode (claude -p "...")** → no tmux needed; use `claude-code` skill's print mode
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# create_session.sh — tmux-agent-orchestrate-create 의 부속 스크립트
|
||||
# create_session.sh — multi-agent-mux-create 의 부속 스크립트
|
||||
# Usage:
|
||||
# bash create_session.sh --workspace <path> --agent <claude|agy> [--session <name>] [--wrapper]
|
||||
#
|
||||
@@ -15,7 +15,7 @@
|
||||
# 0 = success
|
||||
# 1 = preflight failure
|
||||
# 2 = invalid args
|
||||
# 3 = tmux session already exists (use tmux-agent-orchestrate-resume or delete first)
|
||||
# 3 = tmux session already exists (use multi-agent-mux-resume or delete first)
|
||||
# 4 = agent-sessions.yaml append failure
|
||||
set -euo pipefail
|
||||
|
||||
@@ -32,7 +32,7 @@ Options:
|
||||
--wrapper force use of ~/.local/bin/<session> wrapper even if not present
|
||||
--dry-run print commands without executing
|
||||
--tmux-server NAME specify isolated tmux server name
|
||||
--submit-job PROMPT submit a job to tmux-agent-orchestrate-delegate-job registry with the given prompt
|
||||
--submit-job PROMPT submit a job to multi-agent-mux-delegate-job registry with the given prompt
|
||||
-h, --help this help
|
||||
EOF
|
||||
}
|
||||
@@ -95,7 +95,7 @@ fi
|
||||
|
||||
# 이미 살아있으면 실패
|
||||
if _tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
|
||||
echo "ERROR: tmux session '$SESSION_NAME' already exists. Use tmux-agent-orchestrate-resume to attach, or tmux-agent-orchestrate-stop first." >&2
|
||||
echo "ERROR: tmux session '$SESSION_NAME' already exists. Use multi-agent-mux-resume to attach, or multi-agent-mux-stop first." >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
@@ -279,7 +279,7 @@ echo "=== created ==="
|
||||
echo "tmux session: $SESSION_NAME (pane pid $PANE_PID, cmd $PANE_CMD, cwd $PANE_CWD)"
|
||||
if [ -n "$DELEGATE_JOB_ID" ]; then
|
||||
echo "delegate job: $DELEGATE_JOB_ID"
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" started "tmux-agent-orchestrate session created"
|
||||
delegate_publish_event "$DELEGATE_JOB_ID" started "multi-agent-mux session created"
|
||||
WD_PID=$(start_watchdog "$DELEGATE_JOB_ID" "$WORKSPACE")
|
||||
echo "watchdog PID: $WD_PID"
|
||||
fi
|
||||
@@ -290,5 +290,5 @@ if [ -n "${TMUX_SERVER_NAME:-}" ] && [ "$TMUX_SERVER_NAME" != "default" ]; then
|
||||
else
|
||||
echo "Attach: tmux attach -t $SESSION_NAME"
|
||||
fi
|
||||
echo "Delete: use tmux-agent-orchestrate-stop skill"
|
||||
echo "Resume: use tmux-agent-orchestrate-resume skill (after first message creates a session id)"
|
||||
echo "Delete: use multi-agent-mux-stop skill"
|
||||
echo "Resume: use multi-agent-mux-resume skill (after first message creates a session id)"
|
||||
@@ -0,0 +1,11 @@
|
||||
# multi-agent-mux-delegate-job 스킬
|
||||
|
||||
작업(Job)을 자율 에이전트(claude-code/codex/opencode/human)에게 위임하고 MQTT
|
||||
이벤트 채널로 비동기 관찰하는 Hermes 스킬. **시작점은 [`SKILL.md`](./SKILL.md).**
|
||||
|
||||
- 프로토콜/스키마: [`job-protocol.md`](./job-protocol.md)
|
||||
- 브로커 PoC→운영 전환: [`mqtt-broker-setup.md`](./mqtt-broker-setup.md)
|
||||
- 레지스트리 포맷/동시성: [`registry.md`](./registry.md)
|
||||
- 참조 구현: [`multi-agent-mux-delegate-job`](./multi-agent-mux-delegate-job) (bash wrapper), [`scripts/publish_event.py`](./scripts/publish_event.py), [`scripts/job_subscriber.py`](./scripts/job_subscriber.py), [`scripts/registry.py`](./scripts/registry.py), [`scripts/mqtt_common.py`](./scripts/mqtt_common.py)
|
||||
- 영구 감사 로그: `.mam/delegate_job_logs/<job_id>/` (`meta.json`·`events.ndjson`·`status.json`)
|
||||
— `multi-agent-mux-delegate-job logs <id>` 또는 `multi-agent-mux-delegate-job logs --list`로 조회 (SKILL.md "Audit Logs" 참조)
|
||||
+19
-19
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: tmux-agent-orchestrate-delegate-job
|
||||
description: "Delegate a unit of work to any autonomous agent (claude-code, codex, opencode, or a human) and observe it asynchronously over an MQTT event channel. Each job gets a unique id, a registry record (prompt, broker, status, timeouts), and a single per-job topic that carries started/permission_required/progress/completed/error events as schema-versioned JSON. The delegator starts a subscriber first, runs the agent, and treats a completed/error event or a timeout as the job's terminal state. Ships a working reference implementation (publish_event.py, job_subscriber.py, registry.py, mqtt_common.py, tmux-agent-orchestrate-delegate-job wrapper) plus a PoC-to-production path: validate on a public broker, then move to an authenticated TLS broker by changing config only — no code change. Use when you need fire-and-observe delegation, multi-job fan-out across tmux sessions, or a uniform completion-signal protocol shared by several agent types."
|
||||
name: multi-agent-mux-delegate-job
|
||||
description: "Delegate a unit of work to any autonomous agent (claude-code, codex, opencode, or a human) and observe it asynchronously over an MQTT event channel. Each job gets a unique id, a registry record (prompt, broker, status, timeouts), and a single per-job topic that carries started/permission_required/progress/completed/error events as schema-versioned JSON. The delegator starts a subscriber first, runs the agent, and treats a completed/error event or a timeout as the job's terminal state. Ships a working reference implementation (publish_event.py, job_subscriber.py, registry.py, mqtt_common.py, multi-agent-mux-delegate-job wrapper) plus a PoC-to-production path: validate on a public broker, then move to an authenticated TLS broker by changing config only — no code change. Use when you need fire-and-observe delegation, multi-job fan-out across tmux sessions, or a uniform completion-signal protocol shared by several agent types."
|
||||
version: 1.0.0
|
||||
author: Hermes Agent
|
||||
license: MIT
|
||||
@@ -11,7 +11,7 @@ metadata:
|
||||
related_skills: [claude-code, codex, opencode, hermes-agent-skill-authoring]
|
||||
---
|
||||
|
||||
# tmux-agent-orchestrate-delegate-job — Async Job Delegation over MQTT
|
||||
# multi-agent-mux-delegate-job — Async Job Delegation over MQTT
|
||||
|
||||
Delegate a unit of work to an autonomous agent, then **observe** it instead of
|
||||
blocking on it. Every job gets a unique id and a registry record; the agent
|
||||
@@ -73,7 +73,7 @@ you need finer control.
|
||||
```bash
|
||||
# 1) one line: register → start subscriber → launch agent in tmux
|
||||
# (uses public broker by default; last stdout line is the audit-log dir)
|
||||
tmux-agent-orchestrate-delegate-job submit \
|
||||
multi-agent-mux-delegate-job submit \
|
||||
--agent claude-code \
|
||||
--prompt "정렬 문제 10개를 만들어 sort_problems.md로 저장" \
|
||||
--workdir /path/to/project \
|
||||
@@ -86,12 +86,12 @@ tmux-agent-orchestrate-delegate-job submit \
|
||||
# /path/to/project/.mam/delegate_job_logs/<JID> ← audit log dir
|
||||
|
||||
# 2) at any time, query the job or its audit log
|
||||
tmux-agent-orchestrate-delegate-job status --job <JID>
|
||||
tmux-agent-orchestrate-delegate-job logs <JID> # pretty timeline
|
||||
tmux-agent-orchestrate-delegate-job logs --list # every job, live status
|
||||
multi-agent-mux-delegate-job status --job <JID>
|
||||
multi-agent-mux-delegate-job logs <JID> # pretty timeline
|
||||
multi-agent-mux-delegate-job logs --list # every job, live status
|
||||
|
||||
# 3) run a user-supplied validator against the job's artifacts
|
||||
tmux-agent-orchestrate-delegate-job verify --job <JID> --validate ./validate.sh
|
||||
multi-agent-mux-delegate-job verify --job <JID> --validate ./validate.sh
|
||||
```
|
||||
|
||||
The wrapper enforces the **subscribe-before-publish** ordering and **forwards
|
||||
@@ -102,7 +102,7 @@ propagated to the agent"). When you need finer control, the manual flow is:
|
||||
```bash
|
||||
# Manual 5-step (same outcome, more knobs)
|
||||
PY=.venv/bin/python
|
||||
SKILL=./.agents/skills/tmux-agent-orchestrate-delegate-job/scripts
|
||||
SKILL=./.agents/skills/multi-agent-mux-delegate-job/scripts
|
||||
|
||||
# 1) register
|
||||
JID=$($PY "$SKILL/registry.py" register \
|
||||
@@ -194,8 +194,8 @@ never touched.
|
||||
**Reading them:**
|
||||
|
||||
```bash
|
||||
tmux-agent-orchestrate-delegate-job logs <job_id> # pretty-print one job's timeline
|
||||
tmux-agent-orchestrate-delegate-job logs --list # summarise every logged job (with live status)
|
||||
multi-agent-mux-delegate-job logs <job_id> # pretty-print one job's timeline
|
||||
multi-agent-mux-delegate-job logs --list # summarise every logged job (with live status)
|
||||
# or directly via the registry CLI:
|
||||
$PY scripts/registry.py logs <job_id> [--tail N] [--json]
|
||||
$PY scripts/registry.py logs --list [--json]
|
||||
@@ -239,7 +239,7 @@ agent").
|
||||
Your job_id is "$JOB_ID" (read it from the registry record for this delegation —
|
||||
do not reuse any job_id you saw before).
|
||||
|
||||
On start: $PY tmux-agent-orchestrate-delegate-job/scripts/publish_event.py --job "$JOB_ID" --event started
|
||||
On start: $PY multi-agent-mux-delegate-job/scripts/publish_event.py --job "$JOB_ID" --event started
|
||||
On permission: $PY … --job "$JOB_ID" --event permission_required --detail "<tool>:<what>"
|
||||
On progress: $PY … --job "$JOB_ID" --event progress --detail "<short status>"
|
||||
On success: $PY … --job "$JOB_ID" --event completed --detail "<one-line summary>"
|
||||
@@ -261,17 +261,17 @@ agent").
|
||||
|
||||
## User Interface
|
||||
|
||||
The [`tmux-agent-orchestrate-delegate-job`](./tmux-agent-orchestrate-delegate-job) bash wrapper bundles register +
|
||||
The [`multi-agent-mux-delegate-job`](./multi-agent-mux-delegate-job) bash wrapper bundles register +
|
||||
subscribe-first + run-agent + validate:
|
||||
|
||||
```bash
|
||||
tmux-agent-orchestrate-delegate-job submit --agent claude-code \
|
||||
multi-agent-mux-delegate-job submit --agent claude-code \
|
||||
--prompt "정렬 문제 10개를 만들어 sort_problems.md로 저장" \
|
||||
--workdir /path/to/project --timeout 3600 [--validate ./validate.sh]
|
||||
tmux-agent-orchestrate-delegate-job status --job <id> # one record, pretty-printed
|
||||
tmux-agent-orchestrate-delegate-job list # all jobs, one line each
|
||||
tmux-agent-orchestrate-delegate-job verify --job <id> --validate ./validate.sh # runs it, reports exit code
|
||||
tmux-agent-orchestrate-delegate-job wait [--job <id>] # block until terminal (else --wait-any)
|
||||
multi-agent-mux-delegate-job status --job <id> # one record, pretty-printed
|
||||
multi-agent-mux-delegate-job list # all jobs, one line each
|
||||
multi-agent-mux-delegate-job verify --job <id> --validate ./validate.sh # runs it, reports exit code
|
||||
multi-agent-mux-delegate-job wait [--job <id>] # block until terminal (else --wait-any)
|
||||
```
|
||||
|
||||
`submit` **always starts the subscriber before the agent** (the ordering
|
||||
@@ -377,7 +377,7 @@ has been verified (2026-06-21, 6-batch refactoring sprint):
|
||||
logging failure (e.g. read-only log dir) does not break the publish or
|
||||
subscribe path — only a `logger.warning` is emitted.
|
||||
- [ ] **end-to-end demo smoke** — run
|
||||
`tmux-agent-orchestrate-delegate-job submit --agent claude-code --agent-session tmux:demo-smoke
|
||||
`multi-agent-mux-delegate-job submit --agent claude-code --agent-session tmux:demo-smoke
|
||||
--prompt "echo hello and call publish_event.py --job <JID>
|
||||
--event completed" --timeout 120` and confirm
|
||||
(a) registered job id echoed, (b) subscriber pid echoed, (c) tmux session
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Job Event Protocol
|
||||
|
||||
The wire contract every tmux-agent-orchestrate-delegate-job agent (claude-code, codex, opencode,
|
||||
The wire contract every multi-agent-mux-delegate-job agent (claude-code, codex, opencode,
|
||||
human, …) speaks. One job → one MQTT topic → JSON event payloads. Stable across
|
||||
the PoC (public broker) and production (own broker) stages; only transport
|
||||
hardening changes, never the payload shape.
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# MQTT Broker Setup — PoC → Production
|
||||
|
||||
The tmux-agent-orchestrate-delegate-job scripts read **all** broker settings from environment
|
||||
The multi-agent-mux-delegate-job scripts read **all** broker settings from environment
|
||||
variables (or a job record's `broker.*` block) through a single helper,
|
||||
`broker_config_from_env()` in
|
||||
[`./scripts/mqtt_common.py`](./scripts/mqtt_common.py). The design goal:
|
||||
@@ -152,7 +152,7 @@ export MQTT_PASSWORD=… # subscriber side
|
||||
mosquitto_sub -h "$MQTT_BROKER" -p 8883 --cafile "$MQTT_CA_CERTS" \
|
||||
-u hermes -P "$MQTT_PASSWORD" -t 'python/mqtt/jobs/+/events' -v &
|
||||
|
||||
# 3) run the unchanged tmux-agent-orchestrate-delegate-job loop
|
||||
# 3) run the unchanged multi-agent-mux-delegate-job loop
|
||||
PY=.venv/bin/python
|
||||
JID=$($PY scripts/registry.py register --prompt "broker cutover smoke")
|
||||
$PY scripts/job_subscriber.py --job "$JID" --timeout 30 &
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# tmux-agent-orchestrate-delegate-job — user-facing orchestrator for the tmux-agent-orchestrate-delegate-job skill.
|
||||
# multi-agent-mux-delegate-job — user-facing orchestrator for the multi-agent-mux-delegate-job skill.
|
||||
#
|
||||
# Subcommands:
|
||||
# submit register a job, start the subscriber FIRST, then run the agent,
|
||||
@@ -41,7 +41,7 @@ REGISTRY_DIR_DEFAULT=".mam/jobs"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
tmux-agent-orchestrate-delegate-job <command> [options]
|
||||
multi-agent-mux-delegate-job <command> [options]
|
||||
|
||||
submit --agent <name> --prompt <text> [--workdir <dir>] [--agent-session <label>]
|
||||
[--timeout <sec>] [--idle-timeout <sec>] [--validate <script>]
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
"""Shared MQTT + registry helpers for the tmux-agent-orchestrate-delegate-job skill.
|
||||
"""Shared MQTT + registry helpers for the multi-agent-mux-delegate-job skill.
|
||||
|
||||
Single entry point for:
|
||||
- broker configuration (env -> dataclass),
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
"""Job registry for the tmux-agent-orchestrate-delegate-job skill.
|
||||
"""Job registry for the multi-agent-mux-delegate-job skill.
|
||||
|
||||
A job record is the single source of truth for one delegated unit of work:
|
||||
its id, prompt, owning agent session, broker connection, timeouts, and status.
|
||||
@@ -9,7 +9,7 @@ Concurrency is handled via the fcntl lock in :mod:`mqtt_common` (PoC). For
|
||||
multi-host delegation, migrate to SQLite WAL — see references/registry.md.
|
||||
|
||||
Importable as a library and runnable as a CLI (``register``/``list``/``get``/
|
||||
``status``/``pick``) so the ``tmux-agent-orchestrate-delegate-job`` bash wrapper can shell out.
|
||||
``status``/``pick``) so the ``multi-agent-mux-delegate-job`` bash wrapper can shell out.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -184,7 +184,7 @@ def _iter_records(registry_dir: str):
|
||||
# CLI (so the bash wrapper can shell out without inline python)
|
||||
# --------------------------------------------------------------------------
|
||||
def _build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description="tmux-agent-orchestrate-delegate-job registry CLI")
|
||||
parser = argparse.ArgumentParser(description="multi-agent-mux-delegate-job registry CLI")
|
||||
parser.add_argument("--registry-dir", default=DEFAULT_REGISTRY_DIR)
|
||||
sub = parser.add_subparsers(dest="command", required=True)
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: tmux-agent-orchestrate-monitor
|
||||
name: multi-agent-mux-monitor
|
||||
description: "Run a long-lived Kanban worker that polls .mam/agent-sessions.yaml against the actual tmux/agent runtime state and reconciles them. Use when you want live visibility into which agent sessions are running, which are dead, which have stale YAML entries, and which have new session ids that haven't been recorded yet. Designed to be dispatched as a Kanban goal_mode task (--goal) so it keeps running until the user stops it."
|
||||
version: 1.0.0
|
||||
author: godopu
|
||||
@@ -9,13 +9,13 @@ environments: [kanban, terminal, tmux]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [agent, tmux, claude, antigravity, agy, monitor, kanban, observation, reconciliation]
|
||||
related_skills: [tmux-agent-orchestrate-create, tmux-agent-orchestrate-resume, tmux-agent-orchestrate-stop, kanban-orchestrator]
|
||||
prereq_skills: [kanban-worker, tmux-agent-orchestrate-create]
|
||||
related_skills: [multi-agent-mux-create, multi-agent-mux-resume, multi-agent-mux-stop, kanban-orchestrator]
|
||||
prereq_skills: [kanban-worker, multi-agent-mux-create]
|
||||
---
|
||||
|
||||
# Agent Sessions Monitor — Live Reconciliation via Kanban Worker
|
||||
|
||||
> **Companion skills**: `tmux-agent-orchestrate-create` / `tmux-agent-orchestrate-resume` / `tmux-agent-orchestrate-stop` (mutators); this skill is the **observer**.
|
||||
> **Companion skills**: `multi-agent-mux-create` / `multi-agent-mux-resume` / `multi-agent-mux-stop` (mutators); this skill is the **observer**.
|
||||
> **Single source of truth**: `./.mam/agent-sessions.yaml`.
|
||||
|
||||
## What this skill does
|
||||
@@ -59,12 +59,12 @@ hermes kanban create \
|
||||
--title "agent-sessions monitor (live reconcile)" \
|
||||
--assignee default \
|
||||
--workspace worktree \
|
||||
--branch wt/tmux-agent-orchestrate-monitor \
|
||||
--branch wt/multi-agent-mux-monitor \
|
||||
--goal \
|
||||
--goal-max-turns 100 \
|
||||
--max-runtime 8h \
|
||||
--max-retries 1 \
|
||||
--skill tmux-agent-orchestrate-monitor \
|
||||
--skill multi-agent-mux-monitor \
|
||||
--body "$(cat <<'EOF'
|
||||
You are the agent-sessions monitor. Every 30 seconds, do:
|
||||
|
||||
@@ -79,7 +79,7 @@ If the user comments `stop` or `stop monitoring` on this card, call `kanban_bloc
|
||||
|
||||
If you find that a Claude session's `claude_session_id_own` is null but there's a new *.jsonl in the project dir, read the sessionId from the first line and update the YAML.
|
||||
|
||||
Use the helper script at .agents/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh for the YAML updates — it handles all the merge logic and writes a structured comment to this card.
|
||||
Use the helper script at .agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh for the YAML updates — it handles all the merge logic and writes a structured comment to this card.
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
@@ -94,17 +94,17 @@ The worker calls this script every 30s. It:
|
||||
|
||||
```bash
|
||||
# Reconcile + auto-update YAML (atomic, flock-guarded). Emits JSON drift to stdout.
|
||||
bash .agents/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --once --emit-diff
|
||||
bash .agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh --once --emit-diff
|
||||
|
||||
# Read-only: compute drift WITHOUT writing the YAML (use for "what's running?" checks).
|
||||
bash .agents/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --once --emit-diff --dry-run
|
||||
bash .agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh --once --emit-diff --dry-run
|
||||
|
||||
# Push-based MQTT Monitor: listen to delegated job events on the broker and update the YAML instantly.
|
||||
# Bounded run that exits after 5 min idle, or 1 h wall-clock; falls back to polling if the broker is down.
|
||||
bash .agents/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --subscribe --idle-timeout 300 --timeout 3600
|
||||
bash .agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh --subscribe --idle-timeout 300 --timeout 3600
|
||||
|
||||
# Persistent monitor (no timeouts): runs until interrupted; still polls if the broker is unreachable.
|
||||
bash .agents/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --subscribe --idle-timeout 0
|
||||
bash .agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh --subscribe --idle-timeout 0
|
||||
```
|
||||
|
||||
Flags: `--once` (single pass), `--emit-diff` (print JSON), `--dry-run` (P1-E — no mutation), `--subscribe` (push-based MQTT subscription monitoring). `--subscribe` sub-flags: `--timeout N` (exit after N seconds of wall-clock; `0` = no limit, default), `--idle-timeout N` (exit after N seconds with no message; default `3600`, `0` = never idle-out). On a broker connection failure (connect error **or** non-zero CONNACK), `--subscribe` falls back to a polling loop that re-runs `--once --emit-diff` every `RECONCILE_POLL_INTERVAL` (default 15) seconds until `--timeout`. Terminal-event YAML updates are written through `lib.sh::atomic_dump_yaml` (flock + schema-validate + `.bak`). There are **no** `--workspace` / `--agent` / `--comment-card` flags; the worker turns the emitted JSON `drifts[]` into `kanban_comment` calls itself.
|
||||
@@ -126,7 +126,7 @@ tmux: no session
|
||||
|
||||
**Skip-set**: the auto-terminate only fires for sessions whose status is `running`.
|
||||
Rows already in a deliberate end state — `terminated`, `archived`, or **`stopped`**
|
||||
(set by `tmux-agent-orchestrate-stop`) — are
|
||||
(set by `multi-agent-mux-stop`) — are
|
||||
left untouched. This is critical: a `stopped` row keeps its `resumable: true` and
|
||||
captured `*_session_id_own`, so the monitor must **not** overwrite it with
|
||||
`terminated ("auto-detected")` when its tmux is (expectedly) gone.
|
||||
@@ -165,8 +165,8 @@ disk: ~/.claude/projects/.../87dc548e-...jsonl: missing
|
||||
|
||||
- **Don't run the monitor without `--goal`** — without goal mode, a single turn will spawn, do one reconcile, and complete. Goal mode keeps the worker alive across many turns.
|
||||
- **The 30s poll is a default** — workers may override if they detect heavy churn. A workspace with 5+ agent sessions should bump to 60s to avoid noise.
|
||||
- **`kanban_comment` rate limits** — Kanban may throttle if you comment too fast. Coalesce: only comment when the diff is *new* (not the same drift on every poll). The script tracks a state file at `.cache/tmux-agent-orchestrate-monitor/<workspace>.state` in the workspace root for this (overridable via `AGENT_SESSIONS_STATE_DIR`).
|
||||
- **Don't fight the user's explicit action** — if `tmux-agent-orchestrate-stop` is mid-flight and the monitor sees the same session in two states within 5s, prefer the user's most recent action. The monitor should not auto-revert a fresh `terminated` to `running` because of a stale `tmux has-session` check.
|
||||
- **`kanban_comment` rate limits** — Kanban may throttle if you comment too fast. Coalesce: only comment when the diff is *new* (not the same drift on every poll). The script tracks a state file at `.cache/multi-agent-mux-monitor/<workspace>.state` in the workspace root for this (overridable via `AGENT_SESSIONS_STATE_DIR`).
|
||||
- **Don't fight the user's explicit action** — if `multi-agent-mux-stop` is mid-flight and the monitor sees the same session in two states within 5s, prefer the user's most recent action. The monitor should not auto-revert a fresh `terminated` to `running` because of a stale `tmux has-session` check.
|
||||
- **The monitor should never modify the conversation artifacts** (jsonl, db) — only the YAML. If you see a stale UUID, comment about it but don't delete the file.
|
||||
- **TUI capture-pane is expensive** — only capture when you need to update `last_visible_status`, not every poll.
|
||||
|
||||
@@ -180,7 +180,7 @@ The `--body` of the dispatched task IS the worker's behavior spec. Here's a test
|
||||
## Loop (every 30s)
|
||||
|
||||
1. Read agent-sessions.yaml
|
||||
2. Bash: `bash .agents/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --emit-diff`
|
||||
2. Bash: `bash .agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh --emit-diff`
|
||||
3. Parse the JSON diff from stdout
|
||||
4. If `drifts` is non-empty:
|
||||
- For each drift, call `kanban_comment` with the diff message
|
||||
@@ -203,7 +203,7 @@ If `$HERMES_KANBAN_TASK` card has any comment containing "stop" or "stop monitor
|
||||
|
||||
- Do NOT modify conversation artifacts (jsonl, db, brain/)
|
||||
- Do NOT spawn/delete tmux sessions — that's the create/delete skills' job
|
||||
- Do NOT call tmux-agent-orchestrate-create or tmux-agent-orchestrate-stop — only the user initiates those
|
||||
- Do NOT call multi-agent-mux-create or multi-agent-mux-stop — only the user initiates those
|
||||
- Do NOT call `git commit` / `git push`
|
||||
```
|
||||
|
||||
@@ -226,7 +226,7 @@ When using `--subscribe` with the default PoC public broker
|
||||
|
||||
```bash
|
||||
# Run reconcile once and inspect output
|
||||
bash .agents/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --emit-diff --once \
|
||||
bash .agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh --emit-diff --once \
|
||||
| python3 -m json.tool
|
||||
```
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# reconcile.sh — tmux-agent-orchestrate-monitor 의 부속 스크립트
|
||||
# reconcile.sh — multi-agent-mux-monitor 의 부속 스크립트
|
||||
# YAML ↔ tmux ↔ 디스크 artifact 간 drift 감지 (+ YAML 자동 갱신).
|
||||
#
|
||||
# Usage:
|
||||
@@ -7,7 +7,7 @@
|
||||
# bash reconcile.sh --once --emit-diff --dry-run # drift 만 계산, 쓰기 안 함 (P1-E)
|
||||
#
|
||||
# --dry-run: 부수효과 없는 read-only. "지금 뭐 돌고 있지?" 질문에 안전.
|
||||
# tmux-agent-orchestrate-status 스킬이 이걸 재사용.
|
||||
# multi-agent-mux-status 스킬이 이걸 재사용.
|
||||
#
|
||||
# 출력 (JSON): {timestamp, yaml_path, tmux_sessions_alive, tmux_confirmed, drifts, actions}
|
||||
#
|
||||
@@ -16,7 +16,7 @@ set -euo pipefail
|
||||
|
||||
source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh"
|
||||
|
||||
STATE_DIR="${AGENT_SESSIONS_STATE_DIR:-$WORKSPACE_ROOT/.cache/tmux-agent-orchestrate-monitor}"
|
||||
STATE_DIR="${AGENT_SESSIONS_STATE_DIR:-$WORKSPACE_ROOT/.cache/multi-agent-mux-monitor}"
|
||||
|
||||
ONCE=0
|
||||
EMIT_DIFF=0
|
||||
@@ -65,16 +65,16 @@ skills_dir = os.environ.get('SKILLS_DIR', '')
|
||||
timeout = int(os.environ.get('SUB_TIMEOUT', '0') or '0') # 0 = no overall timeout
|
||||
idle_timeout = int(os.environ.get('SUB_IDLE_TIMEOUT', '3600') or '0') # 0 = no idle timeout
|
||||
|
||||
# Locate skills/tmux-agent-orchestrate-delegate-job/scripts to import mqtt_common — relative first, then
|
||||
# Locate skills/multi-agent-mux-delegate-job/scripts to import mqtt_common — relative first, then
|
||||
# an upward walk from cwd. No hardcoded absolute path (review item 6).
|
||||
cand = os.path.join(skills_dir, 'tmux-agent-orchestrate-delegate-job', 'scripts') if skills_dir else ''
|
||||
cand = os.path.join(skills_dir, 'multi-agent-mux-delegate-job', 'scripts') if skills_dir else ''
|
||||
if cand and os.path.isdir(cand):
|
||||
sys.path.append(cand)
|
||||
else:
|
||||
d = os.getcwd()
|
||||
while d and d != '/':
|
||||
hit = None
|
||||
for sub in (('.agents', 'skills', 'tmux-agent-orchestrate-delegate-job', 'scripts'), ('skills', 'tmux-agent-orchestrate-delegate-job', 'scripts'), ('tmux-agent-orchestrate-delegate-job', 'scripts')):
|
||||
for sub in (('.agents', 'skills', 'multi-agent-mux-delegate-job', 'scripts'), ('skills', 'multi-agent-mux-delegate-job', 'scripts'), ('multi-agent-mux-delegate-job', 'scripts')):
|
||||
p = os.path.join(d, *sub)
|
||||
if os.path.isdir(p):
|
||||
hit = p
|
||||
@@ -204,7 +204,7 @@ PYEOF
|
||||
|
||||
if [ "$sub_rc" = "3" ]; then
|
||||
echo "MQTT Monitor: broker unavailable — falling back to polling (interval ${POLL_INTERVAL}s)" >&2
|
||||
_self="$SKILLS_DIR/tmux-agent-orchestrate-monitor/scripts/reconcile.sh"
|
||||
_self="$SKILLS_DIR/multi-agent-mux-monitor/scripts/reconcile.sh"
|
||||
_start=$(date +%s)
|
||||
while :; do
|
||||
bash "$_self" --once --emit-diff >/dev/null 2>&1 || true
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# watchdog.sh — tmux-agent-orchestrate-monitor 의 부속 스크립트
|
||||
# watchdog.sh — multi-agent-mux-monitor 의 부속 스크립트
|
||||
#
|
||||
# Metadata for SKILL.md:
|
||||
# description: "Watchdog helper that keeps subscriber alive and exits when JOB is done"
|
||||
@@ -24,7 +24,7 @@ log "watchdog started for JOB=$JOB_ID workdir=$WORKDIR"
|
||||
|
||||
while true; do
|
||||
# 1) Get current job status with robust Python parsing
|
||||
STATUS=$(cd "$WORKDIR" && .venv/bin/python .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py get --job "$JOB_ID" 2>/dev/null | python3 -c '
|
||||
STATUS=$(cd "$WORKDIR" && .venv/bin/python .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py get --job "$JOB_ID" 2>/dev/null | python3 -c '
|
||||
import sys, json
|
||||
try:
|
||||
data = json.load(sys.stdin)
|
||||
@@ -48,7 +48,7 @@ except Exception:
|
||||
log "starting subscriber (2min hard limit, log: $LOG_FILE)"
|
||||
|
||||
(
|
||||
cd "$WORKDIR" && timeout 120 .venv/bin/python .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/job_subscriber.py \
|
||||
cd "$WORKDIR" && timeout 120 .venv/bin/python .agents/skills/multi-agent-mux-delegate-job/scripts/job_subscriber.py \
|
||||
--job "$JOB_ID" --timeout 120 --idle-timeout 999999 --registry-dir .mam/jobs > "$LOG_FILE" 2>&1
|
||||
echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] subscriber exited" >> "$LOG_FILE"
|
||||
) &
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: tmux-agent-orchestrate-resume
|
||||
name: multi-agent-mux-resume
|
||||
description: "Resume an existing agent (claude, antigravity/agy) conversation by UUID into a tmux session. Reads .mam/agent-sessions.yaml for the saved session/conversation id, spawns (or reuses) a tmux session of the matching name, and runs `claude -r <id>` or `agy --conversation <id>` inside. Use when you want to reattach to a previous session's context, or revive a session whose tmux died but the agent's conversation is still on disk."
|
||||
version: 1.0.0
|
||||
author: godopu
|
||||
@@ -9,14 +9,14 @@ environments: [terminal, tmux]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [agent, tmux, claude, antigravity, agy, multi-agent, context, resume, session-id]
|
||||
related_skills: [tmux-agent-orchestrate-create, tmux-agent-orchestrate-stop, tmux-agent-orchestrate-monitor, claude-code]
|
||||
prereq_skills: [tmux-agent-orchestrate-create]
|
||||
related_skills: [multi-agent-mux-create, multi-agent-mux-stop, multi-agent-mux-monitor, claude-code]
|
||||
prereq_skills: [multi-agent-mux-create]
|
||||
---
|
||||
|
||||
# Multi-Agent Resume — Reattach to a Saved Conversation
|
||||
|
||||
> **Companion skills**: `tmux-agent-orchestrate-create` (start a fresh agent), `tmux-agent-orchestrate-stop` (terminate), `tmux-agent-orchestrate-monitor` (live status).
|
||||
> **Tmux Isolation**: `TMUX_SERVER_NAME` env var를 create에서 설정한 경우, 동일 서버에서 동작합니다. 자세한 격리 패턴은 [tmux-agent-orchestrate-create/SKILL.md](../tmux-agent-orchestrate-create/SKILL.md) 참조.
|
||||
> **Companion skills**: `multi-agent-mux-create` (start a fresh agent), `multi-agent-mux-stop` (terminate), `multi-agent-mux-monitor` (live status).
|
||||
> **Tmux Isolation**: `TMUX_SERVER_NAME` env var를 create에서 설정한 경우, 동일 서버에서 동작합니다. 자세한 격리 패턴은 [multi-agent-mux-create/SKILL.md](../multi-agent-mux-create/SKILL.md) 참조.
|
||||
> **Single source of truth**: `./.mam/agent-sessions.yaml`.
|
||||
|
||||
## What this skill does
|
||||
@@ -26,12 +26,12 @@ metadata:
|
||||
Three cases this skill handles:
|
||||
|
||||
1. **tmux is dead, conversation lives** — `agent-sessions.yaml` has the UUID. The JSONL/db is on disk. Re-spawn the tmux session + run `claude -r <id>` / `agy --conversation <id>`.
|
||||
2. **tmux is alive but empty** — You started a session with `tmux-agent-orchestrate-create` but haven't sent a message yet (so no session id was assigned). The user can either send their first message (and the id is auto-assigned), or you can read the *workspace's* most recent conversation from `$HOME_DIR/.gemini/antigravity-cli/cache/last_conversations.json` (defaults to `~/.gemini/...`) for agy, or the latest `*.jsonl` in `$CLAUDE_PROJECT_DIR/<workspace-key>/` (defaults to `~/.claude/projects/`) for claude.
|
||||
2. **tmux is alive but empty** — You started a session with `multi-agent-mux-create` but haven't sent a message yet (so no session id was assigned). The user can either send their first message (and the id is auto-assigned), or you can read the *workspace's* most recent conversation from `$HOME_DIR/.gemini/antigravity-cli/cache/last_conversations.json` (defaults to `~/.gemini/...`) for agy, or the latest `*.jsonl` in `$CLAUDE_PROJECT_DIR/<workspace-key>/` (defaults to `~/.claude/projects/`) for claude.
|
||||
3. **tmux is alive AND the agent inside is already running** — Just attach. No re-spawn needed.
|
||||
|
||||
### Resuming a `stopped` session (`stopped → running`)
|
||||
|
||||
When a session was ended via `tmux-agent-orchestrate-stop` (which captures the ID and gracefully stops by default),
|
||||
When a session was ended via `multi-agent-mux-stop` (which captures the ID and gracefully stops by default),
|
||||
its row is `status: stopped` with `resumable: true` and the conversation id
|
||||
already recorded in `claude_session_id_own` / `agy_conversation_id_own`. This is the
|
||||
ideal resume path:
|
||||
@@ -55,21 +55,21 @@ ideal resume path:
|
||||
- claude: `ls -t $CLAUDE_PROJECT_DIR/<workspace-key>/*.jsonl | head -1` and parse the `sessionId` from the first line
|
||||
- agy: `jq -r '."<workspace>"' $HOME_DIR/.gemini/antigravity-cli/cache/last_conversations.json`
|
||||
|
||||
If all three are empty → the workspace has no conversation yet. Fall back to `tmux-agent-orchestrate-create`.
|
||||
If all three are empty → the workspace has no conversation yet. Fall back to `multi-agent-mux-create`.
|
||||
|
||||
## Workflow
|
||||
|
||||
```bash
|
||||
WORKSPACE=/path/to/project
|
||||
AGENT=claude # or agy or hermes
|
||||
SESSION_NAME=<workspace>-creator-<agent> # same convention as tmux-agent-orchestrate-create
|
||||
SESSION_NAME=<workspace>-creator-<agent> # same convention as multi-agent-mux-create
|
||||
|
||||
# 1. Resolve the session id
|
||||
UUID=$(bash .agents/skills/tmux-agent-orchestrate-resume/scripts/resolve_session_id.sh \
|
||||
UUID=$(bash .agents/skills/multi-agent-mux-resume/scripts/resolve_session_id.sh \
|
||||
--workspace "$WORKSPACE" --agent "$AGENT")
|
||||
|
||||
if [ -z "$UUID" ]; then
|
||||
echo "No saved session for $WORKSPACE ($AGENT). Use tmux-agent-orchestrate-create first."
|
||||
echo "No saved session for $WORKSPACE ($AGENT). Use multi-agent-mux-create first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -107,8 +107,8 @@ case "$AGENT" in
|
||||
esac
|
||||
|
||||
# 4. Update agent-sessions.yaml: status running, last_visible_status
|
||||
# (Also automatically publishes a `progress --detail "resumed"` event to the tmux-agent-orchestrate-delegate-job registry if a delegate_job_id exists)
|
||||
bash .agents/skills/tmux-agent-orchestrate-resume/scripts/update_yaml_resumed.sh \
|
||||
# (Also automatically publishes a `progress --detail "resumed"` event to the multi-agent-mux-delegate-job registry if a delegate_job_id exists)
|
||||
bash .agents/skills/multi-agent-mux-resume/scripts/update_yaml_resumed.sh \
|
||||
--session "$SESSION_NAME" --uuid "$UUID"
|
||||
|
||||
# 5. Attach
|
||||
@@ -120,8 +120,8 @@ tmux attach -t "$SESSION_NAME"
|
||||
- **`claude -r` requires the SAME project directory** — if the workspace path differs from when the session was created, claude will create a new project dir key (`-home-...-different-name`) and put the resume in a different location. Always `-c` (cd to workspace) before running.
|
||||
- **agy's `--conversation` flag name varies by version** — older versions used `--resume` or `-r`. Check `agy --help | grep -E "conversation|resume"` and use the right flag. v1.0.x: `--conversation`.
|
||||
- **The first message after resume might re-trigger TUI dialogs** — if the original session was created with `--dangerously-skip-permissions`, those flags are NOT persisted; you must re-apply them on resume. The script above re-passes them.
|
||||
- **Don't resume if the session is brand new and empty** — `tmux-agent-orchestrate-create` already set up an empty container; sending a probe message ("init") is the right way to materialize a session id, NOT `claude -r` with a placeholder.
|
||||
- **`agy --conversation <id>` will fail if the conversation was deleted from disk** — check `~/.gemini/antigravity-cli/conversations/<uuid>.db` exists before attempting resume. If missing, the conversation is gone; you need a fresh session via `tmux-agent-orchestrate-create`.
|
||||
- **Don't resume if the session is brand new and empty** — `multi-agent-mux-create` already set up an empty container; sending a probe message ("init") is the right way to materialize a session id, NOT `claude -r` with a placeholder.
|
||||
- **`agy --conversation <id>` will fail if the conversation was deleted from disk** — check `~/.gemini/antigravity-cli/conversations/<uuid>.db` exists before attempting resume. If missing, the conversation is gone; you need a fresh session via `multi-agent-mux-create`.
|
||||
|
||||
## Verification
|
||||
|
||||
@@ -146,6 +146,6 @@ tmux capture-pane -t "$SESSION_NAME" -p -S -30
|
||||
|
||||
## When NOT to use this skill
|
||||
|
||||
- **No saved session yet** → `tmux-agent-orchestrate-create`
|
||||
- **Killing an existing session** → `tmux-agent-orchestrate-stop`
|
||||
- **No saved session yet** → `multi-agent-mux-create`
|
||||
- **Killing an existing session** → `multi-agent-mux-stop`
|
||||
- **Just attaching** → `tmux attach -t <name>` (no skill needed)
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# resolve_session_id.sh — tmux-agent-orchestrate-resume 의 부속 스크립트
|
||||
# resolve_session_id.sh — multi-agent-mux-resume 의 부속 스크립트
|
||||
# Usage:
|
||||
# bash resolve_session_id.sh --workspace <path> --agent <claude|agy>
|
||||
# 출력: stdout 으로 UUID 한 줄 (없으면 빈 줄 + exit 0)
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# update_yaml_resumed.sh — tmux-agent-orchestrate-resume 의 부속 스크립트
|
||||
# update_yaml_resumed.sh — multi-agent-mux-resume 의 부속 스크립트
|
||||
# Resume 한 세션의 agent-sessions.yaml 엔트리를 status=running + resume 메타로 갱신.
|
||||
# resume UUID 를 per-row own id (claude_session_id_own / agy_conversation_id_own)
|
||||
# 에 박는다 — agent_identities 전역은 더 이상 primary 아님 (cache 로 강등, P0-C/단계 e).
|
||||
+16
-16
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: tmux-agent-orchestrate-status
|
||||
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."
|
||||
version: 1.0.0
|
||||
author: godopu
|
||||
@@ -9,13 +9,13 @@ environments: [terminal, tmux]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [agent, tmux, claude, antigravity, agy, status, read-only, snapshot]
|
||||
related_skills: [tmux-agent-orchestrate-create, tmux-agent-orchestrate-resume, tmux-agent-orchestrate-stop, tmux-agent-orchestrate-monitor]
|
||||
prereq_skills: [tmux-agent-orchestrate-create, tmux-agent-orchestrate-monitor]
|
||||
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]
|
||||
---
|
||||
|
||||
# Multi-Agent Status — Read-Only Instant Snapshot
|
||||
|
||||
> **Companion skills**: `tmux-agent-orchestrate-create` (start), `tmux-agent-orchestrate-resume` (re-attach), `tmux-agent-orchestrate-stop` (terminate), `tmux-agent-orchestrate-monitor` (live polling).
|
||||
> **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` 환경변수를 수동으로 지정하지 않아도 모든 격리 서버의 세션 상태를 통합 조회합니다.
|
||||
> **Single source of truth**: `./.mam/agent-sessions.yaml`.
|
||||
|
||||
@@ -23,7 +23,7 @@ metadata:
|
||||
|
||||
Print a single table of every agent tmux session, comparing YAML state to actual tmux state. **No mutation. No Kanban. No polling loop.**
|
||||
|
||||
This is the "what's running right now?" answer — faster than dispatching `tmux-agent-orchestrate-monitor` (which polls every 30s) and safer than `reconcile.sh --once --emit-diff` (which mutates as a side effect).
|
||||
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
|
||||
|
||||
@@ -33,12 +33,12 @@ command -v python3
|
||||
test -f .mam/agent-sessions.yaml
|
||||
```
|
||||
|
||||
If `agent-sessions.yaml` doesn't exist or is malformed → print clear error, exit 1. **Do not create it.** (Use `tmux-agent-orchestrate-create` first.)
|
||||
If `agent-sessions.yaml` doesn't exist or is malformed → print clear error, exit 1. **Do not create it.** (Use `multi-agent-mux-create` first.)
|
||||
|
||||
## Workflow
|
||||
|
||||
```bash
|
||||
bash .agents/skills/tmux-agent-orchestrate-status/scripts/status.sh [--json]
|
||||
bash .agents/skills/multi-agent-mux-status/scripts/status.sh [--json]
|
||||
```
|
||||
|
||||
The script:
|
||||
@@ -98,17 +98,17 @@ lab-paper-pdf2md-creator-claude default running alive clau
|
||||
|
||||
| Class | Detection | Meaning |
|
||||
|---|---|---|
|
||||
| `A` | YAML `running`, tmux dead | session died without going through `tmux-agent-orchestrate-stop`. *Could* auto-terminate but won't — that's `tmux-agent-orchestrate-monitor`'s job. |
|
||||
| `B` | tmux alive, not in YAML | ad-hoc session someone started without `tmux-agent-orchestrate-create`. Suggest: "use tmux-agent-orchestrate-create to register, or tmux kill-session to clean up." |
|
||||
| `C` | YAML has `claude_session_id_own: null` AND a new *.jsonl exists | new session id materialized; suggest: "run tmux-agent-orchestrate-resume or reconcile to register it." |
|
||||
| `D` | YAML has UUID in `agent_identities`, but the on-disk artifact is gone | stale UUID; user should `tmux-agent-orchestrate-stop --purge-conversation` to clean up. |
|
||||
| `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." |
|
||||
| `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 `tmux-agent-orchestrate-monitor` (Kanban worker) or run `tmux-agent-orchestrate-resume` / `tmux-agent-orchestrate-stop` manually.
|
||||
- **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.
|
||||
- **If `agent-sessions.yaml` is malformed** — print the YAML error verbatim and exit 1. Do NOT attempt recovery (that's `tmux-agent-orchestrate-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 `tmux-agent-orchestrate-create` and aren't tracked in YAML.
|
||||
- **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.
|
||||
|
||||
## When to use
|
||||
|
||||
@@ -119,6 +119,6 @@ lab-paper-pdf2md-creator-claude default running alive clau
|
||||
|
||||
## When NOT to use
|
||||
|
||||
- Continuous live tracking → `tmux-agent-orchestrate-monitor` (Kanban worker)
|
||||
- Continuous live tracking → `multi-agent-mux-monitor` (Kanban worker)
|
||||
- Recovering from corruption → manual edit + `.bak` restore
|
||||
- Polling more than once a minute → `tmux-agent-orchestrate-monitor` (it dedupes)
|
||||
- Polling more than once a minute → `multi-agent-mux-monitor` (it dedupes)
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# status.sh — tmux-agent-orchestrate-status 의 부속 스크립트 (READ-ONLY)
|
||||
# status.sh — multi-agent-mux-status 의 부속 스크립트 (READ-ONLY)
|
||||
# 한 번 호출로 현재 agent 세션 상태표를 출력. 부수효과 없음.
|
||||
# reconcile.sh --dry-run 을 재사용해 drift 를 계산하고 (P1-E), YAML/디스크에서
|
||||
# 보강한 표를 그린다. YAML 을 절대 수정하지 않는다.
|
||||
@@ -9,12 +9,12 @@ set -euo pipefail
|
||||
|
||||
source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh"
|
||||
|
||||
RECONCILE="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/tmux-agent-orchestrate-monitor/scripts/reconcile.sh"
|
||||
RECONCILE="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/multi-agent-mux-monitor/scripts/reconcile.sh"
|
||||
|
||||
JSON=0
|
||||
[ "${1:-}" = "--json" ] && JSON=1
|
||||
|
||||
[ -f "$AGENT_SESSIONS_YAML" ] || { echo "ERROR: $AGENT_SESSIONS_YAML not found. Run tmux-agent-orchestrate-create first." >&2; exit 1; }
|
||||
[ -f "$AGENT_SESSIONS_YAML" ] || { echo "ERROR: $AGENT_SESSIONS_YAML not found. Run multi-agent-mux-create first." >&2; exit 1; }
|
||||
|
||||
# read-only drift snapshot — reconcile.sh --dry-run (no side effects)
|
||||
DRIFT_JSON="$(bash "$RECONCILE" --once --emit-diff --dry-run)"
|
||||
@@ -24,7 +24,7 @@ if [ "$JSON" = "1" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Project root (parent of .agents/) holds the tmux-agent-orchestrate-delegate-job .mam registry.
|
||||
# Project root (parent of .agents/) holds the multi-agent-mux-delegate-job .mam registry.
|
||||
# Resolved relative to this script — no hardcoded absolute path (review item 6).
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../" && pwd)"
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: tmux-agent-orchestrate-stop
|
||||
name: multi-agent-mux-stop
|
||||
description: "Stop an agent tmux session (claude, antigravity/agy) and update .mam/agent-sessions.yaml. Default stops gracefully and marks status=stopped with conversation preserved for resume. Does NOT delete on-disk conversation artifacts (jsonl/db) — those are preserved unless --purge-conversation is passed. Use when ending a work session, switching to a different one, or cleaning up before a fresh start."
|
||||
version: 1.0.0
|
||||
author: godopu
|
||||
@@ -9,13 +9,13 @@ environments: [terminal, tmux]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [agent, tmux, claude, antigravity, agy, multi-agent, stop, terminate, cleanup]
|
||||
related_skills: [tmux-agent-orchestrate-create, tmux-agent-orchestrate-resume, tmux-agent-orchestrate-monitor]
|
||||
prereq_skills: [tmux-agent-orchestrate-create, tmux-agent-orchestrate-resume]
|
||||
related_skills: [multi-agent-mux-create, multi-agent-mux-resume, multi-agent-mux-monitor]
|
||||
prereq_skills: [multi-agent-mux-create, multi-agent-mux-resume]
|
||||
---
|
||||
|
||||
# Multi-Agent Stop — Stop an Agent tmux Session
|
||||
|
||||
> **Companion skills**: `tmux-agent-orchestrate-create` (start), `tmux-agent-orchestrate-resume` (re-attach), `tmux-agent-orchestrate-monitor` (live status).
|
||||
> **Companion skills**: `multi-agent-mux-create` (start), `multi-agent-mux-resume` (re-attach), `multi-agent-mux-monitor` (live status).
|
||||
> **Tmux Isolation**: `stop` 명령은 YAML의 `tmux_server` 필드를 자동으로 파싱하여 해당 격리 서버의 세션을 안전하게 종료(kill)하므로, `TMUX_SERVER_NAME` 환경변수를 수동으로 지정할 필요가 없습니다.
|
||||
> **Single source of truth**: `./.mam/agent-sessions.yaml`.
|
||||
|
||||
@@ -24,8 +24,8 @@ metadata:
|
||||
Stop an agent's tmux session gracefully, resolve and store the conversation ID, and **mark the YAML entry (status=stopped)**. Preserves:
|
||||
|
||||
- The tmux session's recorded `pane.pid / cmd / cwd / mcp_attachments` for audit
|
||||
- The agent's on-disk conversation (claude `*.jsonl`, agy `conversations/*.db`) — so the user can `tmux-agent-orchestrate-resume` later
|
||||
- The `start_command` so a future `tmux-agent-orchestrate-create --session <name>` reproduces the same tmux spec
|
||||
- The agent's on-disk conversation (claude `*.jsonl`, agy `conversations/*.db`) — so the user can `multi-agent-mux-resume` later
|
||||
- The `start_command` so a future `multi-agent-mux-create --session <name>` reproduces the same tmux spec
|
||||
|
||||
The stop command is always **graceful by default**:
|
||||
1. Sends exit keys to the agent TUI (`/exit` for Claude, `Exit` for Agy) and waits 3 seconds.
|
||||
@@ -45,7 +45,7 @@ import yaml
|
||||
d = yaml.safe_load(open('$AGENT_SESSIONS_YAML'))
|
||||
names = [s['name'] for s in d.get('tmux_sessions', [])]
|
||||
if '$SESSION_NAME' not in names:
|
||||
print('NOT in YAML — refusing to stop (no audit trail). Use tmux-agent-orchestrate-create first, or pass --force-no-yaml.')
|
||||
print('NOT in YAML — refusing to stop (no audit trail). Use multi-agent-mux-create first, or pass --force-no-yaml.')
|
||||
raise SystemExit(1)
|
||||
"
|
||||
|
||||
@@ -65,16 +65,16 @@ fi
|
||||
|
||||
```bash
|
||||
# 1. Stop gracefully (default — captures ID, shuts down safely, status=stopped)
|
||||
bash .agents/skills/tmux-agent-orchestrate-stop/scripts/stop_session.sh \
|
||||
bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \
|
||||
--session "$SESSION_NAME"
|
||||
|
||||
# 2. Stop gracefully + record a custom stop reason
|
||||
bash .agents/skills/tmux-agent-orchestrate-stop/scripts/stop_session.sh \
|
||||
bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \
|
||||
--session "$SESSION_NAME" --reason api_error
|
||||
|
||||
# 3. Stop gracefully + clean up on-disk conversation (DANGEROUS)
|
||||
# — this prevents any future resume (status=terminated, resumable=false).
|
||||
bash .agents/skills/tmux-agent-orchestrate-stop/scripts/stop_session.sh \
|
||||
bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \
|
||||
--session "$SESSION_NAME" --purge-conversation
|
||||
```
|
||||
|
||||
@@ -94,19 +94,19 @@ If `--purge-conversation` is used: `status: terminated`, `terminated_at`, `termi
|
||||
|
||||
The script:
|
||||
1. Verifies the session is in agent-sessions.yaml
|
||||
2. If `delegate_job_id` is set, automatically publishes a `progress --detail "terminating"` event to the tmux-agent-orchestrate-delegate-job registry
|
||||
2. If `delegate_job_id` is set, automatically publishes a `progress --detail "terminating"` event to the multi-agent-mux-delegate-job registry
|
||||
3. Captures the `last_visible_status` from `tmux capture-pane` (so we have a final TUI snapshot for audit)
|
||||
4. Attempts graceful exit keys → SIGTERM kill-session → SIGKILL fallback
|
||||
5. For `purge-conversation`: deletes `~/.claude/projects/.../jsonl` (claude) or `~/.gemini/antigravity-cli/conversations/...db` + `brain/...` (agy)
|
||||
6. Updates the YAML entry and SQLite database atomically
|
||||
7. If `delegate_job_id` is set, publishes a `completed` event to the tmux-agent-orchestrate-delegate-job registry
|
||||
7. If `delegate_job_id` is set, publishes a `completed` event to the multi-agent-mux-delegate-job registry
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **Don't delete on-disk artifacts by default** — the agent's `*.jsonl` / `conversations/*.db` is the data that `tmux-agent-orchestrate-resume` needs. `--purge-conversation` is for when the user is genuinely done with the conversation and wants zero recovery chance.
|
||||
- **YAML is append-only until you write a stop** — if a previous run left the entry as `running` but tmux is actually dead (crash, host reboot), the YAML is stale. Running `tmux-agent-orchestrate-stop` will detect "tmux already dead, just update YAML" and proceed.
|
||||
- **Don't delete the `claude_session_id_own: null` placeholder** — when the user creates a fresh session with `tmux-agent-orchestrate-create` and never sent a message, the entry has `claude_session_id_own: null`. Stopping must preserve that field.
|
||||
- **Monitor skill may still be tracking** — if `tmux-agent-orchestrate-monitor` is running a heartbeat loop, stopping a session while it watches will trigger its `tmux ls != yaml` reconciliation. That's expected — let the monitor run, it will mark the entry as `terminated` on its own.
|
||||
- **Don't delete on-disk artifacts by default** — the agent's `*.jsonl` / `conversations/*.db` is the data that `multi-agent-mux-resume` needs. `--purge-conversation` is for when the user is genuinely done with the conversation and wants zero recovery chance.
|
||||
- **YAML is append-only until you write a stop** — if a previous run left the entry as `running` but tmux is actually dead (crash, host reboot), the YAML is stale. Running `multi-agent-mux-stop` will detect "tmux already dead, just update YAML" and proceed.
|
||||
- **Don't delete the `claude_session_id_own: null` placeholder** — when the user creates a fresh session with `multi-agent-mux-create` and never sent a message, the entry has `claude_session_id_own: null`. Stopping must preserve that field.
|
||||
- **Monitor skill may still be tracking** — if `multi-agent-mux-monitor` is running a heartbeat loop, stopping a session while it watches will trigger its `tmux ls != yaml` reconciliation. That's expected — let the monitor run, it will mark the entry as `terminated` on its own.
|
||||
|
||||
## Verification
|
||||
|
||||
@@ -133,4 +133,4 @@ print(f' preserved: pane.pid={s[\"pane\"][\"pid\"]}, cmd={s[\"pane\"][\"cmd\"]}
|
||||
|
||||
- **Just detaching** → `tmux detach` (Ctrl-B d) or just close the terminal. The tmux session keeps running.
|
||||
- **Stopping the agent inside but keeping tmux** → send `Ctrl-C` or `/exit` (claude) / `Ctrl-D` (agy) via `tmux send-keys`. The tmux session stays but the agent process is gone.
|
||||
- **Replacing an existing session with a new one** → `tmux-agent-orchestrate-stop` first, then `tmux-agent-orchestrate-create`.
|
||||
- **Replacing an existing session with a new one** → `multi-agent-mux-stop` first, then `multi-agent-mux-create`.
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# stop_session.sh — tmux-agent-orchestrate-stop 의 부속 스크립트
|
||||
# stop_session.sh — multi-agent-mux-stop 의 부속 스크립트
|
||||
# Usage:
|
||||
# bash stop_session.sh --session <name> [--agent claude|agy] \
|
||||
# [--mode soft|hard] [--purge-conversation] [--yes]
|
||||
@@ -139,7 +139,7 @@ fi
|
||||
if [ "$PURGE" = "1" ] && [ "$YES" != "1" ]; then
|
||||
echo "DANGER: --purge-conversation will DELETE this workspace's on-disk conversation."
|
||||
echo " workspace: ${TARGET_CWD:-<unknown>}"
|
||||
echo " This means: no future tmux-agent-orchestrate-resume for this session."
|
||||
echo " This means: no future multi-agent-mux-resume for this session."
|
||||
echo " Re-run with --yes to confirm."
|
||||
exit 3
|
||||
fi
|
||||
@@ -337,5 +337,5 @@ echo " captured: ${CAPTURED_UUID:-<none>}"
|
||||
echo " purge: $PURGE${PURGE_UUID:+ (uuid $PURGE_UUID)}"
|
||||
echo " time: $NOW_ISO"
|
||||
echo
|
||||
echo "Recovery: tmux-agent-orchestrate-create + tmux-agent-orchestrate-resume 로 동일 컨텍스트 복원 가능"
|
||||
echo "Recovery: multi-agent-mux-create + multi-agent-mux-resume 로 동일 컨텍스트 복원 가능"
|
||||
echo " (단 --purge-conversation 사용 시 복원 불가)"
|
||||
@@ -1,11 +0,0 @@
|
||||
# tmux-agent-orchestrate-delegate-job 스킬
|
||||
|
||||
작업(Job)을 자율 에이전트(claude-code/codex/opencode/human)에게 위임하고 MQTT
|
||||
이벤트 채널로 비동기 관찰하는 Hermes 스킬. **시작점은 [`SKILL.md`](./SKILL.md).**
|
||||
|
||||
- 프로토콜/스키마: [`job-protocol.md`](./job-protocol.md)
|
||||
- 브로커 PoC→운영 전환: [`mqtt-broker-setup.md`](./mqtt-broker-setup.md)
|
||||
- 레지스트리 포맷/동시성: [`registry.md`](./registry.md)
|
||||
- 참조 구현: [`tmux-agent-orchestrate-delegate-job`](./tmux-agent-orchestrate-delegate-job) (bash wrapper), [`scripts/publish_event.py`](./scripts/publish_event.py), [`scripts/job_subscriber.py`](./scripts/job_subscriber.py), [`scripts/registry.py`](./scripts/registry.py), [`scripts/mqtt_common.py`](./scripts/mqtt_common.py)
|
||||
- 영구 감사 로그: `.mam/delegate_job_logs/<job_id>/` (`meta.json`·`events.ndjson`·`status.json`)
|
||||
— `tmux-agent-orchestrate-delegate-job logs <id>` 또는 `tmux-agent-orchestrate-delegate-job logs --list`로 조회 (SKILL.md "Audit Logs" 참조)
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# .env.example — committable template for the tmux-agent-orchestrate-* skills
|
||||
# .env.example — committable template for the multi-agent-mux-* skills
|
||||
#
|
||||
# This file is tracked in git and contains NO secrets. To get a working local
|
||||
# config, copy it to `.env` (which is git-ignored) and edit as needed:
|
||||
@@ -24,8 +24,8 @@
|
||||
# AGENT_SESSIONS_YAML=/path/to/workspace/.mam/agent-sessions.yaml
|
||||
|
||||
# Where the monitor (reconcile.sh) keeps its drift-state cache.
|
||||
#default: <workspace>/.cache/tmux-agent-orchestrate-monitor
|
||||
# AGENT_SESSIONS_STATE_DIR=/path/to/workspace/.cache/tmux-agent-orchestrate-monitor
|
||||
#default: <workspace>/.cache/multi-agent-mux-monitor
|
||||
# AGENT_SESSIONS_STATE_DIR=/path/to/workspace/.cache/multi-agent-mux-monitor
|
||||
|
||||
# Root directory that holds Claude Code per-project conversation logs (*.jsonl).
|
||||
#default: $HOME/.claude/projects
|
||||
|
||||
+2
-2
@@ -19,5 +19,5 @@ __pycache__/
|
||||
!.env.example
|
||||
|
||||
# 빌드/배포 HTML 산출물
|
||||
.agents/skills/tmux-agent-orchestrate-delegate-job/USER_MANUAL.html
|
||||
.agents/skills/tmux-agent-orchestrate-delegate-job/mqtt-broker-setup.html
|
||||
.agents/skills/multi-agent-mux-delegate-job/USER_MANUAL.html
|
||||
.agents/skills/multi-agent-mux-delegate-job/mqtt-broker-setup.html
|
||||
+12
-12
@@ -12,12 +12,12 @@
|
||||
|
||||
* `.agents/skills/`: 멀티 에이전트 구동 및 비동기 잡 처리를 수행하는 셸 스크립트 모음
|
||||
* `lib.sh`: 오케스트레이션의 핵심 셸 함수 및 가상환경(venv) 자동 연동 라이브러리
|
||||
* `tmux-agent-orchestrate-create/`: 격리된 tmux 에이전트 세션을 시작하는 스크립트
|
||||
* `tmux-agent-orchestrate-stop/`: 세션을 정상적으로 중지하고 상태를 업데이트하는 스크립트
|
||||
* `tmux-agent-orchestrate-resume/`: 중지된 에이전트 세션을 이전 대화 상태 그대로 복원하는 스크립트
|
||||
* `tmux-agent-orchestrate-status/`: 전체 에이전트 세션의 현재 구동 상태를 조회하는 스크립트
|
||||
* `tmux-agent-orchestrate-monitor/`: tmux 상태와 레지스트리 상태를 동기화하는 모니터 스크립트
|
||||
* `tmux-agent-orchestrate-delegate-job/`: 비동기 잡 분할 실행 모듈
|
||||
* `multi-agent-mux-create/`: 격리된 tmux 에이전트 세션을 시작하는 스크립트
|
||||
* `multi-agent-mux-stop/`: 세션을 정상적으로 중지하고 상태를 업데이트하는 스크립트
|
||||
* `multi-agent-mux-resume/`: 중지된 에이전트 세션을 이전 대화 상태 그대로 복원하는 스크립트
|
||||
* `multi-agent-mux-status/`: 전체 에이전트 세션의 현재 구동 상태를 조회하는 스크립트
|
||||
* `multi-agent-mux-monitor/`: tmux 상태와 레지스트리 상태를 동기화하는 모니터 스크립트
|
||||
* `multi-agent-mux-delegate-job/`: 비동기 잡 분할 실행 모듈
|
||||
* `requirements.txt`: Python 의존성 목록 (paho-mqtt, pyyaml)
|
||||
* `scripts/`: 핵심 비즈니스 로직을 구동하는 Python 스크립트 디렉터리
|
||||
* `registry.py`: 잡의 등록, 클레임 및 원자적 파일 락 제어 (CLI 지원)
|
||||
@@ -80,11 +80,11 @@ source .venv/bin/activate
|
||||
```
|
||||
|
||||
### 단계 3.2: 의존성 패키지 설치
|
||||
`tmux-agent-orchestrate-delegate-job` 디렉터리에 기재된 `requirements.txt` 의존성 목록을 가상환경에 설치합니다.
|
||||
`multi-agent-mux-delegate-job` 디렉터리에 기재된 `requirements.txt` 의존성 목록을 가상환경에 설치합니다.
|
||||
|
||||
```bash
|
||||
# 의존성 패키지(pyyaml, paho-mqtt 등) 설치
|
||||
pip install -r .agents/skills/tmux-agent-orchestrate-delegate-job/requirements.txt
|
||||
pip install -r .agents/skills/multi-agent-mux-delegate-job/requirements.txt
|
||||
```
|
||||
|
||||
---
|
||||
@@ -122,7 +122,7 @@ Python 스크립트 및 venv 라이브러리가 올바르게 로드되는지 확
|
||||
|
||||
```bash
|
||||
# 가상환경(.venv) 파이썬 인터프리터를 사용하여 실행
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py list
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py list
|
||||
```
|
||||
* **출력 기대 결과**: 에러 메시지 없이 빈 JSON 배열 `[]` 또는 현재 등록된 pending/running 잡 목록이 성공적으로 출력되어야 합니다.
|
||||
|
||||
@@ -131,20 +131,20 @@ Python 스크립트 및 venv 라이브러리가 올바르게 로드되는지 확
|
||||
|
||||
```bash
|
||||
# 1. 테스트용 임시 잡 등록 및 발급된 8자리 Hex 잡 ID 획득
|
||||
JID=$(.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py register \
|
||||
JID=$(.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py register \
|
||||
--agent "test-agent" \
|
||||
--prompt "Bootstrap check command" \
|
||||
--timeout 120)
|
||||
echo "Generated Job ID: $JID"
|
||||
|
||||
# 2. 획득한 잡 ID에 대해 백그라운드 이벤트 구독기(Subscriber) 구동
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/job_subscriber.py --job "$JID" &
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/job_subscriber.py --job "$JID" &
|
||||
|
||||
# 3. 구독자의 MQTT Broker 소켓 연결 및 수신부 초기화 완료를 보장하기 위해 2초 대기
|
||||
sleep 2
|
||||
|
||||
# 4. 테스트 시작 이벤트 발행 (Subscribe-before-Publish 원칙 준수)
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/publish_event.py \
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/publish_event.py \
|
||||
--job "$JID" \
|
||||
--event started \
|
||||
--detail "Bootstrap MQTT verification connection check"
|
||||
|
||||
+12
-12
@@ -12,12 +12,12 @@ Before cloning this project into a new environment, you must first understand th
|
||||
|
||||
* `.agents/skills/`: A collection of shell scripts that execute multi-agent coordination and asynchronous job processing.
|
||||
* `lib.sh`: The core orchestration shell functions and virtual environment (venv) auto-loading library.
|
||||
* `tmux-agent-orchestrate-create/`: Script to launch isolated tmux agent sessions.
|
||||
* `tmux-agent-orchestrate-stop/`: Script to gracefully stop agent sessions and update states.
|
||||
* `tmux-agent-orchestrate-resume/`: Script to restore stopped agent sessions back to their previous conversation state.
|
||||
* `tmux-agent-orchestrate-status/`: Script to query the current running state of all agent sessions.
|
||||
* `tmux-agent-orchestrate-monitor/`: Monitor script to sync tmux states with the registry.
|
||||
* `tmux-agent-orchestrate-delegate-job/`: Asynchronous job splitting and delegation module.
|
||||
* `multi-agent-mux-create/`: Script to launch isolated tmux agent sessions.
|
||||
* `multi-agent-mux-stop/`: Script to gracefully stop agent sessions and update states.
|
||||
* `multi-agent-mux-resume/`: Script to restore stopped agent sessions back to their previous conversation state.
|
||||
* `multi-agent-mux-status/`: Script to query the current running state of all agent sessions.
|
||||
* `multi-agent-mux-monitor/`: Monitor script to sync tmux states with the registry.
|
||||
* `multi-agent-mux-delegate-job/`: Asynchronous job splitting and delegation module.
|
||||
* `requirements.txt`: Python dependency list (`paho-mqtt`, `pyyaml`).
|
||||
* `scripts/`: Python scripts running the core business logic.
|
||||
* `registry.py`: Job registration, claiming, and atomic file lock control (CLI supported).
|
||||
@@ -80,11 +80,11 @@ source .venv/bin/activate
|
||||
```
|
||||
|
||||
### Step 3.2: Install Dependency Packages
|
||||
Install the required packages listed in `requirements.txt` under `tmux-agent-orchestrate-delegate-job`:
|
||||
Install the required packages listed in `requirements.txt` under `multi-agent-mux-delegate-job`:
|
||||
|
||||
```bash
|
||||
# Install dependencies (pyyaml, paho-mqtt, etc.)
|
||||
pip install -r .agents/skills/tmux-agent-orchestrate-delegate-job/requirements.txt
|
||||
pip install -r .agents/skills/multi-agent-mux-delegate-job/requirements.txt
|
||||
```
|
||||
|
||||
---
|
||||
@@ -122,7 +122,7 @@ Verify that the Python scripts and virtual environment libraries load correctly
|
||||
|
||||
```bash
|
||||
# Run using the python interpreter in the virtual environment
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py list
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py list
|
||||
```
|
||||
* **Expected Output**: The command should exit successfully and print an empty JSON array `[]` (or a list of pending/running jobs if any exist) without any python traceback errors.
|
||||
|
||||
@@ -131,20 +131,20 @@ Test the end-to-end communication through the broker to verify that events are p
|
||||
|
||||
```bash
|
||||
# 1. Register a temporary test job and capture its 8-character Hex Job ID
|
||||
JID=$(.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py register \
|
||||
JID=$(.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py register \
|
||||
--agent "test-agent" \
|
||||
--prompt "Bootstrap check command" \
|
||||
--timeout 120)
|
||||
echo "Generated Job ID: $JID"
|
||||
|
||||
# 2. Run the background event subscriber (Subscriber) for this Job ID
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/job_subscriber.py --job "$JID" &
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/job_subscriber.py --job "$JID" &
|
||||
|
||||
# 3. Wait 2 seconds to allow the Subscriber to establish its MQTT socket connection
|
||||
sleep 2
|
||||
|
||||
# 4. Publish a start event (adhering to the Subscribe-before-Publish rule)
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/publish_event.py \
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/publish_event.py \
|
||||
--job "$JID" \
|
||||
--event started \
|
||||
--detail "Bootstrap MQTT verification connection check"
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
# Messaging System Technical Analysis & Architecture Report
|
||||
|
||||
This report provides a comprehensive, deep-dive analysis of the messaging system implemented in the `tmux-agent-orchestrate-delegate-job` skill. It covers the MQTT broker architecture, event protocols, job lifecycles, codebase internals, cross-system integration, and a list of known limitations along with production recommendations.
|
||||
This report provides a comprehensive, deep-dive analysis of the messaging system implemented in the `multi-agent-mux-delegate-job` skill. It covers the MQTT broker architecture, event protocols, job lifecycles, codebase internals, cross-system integration, and a list of known limitations along with production recommendations.
|
||||
|
||||
---
|
||||
|
||||
@@ -183,7 +183,7 @@ stateDiagram-v2
|
||||
### 3.1 Step-by-Step Lifecycle Phase Details
|
||||
|
||||
#### Phase 1: Registration (`register`)
|
||||
* **Trigger**: A delegator triggers `registry.py register` (or the `tmux-agent-orchestrate-delegate-job submit` command).
|
||||
* **Trigger**: A delegator triggers `registry.py register` (or the `multi-agent-mux-delegate-job submit` command).
|
||||
* **Registry State**: Flips from non-existent to `pending` inside `.mam/jobs/<job_id>.json`. A `last_seq` counter is initialized to `0`.
|
||||
* **Locking**: Exclusive fcntl file lock acquired over `.lock` during write.
|
||||
* **Durable Audit Log**: Writes `<logs>/<job_id>/meta.json`, sets status to `pending` in `status.json`, and appends a `registered` event line to `events.ndjson`.
|
||||
@@ -272,7 +272,7 @@ The delegated messaging system functions as a critical control backplane, bindin
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
User["User/Cron Client"] -->|submit| Wrap["tmux-agent-orchestrate-delegate-job (Bash)"]
|
||||
User["User/Cron Client"] -->|submit| Wrap["multi-agent-mux-delegate-job (Bash)"]
|
||||
Wrap -->|registers| Reg["registry.py (Live Registry)"]
|
||||
Wrap -->|spawns background| Sub["job_subscriber.py"]
|
||||
Wrap -->|spawns tmux pane| Tmux["tmux Session (Agent Pane)"]
|
||||
@@ -285,8 +285,8 @@ graph LR
|
||||
Mon -->|updates| Inv["agent-sessions.yaml <br> (lib.sh::atomic_dump_yaml)"]
|
||||
```
|
||||
|
||||
### 5.1 Orchestration Wrappers (`tmux-agent-orchestrate-*`)
|
||||
1. **`tmux-agent-orchestrate-delegate-job (submit)`**:
|
||||
### 5.1 Orchestration Wrappers (`multi-agent-mux-*`)
|
||||
1. **`multi-agent-mux-delegate-job (submit)`**:
|
||||
* Registers a job, spawns `job_subscriber.py` to capture standard output streams to `.mam/jobs/<job_id>.subscriber.out`, and sleeps for `1` second.
|
||||
* Boots the agent pane in tmux:
|
||||
```bash
|
||||
@@ -295,10 +295,10 @@ graph LR
|
||||
```
|
||||
* Pre-seeds agent instruction headers via stdin to enforce that the agent runs `publish_event.py` for its transitions.
|
||||
* Blocks on `wait $sub_pid`, and finally prints the audit log directory.
|
||||
2. **`tmux-agent-orchestrate-monitor` (`reconcile.sh` & `watchdog.sh`)**:
|
||||
2. **`multi-agent-mux-monitor` (`reconcile.sh` & `watchdog.sh`)**:
|
||||
* **Watchdog Integration**: Starts a subscriber monitoring loop (`watchdog.sh`) to detect orphaned agent panes or locked workspaces.
|
||||
* **Reconciliation loop**: Subscribes to the global job topic. On terminal events, it invokes `lib.sh::atomic_dump_yaml` to sync status drifts (e.g. setting tmux sessions to `terminated` in `agent-sessions.yaml` once the agent exits).
|
||||
3. **`tmux-agent-orchestrate-create / stop / resume`**:
|
||||
3. **`multi-agent-mux-create / stop / resume`**:
|
||||
* Integrates the job life status into session metadata updates, ensuring standard tmux cleanup triggers state updates in the registry and audit logs.
|
||||
|
||||
---
|
||||
@@ -337,7 +337,7 @@ graph LR
|
||||
This project manages **two distinct state domains** that are often confused:
|
||||
|
||||
### Session States (YAML — `.mam/agent-sessions.yaml`)
|
||||
Managed by `.agents/skills/lib.sh` and the 6 `tmux-agent-orchestrate-*` skills.
|
||||
Managed by `.agents/skills/lib.sh` and the 6 `multi-agent-mux-*` skills.
|
||||
Valid values (see `lib.sh` valid-status set):
|
||||
|
||||
| State | Meaning | Set by |
|
||||
@@ -348,7 +348,7 @@ Valid values (see `lib.sh` valid-status set):
|
||||
| `archived` | soft-stopped via `--mode soft`; tmux left alive, YAML-only update | `stop` (soft mode) |
|
||||
|
||||
### Job States (Registry — `.mam/jobs/<id>.json`)
|
||||
Managed by `.agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py`.
|
||||
Managed by `.agents/skills/multi-agent-mux-delegate-job/scripts/registry.py`.
|
||||
Valid values:
|
||||
|
||||
| State | Meaning | Set by |
|
||||
|
||||
+14
-14
@@ -20,12 +20,12 @@ Tmux와 MQTT 브로커를 기반으로 구축된 고신뢰성 **다중 에이전
|
||||
|
||||
모든 오케스트레이션 스킬들은 `.agents/skills/` 디렉터리 하위에 정의되어 있습니다:
|
||||
|
||||
* **`tmux-agent-orchestrate-create`**: 격리된 tmux 세션을 생성하고 특정 에이전트 CLI를 백그라운드에서 구동합니다. 프로세스 PID 캡처, 메타데이터 레지스트리 업데이트 및 에이전트 인증 검증을 처리합니다.
|
||||
* **`tmux-agent-orchestrate-stop`**: 에이전트 CLI 세션을 정상 종료 키 입력(`/exit` 또는 `Exit`)을 통해 안전하게 닫고, 격리된 대화 히스토리 및 데이터베이스 로그를 삭제(purge)하는 클린업 작업을 수행합니다.
|
||||
* **`tmux-agent-orchestrate-resume`**: 디스크 또는 캐시에서 특정 워크스페이스의 세션 UUID를 조회하여 기존 대화 상태(`claude -r <uuid>` 또는 `hermes --resume <uuid>`) 그대로 세션을 복구하고 재개합니다.
|
||||
* **`tmux-agent-orchestrate-status`**: 활성화된 모든 세션의 실시간 작동 상태를 쿼리하여 PID 정합성, 실행 명령 포맷, tmux 실제 상태와 데이터베이스 간의 동기화 드리프트를 감지합니다.
|
||||
* **`tmux-agent-orchestrate-monitor`**: 백그라운드에서 Kanban Reconcile 프로세스로 실행되어, 실시간 tmux 세션 변화를 모니터링하고 `.mam/agent-sessions.yaml` 메타데이터 파일에 상태를 동기화합니다.
|
||||
* **`tmux-agent-orchestrate-delegate-job`**: 태스크를 비동기식 독립 잡으로 위임 및 관리하는 핵심 모듈입니다:
|
||||
* **`multi-agent-mux-create`**: 격리된 tmux 세션을 생성하고 특정 에이전트 CLI를 백그라운드에서 구동합니다. 프로세스 PID 캡처, 메타데이터 레지스트리 업데이트 및 에이전트 인증 검증을 처리합니다.
|
||||
* **`multi-agent-mux-stop`**: 에이전트 CLI 세션을 정상 종료 키 입력(`/exit` 또는 `Exit`)을 통해 안전하게 닫고, 격리된 대화 히스토리 및 데이터베이스 로그를 삭제(purge)하는 클린업 작업을 수행합니다.
|
||||
* **`multi-agent-mux-resume`**: 디스크 또는 캐시에서 특정 워크스페이스의 세션 UUID를 조회하여 기존 대화 상태(`claude -r <uuid>` 또는 `hermes --resume <uuid>`) 그대로 세션을 복구하고 재개합니다.
|
||||
* **`multi-agent-mux-status`**: 활성화된 모든 세션의 실시간 작동 상태를 쿼리하여 PID 정합성, 실행 명령 포맷, tmux 실제 상태와 데이터베이스 간의 동기화 드리프트를 감지합니다.
|
||||
* **`multi-agent-mux-monitor`**: 백그라운드에서 Kanban Reconcile 프로세스로 실행되어, 실시간 tmux 세션 변화를 모니터링하고 `.mam/agent-sessions.yaml` 메타데이터 파일에 상태를 동기화합니다.
|
||||
* **`multi-agent-mux-delegate-job`**: 태스크를 비동기식 독립 잡으로 위임 및 관리하는 핵심 모듈입니다:
|
||||
* `registry.py`: 파일 락(`fcntl`)을 활용해 경쟁 조건 없이 잡을 원자적으로 등록 및 점유(claim)합니다.
|
||||
* `job_subscriber.py`: MQTT 백플레인 채널을 구독하여 실시간 상태 이벤트를 수집하고 이를 감사 로그(audit trail)에 기록합니다.
|
||||
* `publish_event.py`: 실행 상태 전환 및 세부 에러 내용을 워크스페이스 스크립트에서 백플레인으로 발행합니다.
|
||||
@@ -83,12 +83,12 @@ sequenceDiagram
|
||||
├── .agents/
|
||||
│ └── skills/ # 코어 오케스트레이션 셸 스크립트 및 라이브러리
|
||||
│ ├── lib.sh # 공통 오케스트레이션 셸 함수 라이브러리
|
||||
│ ├── tmux-agent-orchestrate-create/
|
||||
│ ├── tmux-agent-orchestrate-stop/
|
||||
│ ├── tmux-agent-orchestrate-resume/
|
||||
│ ├── tmux-agent-orchestrate-status/
|
||||
│ ├── tmux-agent-orchestrate-monitor/
|
||||
│ └── tmux-agent-orchestrate-delegate-job/
|
||||
│ ├── multi-agent-mux-create/
|
||||
│ ├── multi-agent-mux-stop/
|
||||
│ ├── multi-agent-mux-resume/
|
||||
│ ├── multi-agent-mux-status/
|
||||
│ ├── multi-agent-mux-monitor/
|
||||
│ └── multi-agent-mux-delegate-job/
|
||||
│ ├── requirements.txt # 파이썬 의존성 패키지 선언
|
||||
│ └── scripts/ # 파이썬 기반 백플레인 구현체
|
||||
├── .mam/ # Multi-Agent Mux 메타데이터 (git-ignored)
|
||||
@@ -119,11 +119,11 @@ sequenceDiagram
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r .agents/skills/tmux-agent-orchestrate-delegate-job/requirements.txt
|
||||
pip install -r .agents/skills/multi-agent-mux-delegate-job/requirements.txt
|
||||
```
|
||||
3. **레지스트리 및 환경 작동 자가 검증:**
|
||||
```bash
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py list
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -20,12 +20,12 @@ Modern agentic workflows often suffer from session timeout, lack of process isol
|
||||
|
||||
All orchestration functionalities are structured under the `.agents/skills/` directory:
|
||||
|
||||
* **`tmux-agent-orchestrate-create`**: Spawns isolated tmux sessions running specified agent CLI wrappers. It captures system processes, updates metadata registries, and enforces authentication checks.
|
||||
* **`tmux-agent-orchestrate-stop`**: Gracefully terminates agent CLI sessions (using key macros like `/exit` or `Exit`) and handles disk purge operations (removing conversation JSON files and SQLite logs for deleted workspaces).
|
||||
* **`tmux-agent-orchestrate-resume`**: Restores stopped sessions by resolving workspace UUIDs from disk or cache, and invokes the underlying agent using session-resume parameters (e.g., `claude -r <uuid>` or `hermes --resume <uuid>`).
|
||||
* **`tmux-agent-orchestrate-status`**: Queries the running states of all active sessions, detecting PID mismatches, command signatures, and drifts between actual tmux instances and the registry database.
|
||||
* **`tmux-agent-orchestrate-monitor`**: A long-running Kanban reconcile worker that dynamically monitors tmux sessions and synchronizes states to `.mam/agent-sessions.yaml`.
|
||||
* **`tmux-agent-orchestrate-delegate-job`**: The core asynchronous task distribution module containing:
|
||||
* **`multi-agent-mux-create`**: Spawns isolated tmux sessions running specified agent CLI wrappers. It captures system processes, updates metadata registries, and enforces authentication checks.
|
||||
* **`multi-agent-mux-stop`**: Gracefully terminates agent CLI sessions (using key macros like `/exit` or `Exit`) and handles disk purge operations (removing conversation JSON files and SQLite logs for deleted workspaces).
|
||||
* **`multi-agent-mux-resume`**: Restores stopped sessions by resolving workspace UUIDs from disk or cache, and invokes the underlying agent using session-resume parameters (e.g., `claude -r <uuid>` or `hermes --resume <uuid>`).
|
||||
* **`multi-agent-mux-status`**: Queries the running states of all active sessions, detecting PID mismatches, command signatures, and drifts between actual tmux instances and the registry database.
|
||||
* **`multi-agent-mux-monitor`**: A long-running Kanban reconcile worker that dynamically monitors tmux sessions and synchronizes states to `.mam/agent-sessions.yaml`.
|
||||
* **`multi-agent-mux-delegate-job`**: The core asynchronous task distribution module containing:
|
||||
* `registry.py`: Atomically registers and claims jobs using file advisory locks (`fcntl`).
|
||||
* `job_subscriber.py`: Connects to the MQTT backplane, captures live events, and appends them to audit trails.
|
||||
* `publish_event.py`: Emits execution status transitions and error details from workspace scripts.
|
||||
@@ -83,12 +83,12 @@ To ensure communication integrity across public MQTT brokers, the backplane inte
|
||||
├── .agents/
|
||||
│ └── skills/ # Core orchestration shell wrappers & libraries
|
||||
│ ├── lib.sh # Shared orchestration library
|
||||
│ ├── tmux-agent-orchestrate-create/
|
||||
│ ├── tmux-agent-orchestrate-stop/
|
||||
│ ├── tmux-agent-orchestrate-resume/
|
||||
│ ├── tmux-agent-orchestrate-status/
|
||||
│ ├── tmux-agent-orchestrate-monitor/
|
||||
│ └── tmux-agent-orchestrate-delegate-job/
|
||||
│ ├── multi-agent-mux-create/
|
||||
│ ├── multi-agent-mux-stop/
|
||||
│ ├── multi-agent-mux-resume/
|
||||
│ ├── multi-agent-mux-status/
|
||||
│ ├── multi-agent-mux-monitor/
|
||||
│ └── multi-agent-mux-delegate-job/
|
||||
│ ├── requirements.txt # Python dependency declaration
|
||||
│ └── scripts/ # Core backplane implementation (Python)
|
||||
├── .mam/ # Multi-Agent Mux metadata (git-ignored)
|
||||
@@ -117,11 +117,11 @@ For detailed setup instructions, please consult the **[BOOTSTRAP.md](./BOOTSTRAP
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r .agents/skills/tmux-agent-orchestrate-delegate-job/requirements.txt
|
||||
pip install -r .agents/skills/multi-agent-mux-delegate-job/requirements.txt
|
||||
```
|
||||
3. **Run Registry Diagnostics:**
|
||||
```bash
|
||||
.venv/bin/python3 .agents/skills/tmux-agent-orchestrate-delegate-job/scripts/registry.py list
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user