diff --git a/skills/lib.sh b/skills/lib.sh index caf7d82..9e13808 100644 --- a/skills/lib.sh +++ b/skills/lib.sh @@ -14,7 +14,9 @@ # HARD RULE: the agent-sessions.yaml file is only ever written through # atomic_dump_yaml. Never `open(yaml_path, 'w')` anywhere else. -AGENT_SESSIONS_YAML="${AGENT_SESSIONS_YAML:-$HOME/PuKi/lab/agent_sessions/agent-sessions.yaml}" +SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_ROOT="$(cd "$SKILL_DIR/.." && pwd)" +AGENT_SESSIONS_YAML="${AGENT_SESSIONS_YAML:-$WORKSPACE_ROOT/.hermes/agent-sessions.yaml}" # --------------------------------------------------------------------------- # Tmux Server Isolation support @@ -126,7 +128,8 @@ PYEOF # '_' -> '-', lowercased, joined with '-' # name = "-creator-" # -# /home/godopu16/PuKi/lab/landing_page/refer_landing_page + claude +# Workspace root 기준 상대 해석. 예: +# $WORKSPACE_ROOT/landing_page/refer_landing_page + claude # -> landing-page-refer-landing-page-creator-claude # # Decision (REVIEW P0-A): the actual workspace basename (refer_landing_page) diff --git a/skills/tmux-agent-orchestrate-create/SKILL.md b/skills/tmux-agent-orchestrate-create/SKILL.md index d94f914..911864f 100644 --- a/skills/tmux-agent-orchestrate-create/SKILL.md +++ b/skills/tmux-agent-orchestrate-create/SKILL.md @@ -1,6 +1,6 @@ --- name: tmux-agent-orchestrate-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 ~/PuKi/lab/agent_sessions/agent-sessions.yaml. Use when you want to start a fresh agent (no prior UUID) for a new project workspace." +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 .hermes/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 license: MIT @@ -16,7 +16,7 @@ metadata: # Multi-Agent Create — Start a Fresh Agent in a tmux Session > **Companion skills**: `tmux-agent-orchestrate-resume` (resume an existing UUID), `tmux-agent-orchestrate-delete` (terminate), `tmux-agent-orchestrate-monitor` (live status). -> **Single source of truth**: `~/PuKi/lab/agent_sessions/agent-sessions.yaml` (this skill writes to it; never read it ad-hoc — go through this skill). +> **Single source of truth**: `./.hermes/agent-sessions.yaml` (this skill writes to it; never read it ad-hoc — go through this skill). ## What this skill does @@ -26,7 +26,7 @@ For all agents: the tmux session name is produced by **`lib.sh::derive_session_n > slug = the **two trailing path components** of the absolute workspace, `_`→`-`, lowercased, joined with `-`; name = `-creator-`. -So `/home/godopu16/PuKi/lab/landing_page/refer_landing_page` + `claude` → `landing-page-refer-landing-page-creator-claude`. The workspace basename (`refer_landing_page`) **is** included; the hand-written historical entry that dropped it (`lab-landing-page-creator-claude`) was the bug, not the convention. +So `$WORKSPACE_ROOT/landing_page/refer_landing_page` + `claude` → `landing-page-refer-landing-page-creator-claude`. The workspace basename (`refer_landing_page`) **is** included; the hand-written historical entry that dropped it (`lab-landing-page-creator-claude`) was the bug, not the convention. ## Pre-flight checks @@ -58,7 +58,7 @@ If any check fails → `kanban_block(reason="...")` (worker path) or report to u - never re-derive this by hand — source lib.sh and call the function - **wrapper script** (claude only): `~/.local/bin/-creator-claude` - contents: tmux new-session with `claude` inside, auto-handles trust/bypass dialogs - - see `~/PuKi/lab/landing_page/refer_landing_page/agent_sessions.md` for the canonical wrapper template + - see `/agent_sessions.md` for the canonical wrapper template ## Tmux Server Isolation (격리 서버) @@ -98,7 +98,7 @@ tmc ls # Lists only your multi-agent sessions ```bash WORKSPACE=/path/to/project AGENT=claude # or agy -source ~/PuKi/lab/agent_sessions/skills/lib.sh +source skills/lib.sh SESSION_NAME="$(derive_session_name "$WORKSPACE" "$AGENT")" # 1. If session already alive, fail fast @@ -135,7 +135,7 @@ TMUX_EPOCH=$(tmux list-sessions -F '#{session_created}' -t "$SESSION_NAME" 2>/de ## Registering the session in agent-sessions.yaml -After spawn, append a new `tmux_sessions[]` entry to `~/PuKi/lab/agent_sessions/agent-sessions.yaml`: +After spawn, append a new `tmux_sessions[]` entry to `.hermes/agent-sessions.yaml`: ```yaml - name: @@ -170,7 +170,7 @@ After spawn, append a new `tmux_sessions[]` entry to `~/PuKi/lab/agent_sessions/ Use the `agent-sessions-yaml-edit` script in `scripts/` to safely append (preserves comments + format): ```bash -bash ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-create/scripts/create_session.sh \ +bash skills/tmux-agent-orchestrate-create/scripts/create_session.sh \ --workspace "$WORKSPACE" --agent "$AGENT" --session "$SESSION_NAME" ``` @@ -198,7 +198,7 @@ tmux list-panes -t "$SESSION_NAME" -F 'cmd=#{pane_current_command} cwd=#{pane_cu # 3. agent-sessions.yaml has the new entry python3 -c " import yaml -d = yaml.safe_load(open('$HOME/PuKi/lab/agent_sessions/agent-sessions.yaml')) +d = yaml.safe_load(open('.hermes/agent-sessions.yaml')) names = [s['name'] for s in d['tmux_sessions']] assert '$SESSION_NAME' in names, 'session not registered' print('OK:', names) diff --git a/skills/tmux-agent-orchestrate-create/scripts/create_session.sh b/skills/tmux-agent-orchestrate-create/scripts/create_session.sh index edc87df..eef4fd5 100755 --- a/skills/tmux-agent-orchestrate-create/scripts/create_session.sh +++ b/skills/tmux-agent-orchestrate-create/scripts/create_session.sh @@ -171,8 +171,8 @@ if [ -n "$SUBMIT_JOB_PROMPT" ]; then fi if [ ! -f "$AGENT_SESSIONS_YAML" ]; then - echo "ERROR: $AGENT_SESSIONS_YAML not found. Run init first." >&2 - exit 4 + mkdir -p "$(dirname "$AGENT_SESSIONS_YAML")" + echo "tmux_sessions: []" > "$AGENT_SESSIONS_YAML" fi # atomic_dump_yaml: flock + temp+rename + .bak + schema validate (P0-B). diff --git a/skills/tmux-agent-orchestrate-delete/SKILL.md b/skills/tmux-agent-orchestrate-delete/SKILL.md index 1b3e225..fb8bf5b 100644 --- a/skills/tmux-agent-orchestrate-delete/SKILL.md +++ b/skills/tmux-agent-orchestrate-delete/SKILL.md @@ -1,6 +1,6 @@ --- name: tmux-agent-orchestrate-delete -description: "Terminate an agent tmux session (claude, antigravity/agy) and update ~/PuKi/lab/agent_sessions/agent-sessions.yaml to mark it terminated with timestamp. Does NOT delete on-disk conversation artifacts (jsonl/db) — those are preserved for future resume. Use when ending a work session, switching to a different one, or cleaning up before a fresh start." +description: "Terminate an agent tmux session (claude, antigravity/agy) and update .hermes/agent-sessions.yaml to mark it terminated with timestamp. Does NOT delete on-disk conversation artifacts (jsonl/db) — those are preserved for future resume. Use when ending a work session, switching to a different one, or cleaning up before a fresh start." version: 1.0.0 author: godopu license: MIT @@ -17,7 +17,7 @@ metadata: > **Companion skills**: `tmux-agent-orchestrate-create` (start), `tmux-agent-orchestrate-resume` (re-attach), `tmux-agent-orchestrate-monitor` (live status). > **Tmux Isolation**: `delete` 명령은 YAML의 `tmux_server` 필드를 자동으로 파싱하여 해당 격리 서버의 세션을 안전하게 종료(kill)하므로, `TMUX_SERVER_NAME` 환경변수를 수동으로 지정할 필요가 없습니다. -> **Single source of truth**: `~/PuKi/lab/agent_sessions/agent-sessions.yaml`. +> **Single source of truth**: `./.hermes/agent-sessions.yaml`. ## What this skill does @@ -36,7 +36,7 @@ The user explicitly chooses: ```bash SESSION_NAME=-creator- # convention -AGENT_SESSIONS_YAML=~/PuKi/lab/agent_sessions/agent-sessions.yaml +AGENT_SESSIONS_YAML=.hermes/agent-sessions.yaml # 1) Session is registered? python3 -c " @@ -65,16 +65,16 @@ fi ```bash # 1. soft delete (YAML only — tmux left running) -bash ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-delete/scripts/delete_session.sh \ +bash skills/tmux-agent-orchestrate-delete/scripts/delete_session.sh \ --session "$SESSION_NAME" --mode soft # 2. hard delete (default — kill tmux + update YAML) -bash ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-delete/scripts/delete_session.sh \ +bash skills/tmux-agent-orchestrate-delete/scripts/delete_session.sh \ --session "$SESSION_NAME" --mode hard # 3. hard delete + clean up on-disk conversation (DANGEROUS) # — this prevents any future resume. Use only when user is certain. -bash ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-delete/scripts/delete_session.sh \ +bash skills/tmux-agent-orchestrate-delete/scripts/delete_session.sh \ --session "$SESSION_NAME" --mode hard --purge-conversation ``` diff --git a/skills/tmux-agent-orchestrate-monitor/SKILL.md b/skills/tmux-agent-orchestrate-monitor/SKILL.md index 0c16514..d2a0ec9 100644 --- a/skills/tmux-agent-orchestrate-monitor/SKILL.md +++ b/skills/tmux-agent-orchestrate-monitor/SKILL.md @@ -1,6 +1,6 @@ --- name: tmux-agent-orchestrate-monitor -description: "Run a long-lived Kanban worker that polls ~/PuKi/lab/agent_sessions/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." +description: "Run a long-lived Kanban worker that polls .hermes/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 license: MIT @@ -16,7 +16,7 @@ metadata: # Agent Sessions Monitor — Live Reconciliation via Kanban Worker > **Companion skills**: `tmux-agent-orchestrate-create` / `tmux-agent-orchestrate-resume` / `tmux-agent-orchestrate-delete` (mutators); this skill is the **observer**. -> **Single source of truth**: `~/PuKi/lab/agent_sessions/agent-sessions.yaml`. +> **Single source of truth**: `./.hermes/agent-sessions.yaml`. ## What this skill does @@ -68,7 +68,7 @@ hermes kanban create \ --body "$(cat <<'EOF' You are the agent-sessions monitor. Every 30 seconds, do: -1. Read ~/PuKi/lab/agent_sessions/agent-sessions.yaml +1. Read .hermes/agent-sessions.yaml 2. Run `tmux ls` and `tmux list-panes -F 'session=#{session_name} pid=#{pane_pid} cmd=#{pane_current_command} cwd=#{pane_current_path}'` 3. For each session in the YAML, check the corresponding tmux state 4. For each tmux session matching `*-creator-claude` or `*-creator-agy` that's not in the YAML, register it @@ -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 ~/PuKi/lab/agent_sessions/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 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. EOF )" ``` @@ -124,7 +124,7 @@ tmux: no session ``` tmux: session=lab-paper-pdf2md-creator-agy, pid=..., - cmd=agy, cwd=/home/godopu16/PuKi/lab/paper-pdf2md + cmd=agy, cwd=$WORKSPACE_ROOT/paper-pdf2md YAML: no such session → register as new entry: status=running, last_visible_status=auto-registered → comment: "lab-paper-pdf2md-creator-agy: tmux found but not in YAML. Auto-registered." @@ -169,7 +169,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 ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --emit-diff` +2. Bash: `bash skills/tmux-agent-orchestrate-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 @@ -200,7 +200,7 @@ If `$HERMES_KANBAN_TASK` card has any comment containing "stop" or "stop monitor ```bash # Run reconcile once and inspect output -bash ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --emit-diff --once \ +bash skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh --emit-diff --once \ | python3 -m json.tool ``` diff --git a/skills/tmux-agent-orchestrate-resume/SKILL.md b/skills/tmux-agent-orchestrate-resume/SKILL.md index 42c3bd2..673cc78 100644 --- a/skills/tmux-agent-orchestrate-resume/SKILL.md +++ b/skills/tmux-agent-orchestrate-resume/SKILL.md @@ -1,6 +1,6 @@ --- name: tmux-agent-orchestrate-resume -description: "Resume an existing agent (claude, antigravity/agy) conversation by UUID into a tmux session. Reads ~/PuKi/lab/agent_sessions/agent-sessions.yaml for the saved session/conversation id, spawns (or reuses) a tmux session of the matching name, and runs `claude -r ` or `agy --conversation ` 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." +description: "Resume an existing agent (claude, antigravity/agy) conversation by UUID into a tmux session. Reads .hermes/agent-sessions.yaml for the saved session/conversation id, spawns (or reuses) a tmux session of the matching name, and runs `claude -r ` or `agy --conversation ` 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 license: MIT @@ -16,8 +16,8 @@ metadata: # Multi-Agent Resume — Reattach to a Saved Conversation > **Companion skills**: `tmux-agent-orchestrate-create` (start a fresh agent), `tmux-agent-orchestrate-delete` (terminate), `tmux-agent-orchestrate-monitor` (live status). -> **Tmux Isolation**: `TMUX_SERVER_NAME` env var를 create에서 설정한 경우, 동일 서버에서 동작합니다. 자세한 격리 패턴은 [tmux-agent-orchestrate-create/SKILL.md](file:///home/godopu16/PuKi/laa/canary_projects/advanced_multi_agent/skills/tmux-agent-orchestrate-create/SKILL.md) 참조. -> **Single source of truth**: `~/PuKi/lab/agent_sessions/agent-sessions.yaml`. +> **Tmux Isolation**: `TMUX_SERVER_NAME` env var를 create에서 설정한 경우, 동일 서버에서 동작합니다. 자세한 격리 패턴은 [tmux-agent-orchestrate-create/SKILL.md](../tmux-agent-orchestrate-create/SKILL.md) 참조. +> **Single source of truth**: `./.hermes/agent-sessions.yaml`. ## What this skill does @@ -49,7 +49,7 @@ AGENT=claude # or agy SESSION_NAME=-creator- # same convention as tmux-agent-orchestrate-create # 1. Resolve the session id -UUID=$(bash ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-resume/scripts/resolve_session_id.sh \ +UUID=$(bash skills/tmux-agent-orchestrate-resume/scripts/resolve_session_id.sh \ --workspace "$WORKSPACE" --agent "$AGENT") if [ -z "$UUID" ]; then @@ -58,7 +58,7 @@ if [ -z "$UUID" ]; then fi # Resolve the isolated tmux server name -source ~/PuKi/lab/agent_sessions/skills/lib.sh +source skills/lib.sh export TMUX_SERVER_NAME="$(resolve_tmux_server "$SESSION_NAME")" # 2. If tmux is alive, attach. Done. @@ -88,7 +88,7 @@ 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 ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-resume/scripts/update_yaml_resumed.sh \ +bash skills/tmux-agent-orchestrate-resume/scripts/update_yaml_resumed.sh \ --session "$SESSION_NAME" --uuid "$UUID" # 5. Attach @@ -112,7 +112,7 @@ tmux list-panes -t "$SESSION_NAME" -F 'cmd=#{pane_current_command} cwd=#{pane_cu # 2. agent-sessions.yaml updated python3 -c " import yaml -d = yaml.safe_load(open('$HOME/PuKi/lab/agent_sessions/agent-sessions.yaml')) +d = yaml.safe_load(open('.hermes/agent-sessions.yaml')) s = [s for s in d['tmux_sessions'] if s['name'] == '$SESSION_NAME'][0] print(f' status: {s[\"status\"]}') print(f' pane.cmd_full: {s[\"pane\"][\"cmd_full\"]}') diff --git a/skills/tmux-agent-orchestrate-status/SKILL.md b/skills/tmux-agent-orchestrate-status/SKILL.md index 2e309b5..a56e699 100644 --- a/skills/tmux-agent-orchestrate-status/SKILL.md +++ b/skills/tmux-agent-orchestrate-status/SKILL.md @@ -17,7 +17,7 @@ metadata: > **Companion skills**: `tmux-agent-orchestrate-create` (start), `tmux-agent-orchestrate-resume` (re-attach), `tmux-agent-orchestrate-delete` (terminate), `tmux-agent-orchestrate-monitor` (live polling). > **Tmux Isolation**: `status` 명령은 YAML에 등록된 모든 세션의 격리 서버(`tmux_server` 필드)를 자동으로 조회하여 상태를 확인하므로, `TMUX_SERVER_NAME` 환경변수를 수동으로 지정하지 않아도 모든 격리 서버의 세션 상태를 통합 조회합니다. -> **Single source of truth**: `~/PuKi/lab/agent_sessions/agent-sessions.yaml`. +> **Single source of truth**: `./.hermes/agent-sessions.yaml`. ## What this skill does @@ -30,7 +30,7 @@ This is the "what's running right now?" answer — faster than dispatching `tmux ```bash command -v tmux command -v python3 -test -f ~/PuKi/lab/agent_sessions/agent-sessions.yaml +test -f .hermes/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.) @@ -38,7 +38,7 @@ If `agent-sessions.yaml` doesn't exist or is malformed → print clear error, ex ## Workflow ```bash -bash ~/PuKi/lab/agent_sessions/skills/tmux-agent-orchestrate-status/scripts/status.sh [--json] +bash skills/tmux-agent-orchestrate-status/scripts/status.sh [--json] ``` The script: