#!/bin/bash # 4-pane tmux layout for AI agents # ┌─────────────────────────┬─────────────────────────┐ # │ TL: 오케 + 메인구현 │ TR: 대시보드 │ # │ Claude Code │ │ # ├─────────────────────────┼─────────────────────────┤ # │ BL: 플래너 │ BR: 디자이너+검수자 │ # │ Codex (Plus) │ Claude Code │ # └─────────────────────────┴─────────────────────────┘ # # 모든 AI 페인은 ~/work/agents/ 워크스페이스에서 시작. # claude는 cwd의 CLAUDE.md를 자동 로드 → TL/BR은 매 turn 컨텍스트 자동. # BL(codex)는 자동 로드 X → dispatch.sh의 self-contained 헤더로 보완. SESSION=agents WORKSPACE=$HOME/work/agents mkdir -p "$WORKSPACE/outputs" # 부트스트랩 마커 정리 (디버깅용) rm -f "$WORKSPACE/outputs/.bootstrap_done" 2>/dev/null # Project Root는 매 작업마다 TL이 사용자에게 묻고 TASK.md에 갱신함. # (한 세션에서 여러 프로젝트를 번갈아 다룰 수 있으므로 시작 시 인자로 못 박지 않음) # 항상 리셋: 기존 세션이 있으면 죽이고 새로 만든다 tmux kill-session -t "$SESSION" 2>/dev/null # 1) 새 세션 - 첫 페인 ID 캡처 (좌상단) TL=$(tmux new-session -d -s "$SESSION" -n main -c "$WORKSPACE" -P -F '#{pane_id}') # 2) TL을 좌우 분할 → 우측이 TR TR=$(tmux split-window -h -t "$TL" -c "$WORKSPACE" -P -F '#{pane_id}') # 3) TL을 위아래 분할 → 아래가 BL BL=$(tmux split-window -v -t "$TL" -c "$WORKSPACE" -P -F '#{pane_id}') # 4) TR을 위아래 분할 → 아래가 BR BR=$(tmux split-window -v -t "$TR" -c "$WORKSPACE" -P -F '#{pane_id}') # 5) 진단: 실제 페인 위치를 /tmp/agents-layout.log 에 기록 { echo "=== Pane Layout (실제 위치) ===" tmux list-panes -t "$SESSION:main" \ -F 'pane=#{pane_id} pos=(left:#{pane_left}, top:#{pane_top}) size=#{pane_width}x#{pane_height} cwd=#{pane_current_path}' echo "지정한 ID: TL=$TL TR=$TR BL=$BL BR=$BR" echo "===============================" } > /tmp/agents-layout.log # 6) 각 페인에 명령 전송 # TL: 오케 + 메인구현 (Claude) # TR: 라이브 대시보드 (Python rich) # BL: 플래너 (Codex) # BR: 디자이너+검수자 (Claude) tmux send-keys -t "$TL" "claude" C-m tmux send-keys -t "$TR" "python3 $WORKSPACE/dashboard.py" C-m tmux send-keys -t "$BL" "codex" C-m tmux send-keys -t "$BR" "claude" C-m # 7) 시작 포커스는 좌상단 (오케) tmux select-pane -t "$TL" # 8) 백그라운드 부트스트랩 # claude/codex가 ready 되도록 12초 대기 후 페인별 역할 프롬프트 주입. # multiline 메시지는 dispatch.sh와 동일한 방식 (-l literal paste + 3 Enter). ( sleep 12 TODAY=$(date +'%Y-%m-%d %H:%M') LAST_LOG=$(tail -n 5 "$WORKSPACE/outputs/iterations.log" 2>/dev/null) [ -z "$LAST_LOG" ] && LAST_LOG="(없음 — 새 워크스페이스)" LAST_TASK_HEAD=$(awk 'NR<=12' "$WORKSPACE/TASK.md" 2>/dev/null) [ -z "$LAST_TASK_HEAD" ] && LAST_TASK_HEAD="(없음)" TL_PROMPT="새 agents 세션 시작 ($TODAY). 너는 TL = 오케스트레이터 + 메인 구현자 + GAN 루프 드라이버. [즉시 실행] 1. AGENTS.md, DESIGN.md, TASK.md, outputs/iterations.log 읽고 상태 파악. 2. iterations.log 마지막 줄 mtime이 24시간 이내면 \"이전 작업 이어가는 세션\"일 가능성 높음. 사용자 첫 메시지 받으면: - 새 작업 같음 → Project Root 묻기 → TASK.md 갱신 → plan→design→review 흐름. - 이어가는 거 같음 → \"어제 iter=N (마지막 점수 NN)에서 끊겼는데 이어갈까?\" 명시적 확인. 추측 금지. 3. dispatch.sh 호출 시 self-contained 헤더가 자동 prepend됨 — 본문엔 작업 내용만. [직전 iterations.log (tail -5)] $LAST_LOG [직전 TASK.md 헤더 12줄] $LAST_TASK_HEAD 사용자 메시지 받을 때까지 대기." BL_PROMPT="새 agents 세션 시작 ($TODAY). 너는 BL = 플래너 + 보조 (Codex Plus). dispatch.sh planner 메시지 오면 발동. 매 메시지에 [ROLE: planner | iter=N | project=...] 헤더 + 필독 파일 목록 자동 포함됨. 헤더 따라 ~/work/agents/AGENTS.md, TASK.md 읽고 outputs/plan.md 작성. 요청 없을 때는 대기." BR_PROMPT="새 agents 세션 시작 ($TODAY). 너는 BR = 디자이너 + 검수자 (점수 산출). [즉시 실행] 1. AGENTS.md, DESIGN.md, TASK.md, outputs/iterations.log 읽기. 2. iter ≥ 1이면 outputs/review.md, outputs/design.md도 읽어서 직전 비평/디자인 맥락 파악. 3. dispatch.sh로 메시지 오면 헤더의 [ROLE: designer] 또는 [ROLE: reviewer]에 따라 모드 전환. [직전 iterations.log (tail -5)] $LAST_LOG 요청 올 때까지 대기." send_bootstrap() { local pane="$1" local msg="$2" tmux send-keys -t "$pane" -l "$msg" sleep 1.2 tmux send-keys -t "$pane" Enter sleep 0.6 tmux send-keys -t "$pane" Enter sleep 0.6 tmux send-keys -t "$pane" Enter } send_bootstrap "$TL" "$TL_PROMPT" send_bootstrap "$BL" "$BL_PROMPT" send_bootstrap "$BR" "$BR_PROMPT" # 부트스트랩 완료 마커 (디버깅용) date +%s > "$WORKSPACE/outputs/.bootstrap_done" ) & exec tmux attach -t "$SESSION"