# Design Agent — 진행 상황 ## 현재 상태 요약 | 상태 | 개수 | |------|------| | done | 23 | | in-progress | 0 | | todo | 0 | | bug-fix | 7 (BF-4~10) | | blocked | 0 | | **전체** | **30** | **Phase 2 완료 (2026-03-25):** P2-A~E 전체 done. --- ## Phase 1: 기반 구축 | 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 | |--------|------|------|------|------|------| | DA-1: 프로젝트 셋업 | done | - | - | - | pyproject.toml, .env | | DA-2: FastAPI 서버 | done | - | - | - | DA-1 이후 | | DA-3: 디자인 토큰 + 기본 CSS | done | - | - | - | 독립 작업 가능 | ## Phase 2: 블록 템플릿 제작 | 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 | |--------|------|------|------|------|------| | DA-4: 비교 블록 | done | - | - | - | DA-3 이후 | | DA-5: 카드 그리드 | done | - | - | - | DA-3 이후 | | DA-6: 관계도 | done | - | - | - | DA-3 이후 | | DA-7: 프로세스 | done | - | - | - | DA-3 이후 | | DA-8: 강조 인용 | done | - | - | - | DA-3 이후 | | DA-9: 결론 바 | done | - | - | - | DA-3 이후 | | DA-10: 비교 테이블 | done | - | - | - | DA-3 이후 | | DA-11: 슬라이드 조합 렌더러 | done | - | - | - | DA-4~10 이후 | ## Phase 3: AI 파이프라인 연결 | 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 | |--------|------|------|------|------|------| | DA-12: 1단계 Kei 실장 (꼭지+정보구조+role) | done | - | - | - | Kei API 연동. info_structure + role(flow/reference) | | DA-13a: 2단계A 프리셋 선택 (규칙 기반) | todo | - | - | - | reference→sidebar-right, 비교→two-column 등 자동 | | DA-13b: 2단계B 블록 매핑 (Sonnet) | todo | - | - | - | 프리셋 CSS 포함 프롬프트. zone별 블록 배정 | | DA-13c: 3단계 텍스트 편집자 (Kei 역할) | todo | - | - | - | 의미 우선 편집 + 표 편집 + 자세히보기(요약+상세) | | DA-14: 4단계 실무자 + 5단계 재검토 | todo | - | - | - | 디자인 조정 + HTML 조립 + 팀장 균형 재검토 | ## Phase 4: UI + 출력 | 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 | |--------|------|------|------|------|------| | DA-15: 프론트엔드 | done | - | - | - | DA-14 이후. HTML 다운로드만 | | DA-16: 통합 테스트 | done | - | - | - | DA-15 이후 | --- ## 버그 수정 이력 ### BF-1: 프론트엔드 SSE 파싱 실패 [발견: DA-15 이후] - **현상:** 서버는 정상 응답하지만 브라우저에서 결과 미표시. "시작 중..." 고정. - **원인:** main.py Python 문자열 안에 HTML/JS를 넣어서 `\n`이 실제 줄바꿈으로 변환 → JS `split('\n\n')` 깨짐. 또한 Windows SSE가 `\r\n\r\n`(CRLF)로 구분. - **해결:** static/index.html 별도 파일로 분리. FileResponse로 서빙. SSE split을 `/\r?\n\r?\n/` 정규식으로 변경. - **기술:** FileResponse (FastAPI 내장), 추가 의존성 0 - **충돌 검토:** API 경로와 충돌 없음. 기존 코드 변경 없음. Kei persona 무관. - **상태:** done ### BF-2: 블록 내용이 비어있음 (Jinja2 include 변수 전달 실패) [발견: BF-1 이후] - **현상:** 슬라이드 HTML은 생성되지만 모든 블록 텍스트가 비어있음. 레이아웃 구조만 있고 내용 없음. - **원인:** renderer.py에서 Jinja2 `include`로 블록 템플릿을 삽입하는데, `include`는 블록별 변수를 개별 전달하지 못함. Sonnet이 채운 data가 템플릿에 도달 안 함. - **해결:** `include` 대신 각 블록 템플릿을 `env.get_template().render(**data)`로 개별 렌더링 후 완성된 HTML을 삽입. `render_standalone_block()`이 이미 이 방식으로 동작 중 → 통일. - **기술:** Jinja2 `get_template().render()` (내장), 추가 의존성 0 - **수정 파일:** renderer.py, templates/slide-base.html - **충돌 검토:** 블록 템플릿 7개 변경 없음. pipeline.py 호출 시그니처 동일. Kei persona 무관. - **상태:** done ### BF-3: 한글 깨짐 (다운로드 HTML 파일) [발견: BF-1 이후] - **현상:** 다운로드한 HTML 파일에서 한글이 `ê±´ì¤ì°ì` 같은 깨진 문자로 표시. - **원인:** Blob 다운로드 시 UTF-8 BOM 미포함. 일부 에디터/브라우저가 인코딩 자동 감지 실패. - **해결:** download() 함수에서 Blob 생성 시 UTF-8 BOM(`'\uFEFF'`) 접두사 추가. - **기술:** JavaScript BOM 1줄, 추가 의존성 0 - **수정 파일:** static/index.html - **충돌 검토:** 미리보기(iframe)에 영향 없음. SSE 파싱에 영향 없음. - **상태:** done ### BF-4: body 블록 겹침 [발견: 프리셋 도입 후] - **현상:** body area에 4개 블록이 겹쳐서 하나만 보임 - **원인:** renderer가 같은 area에 별도 div 생성 → CSS Grid 겹침 - **해결:** OrderedDict로 같은 area 그룹핑 → 하나의 div에 flex-column - **기술:** Python OrderedDict (내장) - **수정 파일:** renderer.py - **상태:** 코드 수정 완료, 테스트 필요 ### BF-5: 제목 안 보임 [발견: 프리셋 도입 후] - **현상:** 슬라이드 제목이 표시 안 됨 - **원인:** 프리셋 area명 `title` vs slide-base.html `header` 불일치 - **해결:** 프리셋 4개에서 `title` → `header` 교체 - **기술:** 문자열 교체 - **수정 파일:** design_director.py LAYOUT_PRESETS - **상태:** sidebar-right 수정 완료, 나머지 3개 확인 필요 ### BF-6: sidebar 카드 3열 찢어짐 [발견: sidebar-right 테스트] - **현상:** sidebar 35% 너비에 카드 3열 → 각 카드 폭 극히 좁아 찢어짐 - **원인:** 팀장이 sidebar 공간 고려 없이 배치 - **해결:** Step B 프롬프트에 sidebar 공간 안내 추가 - **기술:** 프롬프트 엔지니어링 - **수정 파일:** design_director.py STEP_B_PROMPT - **상태:** 미수정 ### BF-7: body 블록 텍스트 비어있음 [발견: 편집자 출력 확인] - **현상:** body의 4개 블록 중 1개만 텍스트 있고 3개 비어있음 - **원인:** content_editor 매칭에서 같은 area 첫 번째만 매칭 (break) - **해결:** area + topic_id로 정확 매칭. 편집자 프롬프트에 topic_id 출력 추가 - **기술:** Python 조건문 수정 - **수정 파일:** content_editor.py - **상태:** 미수정 ### BF-8: 컨테이너 예산 기반 블록 배치 [발견: 파이프라인 실행 후 프레임 넘침] - **현상:** body에 4개 블록(quote+card+venn+comparison) 쌓아서 총 ~810px → 490px 예산 초과 → 잘림 - **원인:** 팀장 프롬프트가 콘텐츠 중심 블록 선택 (높이 제약 없음). 큰 SVG(380px)를 다른 블록과 함께 배치 - **해결:** - LAYOUT_PRESETS: zone별 budget_px + width_pct 추가 - STEP_B_PROMPT: "컨테이너 예산 확인 → 배정 → 블록+높이 계산 → 검증" 4단계 사고 - catalog.yaml: 블록별 height_cost (compact/medium/large/xlarge) + 높이 참고표 - base.css: area div에 overflow:hidden + min-height:0 안전망 - 시각화 블록: flex-shrink + responsive SVG - **수정 파일:** design_director.py, catalog.yaml, base.css, venn-diagram.html, circle-gradient.html - **상태:** done (2026-03-25) - **한계:** 프롬프트만으로는 Sonnet이 grid를 무시하는 문제를 방지 불가 → BF-9 필요 - **충돌 해소 (2026-03-25):** 다른 에이전트가 구 블록(quote-block, card-grid, comparison)을 BLOCK_SLOTS/defaults에서 의도적 제거. BF-8에서 catalog에 복원했던 것을 다시 제거하여 정합성 확보. 구 블록 → 신규 블록 대체 방향 확정. ### BF-9: grid와 Sonnet의 역할 분리 [발견: 파이프라인 실행 결과 분석] - **현상:** Sonnet이 프리셋 grid 대신 자기만의 5행 all-auto grid 생성. zone명도 불일치(main, definitions 등) - **원인:** 설계 오류 — Sonnet에게 grid 값을 출력하라고 요구한 것 자체가 잘못. grid는 코드(Step A)가 결정, Sonnet이 건드릴 대상 아님 - **해결:** - Step B 프롬프트: grid 출력 요구 제거, blocks 배열만 출력하도록 변경 - create_layout_concept(): grid 값은 프리셋에서 직접 가져옴 (Sonnet 출력 무시) - Sonnet이 출력한 area명이 프리셋 zone에 없으면 코드에서 자동 매핑 - **원칙:** 코드가 결정한 것은 코드가 유지한다. Sonnet은 콘텐츠 판단만. - **수정 파일:** design_director.py (STEP_B_PROMPT + create_layout_concept) - **상태:** done (2026-03-25) ### BF-10: _CATALOG_MAP 캐시 갱신 문제 [발견: 파이프라인 실행 결과 분석] - **현상:** relationship 블록이 _legacy CSS 원형으로 렌더링됨 (SVG premium이 아님). catalog.yaml 매핑이 적용 안 됨. - **원인:** _CATALOG_MAP이 모듈 레벨 global로 한 번만 로드. 서버가 구 catalog를 캐시. - **해결:** 파일 mtime 확인 후 자동 reload, 또는 매 렌더링 시 강제 reload - **기술:** Python pathlib stat() - **수정 파일:** renderer.py - **상태:** done (2026-03-25) ## Phase 5: 블록 라이브러리 확장 | 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 | |--------|------|------|------|------|------| | DA-17: Figma 에셋 추출 + 블록 템플릿 | done | - | 2026-03-25 | 2026-03-25 | 스크린샷 16장, 에셋 15개+, 신규 블록 6종 | | DA-18: 카테고리 폴더 재편 | done | - | 2026-03-25 | 2026-03-25 | 6개 카테고리 + INDEX.md | | DA-19: 변형 확장 | done | - | 2026-03-25 | 2026-03-25 | 46개 달성. catalog/BLOCK_SLOTS/INDEX 전체 동기화 완료 | ## Phase 2: 파이프라인 고도화 | 태스크 | 상태 | 담당 | 시작 | 완료 | 메모 | |--------|------|------|------|------|------| | P2-A: FAISS 블록 검색 | done | - | 2026-03-25 | 2026-03-25 | bge-m3 1024d, 46벡터. block_search.py 신규. director 연동 완료 | | P2-B: SVG N개 자동 배치 | done | - | 2026-03-25 | 2026-03-25 | svg_calculator.py 신규. N=2~7 테스트 통과. Phase 1 fallback 유지 | | P2-C: Step A Opus+FAISS | done | - | 2026-03-25 | 2026-03-25 | _opus_block_recommendation(). Kei API 경유. Anthropic 직접 0회 | | P2-D: 5단계 재검토 강화 | done | - | 2026-03-25 | 2026-03-25 | MAX_REVIEW_ROUNDS=2. expand/shrink/rewrite 3개 action. 다른쪽 구현+루프 추가 | | P2-E-1: Pillow 이미지 크기 | done | - | 2026-03-25 | 2026-03-25 | 다른쪽에서 image_utils.py 구현 완료 | | P2-E-2: details-block 연결 | done | - | 2026-03-25 | 2026-03-25 | "생략"→details-block 배치. fallback에도 반영 | | DA-21: renderer 카테고리 경로 지원 | todo | - | - | - | DA-18 이후 | | DA-22: catalog.yaml 경로 업데이트 | todo | - | - | - | DA-21 이후 | --- ## 블로킹 이슈 없음 --- ## DA-17 상세 기록 ### Figma 추출 결과 - **파일:** 바론컨설턴트 홈페이지_기획팀공유 (uw7Z2hZGv9k6ygwrgYaAnF) - **접근:** Figma REST API (유료 계정 토큰) - **스크린샷:** 16장 (메인 3 + 자세히보기 13) - **에셋:** bg_header, card_img x3, compare_box x2, dx_bim_table, circle_label, mountain_viz, image_grid x2 등 - **노드 분석:** 2-1_01 (건설산업), 2-1_02 (BIM) depth=4 상세 구조 ### 신규 블록 템플릿 6종 | 블록 | 카테고리 | 검증 결과 | |------|---------|---------| | section-title-with-bg | headers/ | ✅ 렌더링 OK | | topic-left-right | headers/ | ✅ 렌더링 OK, 사용자 확인 | | compare-pill-pair | visuals/ | ✅ 색상 2차 수정 후 OK | | circle-gradient | visuals/ | ✅ 사용자 확인 OK | | card-image-3col | cards/ | ✅ 사용자 확인 OK | | image-row-2col | media/ | ✅ 렌더링 OK | ### 기존 블록 수정 | 블록 | 수정 내용 | |------|---------| | comparison-table → compare-3col-badge | Figma 톤으로 재디자인 (중앙 VS 배지, 좌우 중앙정렬) | | conclusion-bar → conclusion-accent-bar | Figma 톤으로 재디자인 (좌측 파란 라인 + 밝은 배경) | | compare-box → compare-pill-pair | Figma 톤으로 재디자인 (하늘색 둥근 테두리 + 시안 텍스트) | ### 시각화 방식 검증 이력 1. **CSS 원형 벤 다이어그램** → 실패 (클로드스러운 플랫 디자인, 20점) 2. **AntV infographic-cli** → 제한적 (일부 SSR 타임아웃, 관계도 용도 안 맞음) 3. **AI 이미지(Gemini) + HTML 텍스트 오버레이** → 실패 (이미지 내 원 위치가 매번 달라 텍스트 위치 맞출 수 없음) 4. **SVG premium (radialGradient + filter + 수학적 좌표 계산)** → **성공! 최종 확정** - 텍스트가 SVG 안에 있어 위치 100% 정확 - 그라데이션/글로우/하이라이트로 Figma 수준 품질 - N개 원소 자동 배치 (360/N 간격, cos/sin) ### Phase 1 완료 요약 (2026-03-25) - 블록 라이브러리: 6개 카테고리, 18개 블록 변형 - 시각화 방식: SVG premium 확정 - Figma 에셋: 스크린샷 16장, 에셋 15개+ - 블록 검증: 독립 렌더링 테스트 전체 통과 - 노하우: 텍스트=HTML/CSS, 시각화=SVG, 실사=이미지, AI이미지=배경전용 --- ## 완료된 준비 사항 | 항목 | 파일 | 상태 | |------|------|------| | 프로젝트 규칙 | CLAUDE.md | 완료 (블록 라이브러리 구조 반영) | | 실행 계획 | PLAN.md | 완료 (Phase 5 추가) | | 진행 추적 | PROGRESS.md | 완료 (이 파일) | | 기술 조사 | docs/RESEARCH.md | 완료 | | Figma 분석 | docs/figma-analysis/DESIGN-ANALYSIS.md | 완료 | | Figma 추출 계획 | docs/FIGMA-COMPONENT-EXTRACTION-PLAN.md | 완료 | | 블록 라이브러리 | templates/blocks/ (6개 카테고리) | 구축 완료, 변형 확장 중 | | 블록 인덱스 | templates/blocks/INDEX.md | 완료 | | 블록 카탈로그 | templates/catalog.yaml | 완료 (경로 업데이트 필요) | | MCP 설정 | .mcp.json (Framelink Figma MCP) | 완료 |