diff --git a/.agents/skills/multi-agent-mux-loop/SKILL.md b/.agents/skills/multi-agent-mux-loop/SKILL.md index bfa4546..b01f6ad 100644 --- a/.agents/skills/multi-agent-mux-loop/SKILL.md +++ b/.agents/skills/multi-agent-mux-loop/SKILL.md @@ -10,7 +10,7 @@ Run an autonomous planning-execution-review loop using multiple agents (Planner, Creator, Reviewers) in the workspace. It supports: - **Collaborative Planning** (`--plan` and `--plan-talk N`): Planner designs the solution, Creator challenges the plan for N turns to resolve edge cases, then implementation starts. -- **Existing Plan Execution** (default without `--plan`): Planner 에이전트에게 계획 작성을 위임하지 않고 기존에 승격된 계획서(`.agents/reports//report-final.md`)의 내용을 로드하여 작업자(Creator)의 판단하에 즉시 구현을 시작합니다. +- **Creator Self-Planning & Development** (default without `--plan`): Planner 에이전트에게 계획 작성을 위임하지 않고, 기존에 승격된 계획서가 있다면 이를 로드하여 코드를 구현하며, 계획서가 존재하지 않는 경우 작업자(Creator: developer/writer)가 스스로 구현 계획 및 설계 수립을 포함한 개발 전 과정을 직접 진행합니다. - **Targeted Peer-Review** (`--reviewer`): Runs custom-selected reviewer agents to verify code changes. - **Total Peer-Review** (`--all-reviewer`): Enforces a unanimous PASS verdict from all registered reviewer sessions. - **Self-Review** (default): Creator verifies its code changes autonomously without peer reviews. @@ -91,8 +91,12 @@ sequenceDiagram Dev->>Plan: send critiques (Discussion) Plan-->>Dev: update plan & reach consensus end - else Use Existing Plan (No --plan) - Loop->>Dev: notify task execution using existing plan + else Use Existing Plan or Creator Self-Plan (No --plan) + alt Existing Plan Found + Loop->>Dev: notify task execution using existing plan + else No Plan Found + Loop->>Dev: request Creator self-planning and code execution + end end Loop->>Dev: delegate code implementation @@ -110,7 +114,7 @@ sequenceDiagram else Self-Review (default) Loop->>Dev: notify self-evaluation Dev-->>Loop: verification complete - fi + end end alt --cleanup enabled @@ -122,8 +126,10 @@ sequenceDiagram ## Feedback Loop Cadence -1. **Planning Phase**: 사용자가 요구사항을 제시하면 Planner가 프로젝트 구조를 파악하고 `implementation_plan.md`/`task.md`로 로드맵을 제공합니다. 사용자가 승인하면 다음 단계로 이행합니다. -2. **Execution Phase**: Creator가 배정된 태스크의 코드를 수정합니다. 진행 중 예상치 못한 설계 변경 필요성이 감지되면 작업을 멈추고 Planner에게 계획 수정을 먼저 위임합니다. 구현 완료 후 DoD(타입 매핑, 공유 자원 사이드 이펙트 방지, 문서-코드 정합성)를 자체 검증한 뒤 단일 커밋을 작성합니다. +1. **Planning Phase**: + - **Collaborative Planning (`--plan`)**: Planner가 프로젝트 구조를 파악하고 `implementation_plan.md`/`task.md`로 로드맵을 제공하며, Creator와의 피드백 루프를 통해 정제됩니다. + - **Creator Self-Planning (No `--plan`)**: Planner의 개입 없이, 기존 계획서가 있다면 이를 기반으로 하고, 그렇지 않다면 Creator가 독자적으로 설계 및 태스크 단위를 구상한 후 구현에 착수합니다. +2. **Execution Phase**: Creator가 배정된 태스크의 코드를 수정합니다. `--plan` 모드 진행 중 예상치 못한 설계 변경 필요성이 감지되면 작업을 멈추고 Planner에게 계획 수정을 먼저 위임합니다. (Creator 자율 계획 모드에서는 Creator가 직접 설계를 변경하며 진행합니다.) 구현 완료 후 DoD(타입 매핑, 공유 자원 사이드 이펙트 방지, 문서-코드 정합성)를 자체 검증한 뒤 단일 커밋을 작성합니다. 3. **Review Phase**: Creator가 리뷰어 세션에 작업 완료 사실과 변경 범위(`git diff`)를 전달합니다. 리뷰어는 검증 후 리포트 **마지막에 단독 행**으로 판정을 남깁니다: - **반려 (`[VERDICT: NOT PASS]`)** → 피드백 요약을 Planner에게 전송하여 상위 레벨 계획(Rev.n)을 개시합니다. - **통과 (`[VERDICT: PASS]`)** → 모든 검토 사항이 해결되었음을 명시합니다. @@ -138,7 +144,7 @@ sequenceDiagram | 워크플로우 단계 | 해당 CLI 옵션 | 설명 | | :--- | :--- | :--- | -| **Phase 1: Planning** | `--plan` | Planner 에이전트를 기동하여 최초 계획 작성을 강제합니다. (옵션을 지정하지 않을 경우 새 계획서 작성을 생략하고 기존 계획에 의거하여 즉시 구현에 착수합니다.) | +| **Phase 1: Planning** | `--plan` | Planner 에이전트를 기동하여 최초 계획 작성을 강제합니다. (옵션을 지정하지 않을 경우 새 계획서 작성을 생략하며, 기존 계획서가 있는 경우 이를 로드하고, 없는 경우 Creator가 직접 계획 및 설계를 수립하여 즉시 구현에 착수합니다.) | | **Phase 1: Debate** | `--plan-talk N` | Planner와 Creator가 상호 대화식 챌린지 루프를 `N`회 돌며 계획을 교차 정제합니다. | | **Phase 2: Execution** | (기본값) | `--target-agent`로 명시한 주 작업 세션에 코딩 태스크를 주입합니다. | | **Phase 3: Review** | `--reviewer "A,B"` | 지정된 리뷰어 세션 리스트(`A`, `B` 등)에 교차 Peer Review를 위임합니다. | @@ -150,7 +156,7 @@ sequenceDiagram ## Workflow ```bash -# 1. Existing-plan execution + Self-review (direct task execution using existing promoted plan) +# 1. Creator Self-Planning & Development + Self-review (direct task execution using existing promoted plan or Creator's own self-plan) bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ --target-agent "" \ --task "Fix typo in deploy/README.md" diff --git a/.agents/skills/multi-agent-mux-loop/scripts/run_loop.sh b/.agents/skills/multi-agent-mux-loop/scripts/run_loop.sh index 417fa9d..90da226 100644 --- a/.agents/skills/multi-agent-mux-loop/scripts/run_loop.sh +++ b/.agents/skills/multi-agent-mux-loop/scripts/run_loop.sh @@ -117,7 +117,7 @@ wait_for_job() { status=$(python3 -c " import json, os try: - with open('.mam/jobs/$job_id/job.json') as f: + with open('.mam/jobs/$job_id.json') as f: print(json.load(f).get('status', 'unknown')) except Exception: print('unknown') @@ -331,7 +331,7 @@ log_info "=== Phase 2: Code Implementation ===" # cumulative and non-empty even after the Creator commits per DoD (P0-1). BASE_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "") -EXECUTION_PROMPT="다음 작업 목표를 완성해주세요: $TASK" +EXECUTION_PROMPT="계획서가 존재하지 않으므로, 작업자(Creator)의 판단하에 스스로 구현 계획 및 설계를 수립한 뒤, 이를 바탕으로 코드를 구현하고 다음 작업 목표를 완성해주세요. 작업 목표: $TASK" if [ -n "$CURRENT_PLAN" ]; then EXECUTION_PROMPT="이미 수립된 다음 계획서에 입각하여 작업자의 판단하에 코드를 구현하고 작업 목표를 완성해주세요. 계획서:\n$CURRENT_PLAN\n\n작업 목표: $TASK" fi diff --git a/.agents/skills/multi-agent-mux-resume/scripts/resume_session.sh b/.agents/skills/multi-agent-mux-resume/scripts/resume_session.sh new file mode 100755 index 0000000..6dfd038 --- /dev/null +++ b/.agents/skills/multi-agent-mux-resume/scripts/resume_session.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# resume_session.sh — resume a stopped session +set -euo pipefail + +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh" + +usage() { + cat < --agent --session +EOF +} + +WORKSPACE="" +AGENT="" +SESSION_NAME="" + +while [ $# -gt 0 ]; do + case "$1" in + --workspace) WORKSPACE="$2"; shift 2 ;; + --agent) AGENT="$2"; shift 2 ;; + --session) SESSION_NAME="$2"; shift 2 ;; + -h|--help) usage; exit 0 ;; + *) echo "ERROR: unknown arg: $1" >&2; exit 2 ;; + esac +done + +[ -n "$WORKSPACE" ] || { echo "ERROR: --workspace required" >&2; exit 2; } +[ -n "$AGENT" ] || { echo "ERROR: --agent required" >&2; exit 2; } +[ -n "$SESSION_NAME" ] || { echo "ERROR: --session required" >&2; exit 2; } + +# 1. Resolve the session id +UUID=$(bash "$(dirname "${BASH_SOURCE[0]}")/resolve_session_id.sh" \ + --workspace "$WORKSPACE" --agent "$AGENT" --session "$SESSION_NAME") + +if [ -z "$UUID" ]; then + echo "ERROR: No saved session for $WORKSPACE ($AGENT). Use multi-agent-mux-create first." >&2 + exit 1 +fi + +export TMUX_SERVER_NAME="$(resolve_tmux_server "$SESSION_NAME")" + +# 2. If tmux is alive, print warning or attach. +if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then + echo "tmux '$SESSION_NAME' already running." + # Just update YAML to make sure it's set to running + bash "$(dirname "${BASH_SOURCE[0]}")/update_yaml_resumed.sh" \ + --session "$SESSION_NAME" --uuid "$UUID" --agent "$AGENT" + exit 0 +fi + +# 3. Resolve isolation settings for this session +ISO_ROOT="" +ISO_ENV="" +ISO_ARGS="" + +ISO_DATA=$(env_python "$AGENT_SESSIONS_YAML" SESSION_NAME="$SESSION_NAME" <<'PYEOF' +import os, json, yaml, sqlite3 +name = os.environ['SESSION_NAME'] +yaml_path = os.environ['YAML_PATH'] +db_path = os.path.splitext(yaml_path)[0] + '.db' +d = {} +try: + if os.path.exists(db_path): + conn = sqlite3.connect(db_path, timeout=60.0) + row = conn.execute('SELECT data FROM sessions WHERE name=?', (name,)).fetchone() + if row: + s = json.loads(row[0]) + print(json.dumps(s.get('isolation') or {})) + raise SystemExit(0) + elif os.path.exists(yaml_path): + with open(yaml_path) as f: + d = yaml.safe_load(f) or {} +except Exception: + pass +for s in d.get('tmux_sessions', []): + if s.get('name') == name: + print(json.dumps(s.get('isolation') or {})) + raise SystemExit(0) +print("{}") +PYEOF +) + +ISO_ROOT=$(printf '%s' "$ISO_DATA" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("root",""))') +if [ -n "$ISO_ROOT" ]; then + ISO_ENV="$(isolation_env_prefix "$AGENT" "$ISO_ROOT")" + ISO_ARGS="$(isolation_cmd_args "$AGENT" "$ISO_ROOT")" + echo "Re-applying isolation: root=$ISO_ROOT env=$ISO_ENV args=$ISO_ARGS" +fi + +# Determine CMD_FULL with isolation applied +case "$AGENT" in + claude) CMD_FULL="claude --dangerously-skip-permissions -r $UUID" ;; + agy) CMD_FULL="agy --dangerously-skip-permissions --conversation $UUID" ;; + hermes) CMD_FULL="hermes --resume $UUID" ;; + cline) CMD_FULL="cline -i --id $UUID" ;; +esac + +# Prepend env prefix and append command args (T4) +if [ -n "$ISO_ENV" ]; then + CMD_FULL="$ISO_ENV $CMD_FULL" +fi +if [ -n "$ISO_ARGS" ]; then + CMD_FULL="$CMD_FULL $ISO_ARGS" +fi + +# 4. Spawn new tmux session + run agent with the saved id +case "$AGENT" in + claude) + if [ -z "$ISO_ROOT" ] && [ -x "$HOME/.local/bin/canary-projects-multi-agent-mux-creator-claude" ]; then + START_CMD="tmux new-session -d -s \"$SESSION_NAME\" -x 140 -y 40 -c \"$WORKSPACE\" \"$HOME/.local/bin/canary-projects-multi-agent-mux-creator-claude\"" + else + START_CMD="tmux new-session -d -s \"$SESSION_NAME\" -x 140 -y 40 -c \"$WORKSPACE\" \"$CMD_FULL\"" + fi + eval "$START_CMD" + # auto-handle trust / bypass dialogs + handle_startup_dialogs "$SESSION_NAME" 20 + ;; + agy|hermes|cline) + eval "tmux new-session -d -s \"$SESSION_NAME\" -x 140 -y 40 -c \"$WORKSPACE\" \"$CMD_FULL\"" + ;; +esac + +# Wait for TUI readiness or let it settle +sleep 2 + +# 5. Update agent-sessions.yaml: status running, last_visible_status +bash "$(dirname "${BASH_SOURCE[0]}")/update_yaml_resumed.sh" \ + --session "$SESSION_NAME" --uuid "$UUID" --agent "$AGENT" + +echo "Successfully resumed $SESSION_NAME ($AGENT)" diff --git a/PLAN_LOOP.md b/PLAN_LOOP.md index e25736f..8896c79 100644 --- a/PLAN_LOOP.md +++ b/PLAN_LOOP.md @@ -16,7 +16,7 @@ $ bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ [--max-loop N] \ [--verbose] \ [--cleanup] \ - --target-agent "canary-projects-multi-agent-mux-creator-claude" \ + --target-agent "" \ --task "수행할 작업 목표" ``` @@ -24,7 +24,7 @@ $ bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ | 옵션명 | 기본값 | 분류 | 역할 및 안전 조치 | |---|---|---|---| -| `--plan` | 비활성 | 기능 | Planner 에이전트를 기동하여 협력 계획 수립 및 토론 단계 개시. | +| `--plan` | 비활성 | 기능 | Planner 에이전트를 기동하여 협력 계획 수립 및 토론 단계 개시. (비활성화 시 기존 계획서를 로드하며, 계획서가 없는 경우 Creator가 직접 계획 및 설계를 수립하여 구동) | | `--plan-talk N` | `1` | 안전 | 플래너-작업자 간 토론 왕복 횟수 상한선. 토큰 낭비 무한 토론 차단. | | `--reviewer "A,B"` | 비활성 | 기능 | 지정된 peer 리뷰어 에이전트 세션(들)에 피드백 루프 의뢰 (주 작업자 세션은 강제 제외). | | `--all-reviewer` | 비활성 | 기능 | 레지스트리 상의 모든 `role: reviewer` 세션들을 전수 자동 수집하여 의뢰 (주 작업자 세션은 강제 제외). | @@ -42,8 +42,8 @@ $ bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ sequenceDiagram autonumber actor User as 사용자 / run_loop.sh - participant Plan as Planner Claude - participant Dev as Creator Claude + participant Plan as Planner Agent + participant Dev as Creator Agent participant Rev as Reviewer Agents User->>User: run_loop.sh 기동 (옵션 세트 검증 및 대상 예외 필터링) @@ -58,8 +58,12 @@ sequenceDiagram Plan-->>Dev: 수정 반영 및 최종 계획 합의 end else --plan 미지정 - User->>Dev: Self-planning 지시 (스스로 계획 세워 즉시 시작) - fi + alt 기존 계획 존재 시 + User->>Dev: 기존 계획서 로드 및 구현 지시 + else 계획 미존재 시 + User->>Dev: Self-planning 지시 (스스로 계획/설계 수립하여 구현) + end + end %% Execution User->>Dev: delegate-job (작업 지시) @@ -77,7 +81,7 @@ sequenceDiagram end else 리뷰어 미지정 User->>Dev: Self-Review 지시 (자가 검증 및 자율 종결) - fi + end end %% Cleanup & Final Report