ByteBytego 스타일의 시스템 아키텍처 다이어그램을 자동 생성합니다. 프로젝트 구조를 분석하여 HTML/SVG 기반 애니메이션 다이어그램을 만듭니다. "아키텍처 그려줘", "구조도", "architecture diagram" 요청 시 사용합니다.
권장 모델: Opus — 이 스킬은 복잡한 SVG 좌표 계산이 필요하므로 Opus 모델을 권장합니다. Sonnet에서도 동작하지만 좌표 정확도가 떨어질 수 있습니다. 실행 전
/model opus로 전환하세요.
Explore 에이전트를 사용하여 프로젝트 구조를 분석합니다:
다이어그램을 그리기 전에 반드시 각 박스의 좌표와 연결점을 먼저 계산하세요.
각 박스에 대해 다음을 계산합니다:
박스: { x, y, w, h }
중심: cx = x + w/2, cy = y + h/2
연결점:
top = (cx, y)
bottom = (cx, y + h)
left = (x, cy)
right = (x + w, cy)
화살표 시작/끝은 반드시 박스의 edge center (top/bottom/left/right 중 하나)에 연결
같은 행에서 여러 박스로 팬아웃할 때:
박스 중심에서 벗어난 연결 금지: 절대로 박스 모서리나 임의 지점에 연결하지 마세요
화살표가 다른 박스를 관통하면 안 됨: path가 중간에 있는 박스를 지나가지 않도록 경로를 우회하세요
cubic bezier의 마지막 좌표가 반드시 target의 edge center여야 함:
M sx,sy C cx1,cy1 cx2,cy2 **ex,ey** ← (ex,ey)가 target.top/bottom/left/right 중 하나여야 함C 300,200 400,200 450,250 (450,250이 어떤 박스의 edge center도 아님)C 300,200 475,200 475,232 (475,232 = Box B의 top center)4개 이상 팬아웃 시 시작점 분산 필수:
Box A: rect x=100 y=50 w=160 h=66
→ cx=180, cy=83
→ top=(180,50), bottom=(180,116), left=(100,83), right=(260,83)
Box B: rect x=400 y=200 w=150 h=64
→ cx=475, cy=232
→ top=(475,200), bottom=(475,264), left=(400,232), right=(550,232)
A→B 아래로 연결:
시작 = A.bottom = (180, 116)
끝 = B.top = (475, 200)
path = "M 180,116 C 180,158 475,158 475,200"
midY = (116 + 200) / 2 = 158
docs/architecture.html 파일로 ByteBytego 스타일 다이어그램을 생성합니다.
레이아웃:
박스 스타일:
<script src="https://unpkg.com/lucide@latest"></script> + <i data-lucide="icon-name"></i>화살표 (CRITICAL):
화살촉 Marker 정의 (MUST INCLUDE):
모든 SVG <defs> 안에 사용하는 색상별 marker를 반드시 정의해야 합니다. marker가 없으면 화살표 머리가 보이지 않습니다.
<defs>
<!-- 사용하는 모든 색상에 대해 marker 정의 필수 -->
<marker id="ah-gray" viewBox="0 0 10 8" refX="10" refY="4" markerWidth="7" markerHeight="6" orient="auto">
<path d="M0,0 L10,4 L0,8 Z" fill="#94a3b8"/>
</marker>
<marker id="ah-green" viewBox="0 0 10 8" refX="10" refY="4" markerWidth="7" markerHeight="6" orient="auto">
<path d="M0,0 L10,4 L0,8 Z" fill="#10b981"/>
</marker>
<marker id="ah-purple" viewBox="0 0 10 8" refX="10" refY="4" markerWidth="7" markerHeight="6" orient="auto">
<path d="M0,0 L10,4 L0,8 Z" fill="#8b5cf6"/>
</marker>
<marker id="ah-blue" viewBox="0 0 10 8" refX="10" refY="4" markerWidth="7" markerHeight="6" orient="auto">
<path d="M0,0 L10,4 L0,8 Z" fill="#3b82f6"/>
</marker>
<marker id="ah-cyan" viewBox="0 0 10 8" refX="10" refY="4" markerWidth="7" markerHeight="6" orient="auto">
<path d="M0,0 L10,4 L0,8 Z" fill="#06b6d4"/>
</marker>
<marker id="ah-pink" viewBox="0 0 10 8" refX="10" refY="4" markerWidth="7" markerHeight="6" orient="auto">
<path d="M0,0 L10,4 L0,8 Z" fill="#ec4899"/>
</marker>
<marker id="ah-orange" viewBox="0 0 10 8" refX="10" refY="4" markerWidth="7" markerHeight="6" orient="auto">
<path d="M0,0 L10,4 L0,8 Z" fill="#f97316"/>
</marker>
</defs>
중요: refX="10"으로 설정해야 화살촉이 선 끝에 정확히 위치합니다. refX="9" 이하면 화살촉이 선 끝 안쪽에 묻혀 보이지 않을 수 있습니다.
화살표 path에 반드시 marker-end="url(#ah-색상)" 속성을 추가하세요:
<path d="M 100,200 C 100,260 300,260 300,320" class="arrow" stroke="#10b981" marker-end="url(#ah-green)"/>
M sx,sy C sx,midY ex,midY ex,ey (midY = (sy+ey)/2)M sx,sy C midX,sy midX,ey ex,ey (midX = (sx+ex)/2)M x,y1 L x,y2 또는 M x1,y L x2,y팬아웃 연결 (1개 → 여러개):
중요: 팬아웃의 S-커브 끝에 반드시 **수직 L 구간(30px 이상)**을 추가하여 화살촉이 정확히 아래를 향하도록 합니다. S-커브만으로 끝나면 화살촉이 비스듬하게 표시됩니다.
source.bottom = (sx, sy)
targets = [(t1x, t1y), (t2x, t2y), (t3x, t3y)]
turnY = t1y - 30 (target 위 30px에서 수직 전환)
올바른 패턴 (S-커브 + 수직 L):
path1 = "M sx,sy C sx,midY t1x,midY t1x,turnY L t1x,t1y"
path2 = "M sx,sy C sx,midY t2x,midY t2x,turnY L t2x,t2y"
path3 = "M sx,sy C sx,midY t3x,midY t3x,turnY L t3x,t3y"
잘못된 패턴 (S-커브만, 화살촉 비스듬):
path1 = "M sx,sy C sx,midY t1x,midY t1x,t1y" ← 화살촉 방향 불안정!
방법 2: 시작점을 분산 (박스가 좁을 때, 간격 25px)
path1 = "M sx-25,sy C sx-25,midY t1x,midY t1x,t1y"
path2 = "M sx,sy C sx,midY t2x,midY t2x,t2y"
path3 = "M sx+25,sy C sx+25,midY t3x,midY t3x,t3y"
수렴 연결 (여러개 → 1개):
sources = [(s1x, s1y), (s2x, s2y)]
target.top = (tx, ty)
path1 = "M s1x,s1y C s1x,midY tx,midY tx,ty"
path2 = "M s2x,s2y C s2x,midY tx,midY tx,ty"
수평 연결 (좌↔우):
source.right = (sx, sy)
target.left = (tx, ty)
직선 (같은 높이): "M sx,sy L tx,ty"
곡선 (다른 높이): "M sx,sy C midX,sy midX,ty tx,ty"
애니메이션:
<animateMotion> 으로 데이터 흐름 표현begin 속성으로 시차 적용 (0.3~0.5s 간격)dur 2~2.5s, repeatCount="indefinite"패널 구성 (프로젝트에 맞게 조정):
display:flex; align-items:center;를 .panel-body에 적용하거나 SVG viewBox 높이를 내용물에 맞게 줄임SVG viewBox 크기:
다이어그램 생성 후 모든 화살표를 검증합니다:
<defs> 안에 사용된 모든 색상의 marker가 정의되어 있는지 확인 — marker가 없으면 화살촉이 보이지 않음<path> 에 marker-end="url(#ah-색상)" 속성이 있는지 확인검증 체크리스트 예시:
화살표: User.bottom → FastAPI.top
User rect: x=450 y=50 w=200 h=66 → bottom = (550, 116)
FastAPI rect: x=350 y=300 w=300 h=70 → top = (500, 300)
path d="M 550,116 C 550,208 500,208 500,300" ← OK (시작=550,116 끝=500,300)
marker-end="url(#ah-green)" ← OK
<defs>에 id="ah-green" marker 존재 ← OK
검증 실패 시 좌표를 수정합니다.
생성된 HTML을 Playwright로 렌더링하고 스크린샷을 캡처하여 시각적으로 검증합니다.
# Windows/Mac/Linux 공통: file:// 절대 경로 사용
npx playwright screenshot --viewport-size="1400,900" --full-page "file:///${PWD}/docs/architecture.html" docs/architecture-screenshot.png
# Windows에서 안 되면:
# npx playwright screenshot --viewport-size="1400,900" --full-page "file:///D:/path/to/docs/architecture.html" docs/architecture-screenshot.png
캡처된 docs/architecture-screenshot.png를 Read tool로 읽어서 다음을 확인합니다:
문제 발견 시: HTML을 수정하고 다시 스크린샷 캡처 → 검증을 반복합니다. 최대 3회 반복 후 사용자에게 결과를 보고합니다.
스크린샷 검증에서 문제가 발견되면 반드시 수정하고 다시 캡처합니다. 최대 3회 반복.
Round 1: 생성 → 스크린샷 → 검증 → 문제 발견
Round 2: HTML 수정 → 스크린샷 → 검증 → 문제 발견
Round 3: HTML 수정 → 스크린샷 → 검증 → 통과 (또는 사용자에게 보고)
각 라운드에서 확인할 항목:
3회 이내에 모든 항목이 통과될 때까지 반드시 반복하세요. 사용자에게 묻지 말고 자동으로 진행하세요.