Files
s-canvas/agents.sh
HYUNJUNGLEE b9342f6726 Import S-CANVAS source + iter=1~7 lint cleanup
S-CANVAS (Saman Corp.) — DXF + DEM + AI 기반 3D 조감도 생성 엔진.
~24k LOC Python (scanvas_maker.py 7072 LOC GUI + 구조물 파서/빌더 다수).

이 커밋은 7-iter cleanup이 적용된 상태로 import:
- F821 8 + B023 6: 비동기 lambda + except/loop 변수 캡처 NameError
  (Py3.13에서 reproduce 확인된 진짜 버그)
- RUF012 4 + RUF013 1: ClassVar / implicit Optional 명시화
- F811/B905/B904/F401/F841/W293/F541/UP/SIM/RUF/PLR 700+ cleanup/modernization

신규 파일:
- ruff.toml: target=py313, Korean unicode/저자 스타일/도메인 복잡도 무력화
- requirements-py313.txt: pyproj>=3.7, scipy>=1.14, numpy>=2.0.2 (Py3.13 wheel)
- .gitignore: gcp-key.json, 캐시, 백업, 생성 이미지 제외

검증: ruff 0 errors, py_compile 0 errors, import 33/33 OK on Py3.13.13.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 10:29:08 +09:00

139 lines
5.5 KiB
Bash

#!/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 흐름.
- 이어가는 거 같음 → \"어제 <TASK 제목> 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"