docs: 설치가이드 전면 리디자인 — 나눔고딕 통일·표 디자인 개선·꽉 찬 레이아웃
- 폰트 나눔고딕 통일 (latin+eastasia 타입페이스 모두 명시) - 표 재디자인: 네이비 헤더행 + 지브라 행 + 격자선 + 번호/체크/경고 아이콘 원 - 스텝 진행 셰브런(1→2→3)·다크 코드블록 카드·칩·통계 스트립 추가 - zioinfo_team.png(6인 파이프라인) 활용, 슬라이드 여백 제거·내용 보강 - 환경 확인 원라이너·구버전 정리·webhook 설정 등 실무 팁 추가 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
ed6af178f3
commit
a5154e22bc
@ -4,6 +4,7 @@
|
|||||||
zioinfo(ythong 마켓플레이스) 사내전용 설치가이드 생성 — python-pptx.
|
zioinfo(ythong 마켓플레이스) 사내전용 설치가이드 생성 — python-pptx.
|
||||||
(스크립트가 진실원천: 내용 수정 후 재생성)
|
(스크립트가 진실원천: 내용 수정 후 재생성)
|
||||||
실행: python docs/gen_install_guide.py → docs/zioinfo_사내전용_설치가이드.pptx
|
실행: python docs/gen_install_guide.py → docs/zioinfo_사내전용_설치가이드.pptx
|
||||||
|
디자인 원칙: 여백 없이 꽉 찬 레이아웃 · 카드/아이콘/칩/스텝도형 · 표는 헤더행+지브라 · 폰트 나눔고딕 통일
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from pptx import Presentation
|
from pptx import Presentation
|
||||||
@ -11,18 +12,23 @@ from pptx.util import Inches, Pt
|
|||||||
from pptx.dml.color import RGBColor
|
from pptx.dml.color import RGBColor
|
||||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||||
from pptx.enum.shapes import MSO_SHAPE
|
from pptx.enum.shapes import MSO_SHAPE
|
||||||
|
from pptx.oxml.ns import qn
|
||||||
|
|
||||||
# ── 테마 (ZIO INFOTECH 브랜드: 네이비 + 라이트블루 + 그레이) ──────────
|
# ── 테마 (ZIO INFOTECH 브랜드: 네이비 + 라이트블루 + 그레이) ──────────
|
||||||
NAVY = RGBColor(0x17, 0x35, 0x7F) # 브랜드 네이비 (배경/제목)
|
NAVY = RGBColor(0x17, 0x35, 0x7F) # 브랜드 네이비 (배경/제목)
|
||||||
BLUE = RGBColor(0x2E, 0x9B, 0xD6) # 라이트블루 액센트
|
BLUE = RGBColor(0x2E, 0x9B, 0xD6) # 라이트블루 액센트
|
||||||
SKY = RGBColor(0x4F, 0xB3, 0xE8) # 밝은 하늘 포인트
|
SKY = RGBColor(0x4F, 0xB3, 0xE8) # 밝은 하늘 포인트
|
||||||
STEEL = RGBColor(0xA7, 0xAB, 0xB0) # 브랜드 그레이
|
STEEL = RGBColor(0xA7, 0xAB, 0xB0) # 브랜드 그레이
|
||||||
|
AMBER = RGBColor(0xE8, 0x9A, 0x2A) # 주의 액센트
|
||||||
INK = RGBColor(0x14, 0x2B, 0x66) # 본문 제목 네이비
|
INK = RGBColor(0x14, 0x2B, 0x66) # 본문 제목 네이비
|
||||||
GRAY = RGBColor(0x55, 0x5F, 0x70) # 본문 회색
|
GRAY = RGBColor(0x55, 0x5F, 0x70) # 본문 회색
|
||||||
LIGHT = RGBColor(0xE2, 0xED, 0xF8) # 연블루 배경
|
LIGHT = RGBColor(0xE2, 0xED, 0xF8) # 연블루 배경
|
||||||
CARD = RGBColor(0xF6, 0xF9, 0xFD)
|
CARD = RGBColor(0xF6, 0xF9, 0xFD)
|
||||||
|
ZEBRA = RGBColor(0xEE, 0xF4, 0xFB) # 표 지브라 행
|
||||||
|
GRID = RGBColor(0xD5, 0xE2, 0xF0) # 표 격자선
|
||||||
|
DARK = RGBColor(0x0E, 0x22, 0x55) # 코드 블록 배경
|
||||||
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
|
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
|
||||||
FONT = "맑은 고딕"
|
FONT = "나눔고딕" # 전 슬라이드 폰트 통일 (latin+ea)
|
||||||
|
|
||||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||||
ROOT = os.path.dirname(HERE)
|
ROOT = os.path.dirname(HERE)
|
||||||
@ -39,6 +45,12 @@ BLANK = prs.slide_layouts[6]
|
|||||||
def _set(run, size, bold=False, color=INK, font=FONT):
|
def _set(run, size, bold=False, color=INK, font=FONT):
|
||||||
run.font.size = Pt(size); run.font.bold = bold
|
run.font.size = Pt(size); run.font.bold = bold
|
||||||
run.font.color.rgb = color; run.font.name = font
|
run.font.color.rgb = color; run.font.name = font
|
||||||
|
# 한글(eastasia) 폰트까지 명시해야 나눔고딕 통일이 실제 적용됨
|
||||||
|
rPr = run._r.get_or_add_rPr()
|
||||||
|
ea = rPr.find(qn('a:ea'))
|
||||||
|
if ea is None:
|
||||||
|
ea = rPr.makeelement(qn('a:ea'), {}); rPr.append(ea)
|
||||||
|
ea.set('typeface', font)
|
||||||
|
|
||||||
|
|
||||||
def box(slide, x, y, w, h, fill=None, line=None, line_w=1.0, round_=False):
|
def box(slide, x, y, w, h, fill=None, line=None, line_w=1.0, round_=False):
|
||||||
@ -70,13 +82,37 @@ def text(slide, x, y, w, h, runs, align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.TOP,
|
|||||||
return tb
|
return tb
|
||||||
|
|
||||||
|
|
||||||
|
def shape_text(shp, label, size, bold, color, align=PP_ALIGN.CENTER):
|
||||||
|
tf = shp.text_frame; tf.word_wrap = True
|
||||||
|
tf.margin_left = tf.margin_right = Inches(0.03)
|
||||||
|
tf.margin_top = tf.margin_bottom = 0
|
||||||
|
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||||
|
p = tf.paragraphs[0]; p.alignment = align
|
||||||
|
r = p.add_run(); r.text = label; _set(r, size, bold, color)
|
||||||
|
|
||||||
|
|
||||||
|
def icon_circle(slide, x, y, d, glyph, fill=BLUE, fg=WHITE, size=13):
|
||||||
|
shp = slide.shapes.add_shape(MSO_SHAPE.OVAL, Inches(x), Inches(y), Inches(d), Inches(d))
|
||||||
|
shp.shadow.inherit = False
|
||||||
|
shp.fill.solid(); shp.fill.fore_color.rgb = fill
|
||||||
|
shp.line.fill.background()
|
||||||
|
shape_text(shp, glyph, size, True, fg)
|
||||||
|
return shp
|
||||||
|
|
||||||
|
|
||||||
|
def chip(slide, x, y, w, h, label, fill, fg=WHITE, size=11, bold=True, line=None):
|
||||||
|
shp = box(slide, x, y, w, h, fill=fill, line=line, line_w=1.0, round_=True)
|
||||||
|
shape_text(shp, label, size, bold, fg)
|
||||||
|
return shp
|
||||||
|
|
||||||
|
|
||||||
def header(slide, title, kicker=None, n=None):
|
def header(slide, title, kicker=None, n=None):
|
||||||
box(slide, 0, 0, 13.333, 1.15, fill=NAVY)
|
box(slide, 0, 0, 13.333, 1.15, fill=NAVY)
|
||||||
box(slide, 0, 1.15, 13.333, 0.06, fill=BLUE)
|
box(slide, 0, 1.15, 13.333, 0.06, fill=BLUE)
|
||||||
runs = []
|
runs = []
|
||||||
if kicker:
|
if kicker:
|
||||||
runs.append([(kicker, 12, True, SKY)])
|
runs.append([(kicker, 12, True, SKY)])
|
||||||
runs.append([(title, 26, True, WHITE)])
|
runs.append([(title, 25, True, WHITE)])
|
||||||
text(slide, 0.6, 0.12, 11.5, 0.95, runs, anchor=MSO_ANCHOR.MIDDLE, space=2)
|
text(slide, 0.6, 0.12, 11.5, 0.95, runs, anchor=MSO_ANCHOR.MIDDLE, space=2)
|
||||||
if n is not None:
|
if n is not None:
|
||||||
text(slide, 12.2, 0.12, 0.9, 0.95, [[(f"{n:02d}", 22, True, SKY)]],
|
text(slide, 12.2, 0.12, 0.9, 0.95, [[(f"{n:02d}", 22, True, SKY)]],
|
||||||
@ -84,184 +120,315 @@ def header(slide, title, kicker=None, n=None):
|
|||||||
|
|
||||||
|
|
||||||
def footer(slide):
|
def footer(slide):
|
||||||
text(slide, 0.6, 7.05, 9, 0.35, [[("ZIO INFOTECH · ythong 마켓플레이스 사내전용 설치가이드", 9, False, GRAY)]])
|
text(slide, 0.6, 7.06, 9, 0.35, [[("ZIO INFOTECH · ythong 마켓플레이스 사내전용 설치가이드", 9, False, GRAY)]])
|
||||||
text(slide, 11.0, 7.05, 1.9, 0.35, [[("2026-07", 9, False, GRAY)]], align=PP_ALIGN.RIGHT)
|
text(slide, 11.0, 7.06, 1.9, 0.35, [[("2026-07", 9, False, GRAY)]], align=PP_ALIGN.RIGHT)
|
||||||
|
|
||||||
|
|
||||||
def card(slide, x, y, w, h, title, lines, accent=BLUE, tsize=15):
|
def card(slide, x, y, w, h, title, lines, accent=BLUE, tsize=14, glyph="✓", lsize=11.5):
|
||||||
box(slide, x, y, w, h, fill=CARD, line=RGBColor(0xDD, 0xE6, 0xF2), line_w=0.75, round_=True)
|
"""아이콘 원 + 좌측 액센트 바 + 불릿 라인 카드. lines 항목이 list면 런 스펙으로 그대로 사용."""
|
||||||
box(slide, x, y, 0.12, h, fill=accent)
|
box(slide, x, y, w, h, fill=CARD, line=GRID, line_w=0.75, round_=True)
|
||||||
runs = [[(title, tsize, True, INK)]]
|
box(slide, x, y, 0.1, h, fill=accent)
|
||||||
|
icon_circle(slide, x + 0.26, y + 0.19, 0.36, glyph, fill=accent, size=13)
|
||||||
|
text(slide, x + 0.74, y + 0.17, w - 0.92, 0.45, [[(title, tsize, True, INK)]])
|
||||||
|
runs = []
|
||||||
for ln in lines:
|
for ln in lines:
|
||||||
runs.append([("· ", 11, True, accent), (ln, 11.5, False, GRAY)])
|
if isinstance(ln, list):
|
||||||
text(slide, x + 0.3, y + 0.22, w - 0.45, h - 0.4, runs, space=4)
|
runs.append(ln)
|
||||||
|
else:
|
||||||
|
runs.append([("▪ ", lsize - 1, True, accent), (ln, lsize, False, GRAY)])
|
||||||
|
text(slide, x + 0.34, y + 0.66, w - 0.58, h - 0.82, runs, space=4)
|
||||||
|
|
||||||
|
|
||||||
def codebox(slide, x, y, w, h, title, code_lines):
|
def codebox(slide, x, y, w, h, title, code_lines):
|
||||||
box(slide, x, y, w, h, fill=CARD, line=RGBColor(0xDD, 0xE6, 0xF2), line_w=0.75, round_=True)
|
"""제목 + 다크 코드 블록 카드."""
|
||||||
box(slide, x, y, 0.12, h, fill=NAVY)
|
box(slide, x, y, w, h, fill=CARD, line=GRID, line_w=0.75, round_=True)
|
||||||
text(slide, x + 0.3, y + 0.15, w - 0.5, 0.4, [[(title, 14, True, INK)]])
|
box(slide, x, y, 0.1, h, fill=NAVY)
|
||||||
runs = [[(ln, 12.5, False, RGBColor(0x1C, 0x3D, 0x91), "Consolas")] for ln in code_lines]
|
icon_circle(slide, x + 0.26, y + 0.15, 0.36, "▸", fill=NAVY, size=12)
|
||||||
text(slide, x + 0.3, y + 0.6, w - 0.5, h - 0.75, runs, space=3)
|
text(slide, x + 0.74, y + 0.13, w - 0.92, 0.4, [[(title, 13.5, True, INK)]])
|
||||||
|
ch = h - 0.72
|
||||||
|
box(slide, x + 0.3, y + 0.56, w - 0.6, ch, fill=DARK, round_=True)
|
||||||
|
runs = [[("▸ ", 12.5, True, SKY), (ln, 12.5, True, WHITE)] for ln in code_lines]
|
||||||
|
text(slide, x + 0.58, y + 0.56, w - 1.1, ch, runs, anchor=MSO_ANCHOR.MIDDLE, space=3)
|
||||||
|
|
||||||
|
|
||||||
|
def table_head(slide, x, y, col_ws, labels, h=0.5):
|
||||||
|
box(slide, x, y, sum(col_ws), h, fill=NAVY)
|
||||||
|
cx = x
|
||||||
|
for w, lab in zip(col_ws, labels):
|
||||||
|
if lab:
|
||||||
|
text(slide, cx + 0.16, y, w - 0.24, h, [[(lab, 12.5, True, WHITE)]],
|
||||||
|
anchor=MSO_ANCHOR.MIDDLE)
|
||||||
|
cx += w
|
||||||
|
|
||||||
|
|
||||||
|
def table_row(slide, x, y, col_ws, cells, h, zebra=False):
|
||||||
|
box(slide, x, y, sum(col_ws), h, fill=(ZEBRA if zebra else WHITE), line=GRID, line_w=0.5)
|
||||||
|
cx = x
|
||||||
|
for w, cell in zip(col_ws, cells):
|
||||||
|
if cell:
|
||||||
|
text(slide, cx + 0.16, y, w - 0.26, h, cell, anchor=MSO_ANCHOR.MIDDLE, space=2)
|
||||||
|
cx += w
|
||||||
|
cx = x
|
||||||
|
for w in col_ws[:-1]:
|
||||||
|
cx += w
|
||||||
|
box(slide, cx, y, 0.014, h, fill=GRID)
|
||||||
|
|
||||||
|
|
||||||
|
def chevrons(slide, y, items, current=None, x=0.6, total_w=12.13, h=0.55, gap=0.08):
|
||||||
|
"""스텝 진행 도형. current 지정 시 완료=NAVY/현재=BLUE/예정=LIGHT, 미지정 시 전체 NAVY."""
|
||||||
|
n = len(items); w = (total_w - gap * (n - 1)) / n
|
||||||
|
for i, lab in enumerate(items):
|
||||||
|
if current is None:
|
||||||
|
fill, fg = NAVY, WHITE
|
||||||
|
elif i == current:
|
||||||
|
fill, fg = BLUE, WHITE
|
||||||
|
elif i < current:
|
||||||
|
fill, fg = NAVY, WHITE
|
||||||
|
else:
|
||||||
|
fill, fg = LIGHT, GRAY
|
||||||
|
shp = slide.shapes.add_shape(MSO_SHAPE.CHEVRON, Inches(x + i * (w + gap)),
|
||||||
|
Inches(y), Inches(w), Inches(h))
|
||||||
|
shp.shadow.inherit = False
|
||||||
|
shp.fill.solid(); shp.fill.fore_color.rgb = fill
|
||||||
|
shp.line.fill.background()
|
||||||
|
shape_text(shp, lab, 11.5, True, fg)
|
||||||
|
|
||||||
|
|
||||||
|
def stat(slide, x, y, w, h, num, label, accent=BLUE):
|
||||||
|
box(slide, x, y, w, h, fill=CARD, line=GRID, line_w=0.75, round_=True)
|
||||||
|
text(slide, x, y + 0.06, w, 0.42, [[(num, 19, True, accent)]], align=PP_ALIGN.CENTER)
|
||||||
|
text(slide, x, y + 0.46, w, 0.3, [[(label, 10.5, True, GRAY)]], align=PP_ALIGN.CENTER)
|
||||||
|
|
||||||
|
|
||||||
|
STEPS = ["STEP 1 · 마켓플레이스 등록", "STEP 2 · 설치 + 리로드", "STEP 3 · 설치 검증"]
|
||||||
|
|
||||||
# ── 1. 타이틀 ────────────────────────────────────────────────────────
|
# ── 1. 타이틀 ────────────────────────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK)
|
s = prs.slides.add_slide(BLANK)
|
||||||
box(s, 0, 0, 13.333, 7.5, fill=NAVY)
|
box(s, 0, 0, 13.333, 7.5, fill=NAVY)
|
||||||
box(s, 0, 0, 0.25, 7.5, fill=BLUE)
|
box(s, 0, 0, 0.25, 7.5, fill=BLUE)
|
||||||
box(s, 0.25, 0, 0.1, 7.5, fill=SKY)
|
box(s, 0.25, 0, 0.1, 7.5, fill=SKY)
|
||||||
if os.path.exists(BANNER):
|
if os.path.exists(BANNER):
|
||||||
try: s.shapes.add_picture(BANNER, Inches(7.6), Inches(0.7), height=Inches(2.4))
|
try: s.shapes.add_picture(BANNER, Inches(8.15), Inches(0.55), height=Inches(2.3))
|
||||||
except Exception: pass
|
except Exception: pass
|
||||||
text(s, 0.9, 2.1, 10.5, 2.4, [
|
text(s, 0.9, 1.75, 7.2, 2.2, [
|
||||||
[("사내전용 설치가이드", 52, True, WHITE)],
|
[("사내전용 설치가이드", 50, True, WHITE)],
|
||||||
[("ythong 마켓플레이스 · zioinfo 통합 플러그인 v2.1.0", 21, True, SKY)],
|
[("ythong 마켓플레이스 · zioinfo 통합 플러그인 v2.1.0", 20, True, SKY)],
|
||||||
|
[("ZIO INFOTECH Suite — 4개 트랙 · 에이전트 16 · 스킬 8 · 커맨드 3", 14, False, RGBColor(0xCF, 0xE4, 0xF5))],
|
||||||
], space=10)
|
], space=10)
|
||||||
text(s, 0.95, 4.6, 11.4, 1.6, [
|
bar = box(s, 0.9, 4.3, 11.53, 0.95, fill=DARK, line=SKY, line_w=1.0, round_=True)
|
||||||
[("ZIO INFOTECH Suite — 풀스택 개발 · 하네스 팩토리 · 제안서 · PM·PMO 4개 트랙 통합", 16, True, RGBColor(0xCF, 0xE4, 0xF5))],
|
text(s, 1.25, 4.3, 10.9, 0.95, [
|
||||||
[("설치 2줄이면 끝 — /plugin install zioinfo@ythong → /reload-plugins", 14, False, RGBColor(0xB9, 0xCD, 0xE6))],
|
[("▸ ", 16, True, SKY), ("/plugin install zioinfo@ythong", 16, True, WHITE),
|
||||||
], space=8)
|
(" → ", 14, True, STEEL), ("/reload-plugins", 16, True, WHITE),
|
||||||
text(s, 0.95, 6.5, 11, 0.5, [[("ZIO INFOTECH · 사내 배포용 · 외부 공유 금지", 11, False, RGBColor(0x8A, 0x9F, 0xC0))]])
|
(" 설치 2줄이면 끝", 13, False, SKY)],
|
||||||
|
], anchor=MSO_ANCHOR.MIDDLE)
|
||||||
|
chips = ["① 풀스택 개발 (zio-harness)", "② 하네스 팩토리", "③ 제안서 자동완성", "④ PM·PMO · LLM wiki"]
|
||||||
|
cw = (11.53 - 3 * 0.13) / 4
|
||||||
|
for i, c in enumerate(chips):
|
||||||
|
chip(s, 0.9 + i * (cw + 0.13), 5.6, cw, 0.6, c, RGBColor(0x1F, 0x4A, 0x9E), fg=WHITE, size=11.5, line=SKY)
|
||||||
|
text(s, 0.9, 6.55, 11.5, 0.5, [[("ZIO INFOTECH · 사내 배포용 · 외부 공유 금지", 11, False, RGBColor(0x8A, 0x9F, 0xC0))]])
|
||||||
|
|
||||||
# ── 2. 개요: 무엇이 설치되나 ─────────────────────────────────────────
|
# ── 2. 개요: 무엇이 설치되나 (표 + 통계 스트립) ──────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "무엇이 설치되나 — zioinfo 통합 플러그인 (4개 트랙)", "OVERVIEW", 2)
|
s = prs.slides.add_slide(BLANK); header(s, "무엇이 설치되나 — zioinfo 통합 플러그인 (4개 트랙)", "OVERVIEW", 2)
|
||||||
|
col_ws = [0.75, 2.35, 2.75, 6.28]
|
||||||
|
table_head(s, 0.6, 1.42, col_ws, ["", "트랙", "진입점 · 트리거", "무엇을 해주나"], h=0.5)
|
||||||
rows = [
|
rows = [
|
||||||
("풀스택 개발", "zio-harness 스킬", "React + Spring Boot + Mobile 6인 팀 — hermes(전령)는 4대 특징 탑재: memory·skill 자가축적·cron·External APIs"),
|
("1", BLUE, "풀스택 개발", "zio-harness 스킬\n\"기능 추가해줘\"",
|
||||||
("하네스 팩토리", "harness 스킬", "메타 스킬 — 도메인 한 문장을 에이전트 팀 + 스킬로 자동 생성"),
|
[[("React + Spring Boot + Mobile 6인 팀 — analyst→designer→agent→bot→hermes", 11, False, GRAY)],
|
||||||
("제안서", "/zioinfo:proposal", "RFP + PPT 템플릿 → 제안서 자동 완성 (전문가 7인 + 아키텍처 풀)"),
|
[("hermes 4대 특징: ", 11, True, INK), ("memory · skill 자가축적 · cron · External APIs(Gitea·webhook)", 11, False, GRAY)]]),
|
||||||
("PM·PMO", "/zioinfo:pmo", "계획/WBS·리스크·보고(EVM)·감리·포트폴리오·AI 의뢰서 (8인) + LLM wiki(/zioinfo:wiki)"),
|
("2", NAVY, "하네스 팩토리", "harness 스킬\n\"하네스 구성해줘\"",
|
||||||
|
[[("도메인 한 문장 → 에이전트 팀 + 스킬 + CLAUDE.md 자동 생성", 11, False, GRAY)],
|
||||||
|
[("6개 팀 아키텍처 패턴(파이프라인·전문가 풀·감독자 등) 중 자동 선택", 11, False, GRAY)]]),
|
||||||
|
("3", SKY, "제안서", "/zioinfo:proposal\n\"제안서 작성해줘\"",
|
||||||
|
[[("RFP + PPT 디자인 템플릿 → 제안서 자동완성 (SI·SM 주력)", 11, False, GRAY)],
|
||||||
|
[("전문가 7인 + 아키텍처 풀 · PPTX 빌드 스크립트(inspect_template·build_deck)", 11, False, GRAY)]]),
|
||||||
|
("4", STEEL, "PM · PMO", "/zioinfo:pmo\n/zioinfo:wiki",
|
||||||
|
[[("계획(WBS·M/M) → 리스크 → 진척보고(EVM) → 감리 대응 → 포트폴리오 (8인)", 11, False, GRAY)],
|
||||||
|
[("LLM wiki(/zioinfo:wiki) · graphify 지식그래프 SessionStart 자동 분석", 11, False, GRAY)]]),
|
||||||
]
|
]
|
||||||
y = 1.6
|
y = 1.92
|
||||||
for name, ver, desc in rows:
|
for i, (num, accent, track, entry, desc) in enumerate(rows):
|
||||||
box(s, 0.6, y, 12.1, 1.05, fill=CARD, line=RGBColor(0xDD, 0xE6, 0xF2), line_w=0.75, round_=True)
|
entry_runs = [[(ln, 11, True, BLUE)] for ln in entry.split("\n")]
|
||||||
box(s, 0.6, y, 0.12, 1.05, fill=BLUE)
|
table_row(s, 0.6, y, col_ws, [None, [[(track, 13.5, True, INK)]], entry_runs, desc],
|
||||||
text(s, 0.95, y + 0.1, 2.9, 0.5, [[(name, 16, True, INK)]])
|
h=1.02, zebra=(i % 2 == 1))
|
||||||
text(s, 0.95, y + 0.58, 2.9, 0.4, [[(ver, 11, True, BLUE)]])
|
icon_circle(s, 0.6 + (0.75 - 0.42) / 2, y + (1.02 - 0.42) / 2, 0.42, num, fill=accent, size=14)
|
||||||
text(s, 4.0, y, 8.5, 1.05, [[(desc, 12.5, False, GRAY)]], anchor=MSO_ANCHOR.MIDDLE)
|
y += 1.02
|
||||||
y += 1.22
|
stats = [("8", "스킬", BLUE), ("16", "에이전트", NAVY), ("3", "커맨드", SKY), ("1", "SessionStart 훅", BLUE), ("1", "ZIO WISE 테마", STEEL)]
|
||||||
|
sw = (12.13 - 4 * 0.13) / 5
|
||||||
|
for i, (num, lab, accent) in enumerate(stats):
|
||||||
|
stat(s, 0.6 + i * (sw + 0.13), 6.14, sw, 0.78, num, lab, accent)
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 3. 사전 준비 ─────────────────────────────────────────────────────
|
# ── 3. 사전 준비 ─────────────────────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "사전 준비", "PREREQUISITES", 3)
|
s = prs.slides.add_slide(BLANK); header(s, "사전 준비", "PREREQUISITES", 3)
|
||||||
card(s, 0.6, 1.6, 5.95, 2.3, "필수", [
|
card(s, 0.6, 1.42, 5.95, 2.2, "필수", [
|
||||||
"Claude Code v2.x 이상 (claude --version)",
|
"Claude Code v2.x 이상 — claude --version 으로 확인",
|
||||||
"사내 Gitea 접근 가능 (git.zioinfo.co.kr)",
|
"사내 Gitea 접근 가능 (git.zioinfo.co.kr)",
|
||||||
"git 클라이언트 설치",
|
"git 클라이언트 설치",
|
||||||
], accent=NAVY, tsize=16)
|
"(권장) SSH 키 ~/.ssh/id_ed25519 를 Gitea 계정에 등록",
|
||||||
card(s, 6.8, 1.6, 5.95, 2.3, "선택 (기능별)", [
|
], accent=NAVY, tsize=15, glyph="✓")
|
||||||
|
card(s, 6.78, 1.42, 5.95, 2.2, "선택 (기능별)", [
|
||||||
"Agent Teams 팀 모드: CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1",
|
"Agent Teams 팀 모드: CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1",
|
||||||
"제안서 트랙 PPTX 생성: pip install python-pptx",
|
"제안서 트랙 PPTX 생성: pip install python-pptx",
|
||||||
"지식그래프·LLM wiki: graphify (훅이 자동 설치, 끄기 ZIO_HARNESS_NO_GRAPHIFY=1)",
|
"지식그래프·LLM wiki: graphify — SessionStart 훅이 자동 설치",
|
||||||
], accent=BLUE, tsize=16)
|
"끄기 스위치: ZIO_HARNESS_NO_GRAPHIFY=1",
|
||||||
card(s, 0.6, 4.15, 12.15, 2.1, "권한·보안 안내", [
|
], accent=BLUE, tsize=15, glyph="+")
|
||||||
|
card(s, 0.6, 3.77, 12.13, 1.95, "권한 · 보안 안내", [
|
||||||
"마켓플레이스는 사내 Gitea 저장소(ythong/harness) 기준 — 외부 공개 저장소 아님",
|
"마켓플레이스는 사내 Gitea 저장소(ythong/harness) 기준 — 외부 공개 저장소 아님",
|
||||||
"플러그인 산출물에 자격증명·내부 IP 기재 금지 (하네스 공통 보안 원칙)",
|
"플러그인 산출물에 자격증명·내부 IP 기재 금지 (하네스 공통 보안 원칙)",
|
||||||
"설치 범위는 기본 user scope — 개인 PC 단위로 설치·관리",
|
"설치 범위는 기본 user scope — 개인 PC 단위 설치·관리 · hermes webhook URL은 /plugin configure 로만 입력",
|
||||||
], accent=SKY, tsize=16)
|
], accent=AMBER, tsize=15, glyph="!")
|
||||||
|
codebox(s, 0.6, 5.85, 12.13, 1.05, "환경 확인 한 줄 (전부 통과하면 준비 끝)", [
|
||||||
|
"claude --version ; git --version ; ssh -T git@git.zioinfo.co.kr",
|
||||||
|
])
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 4. STEP 1: 마켓플레이스 등록 ─────────────────────────────────────
|
# ── 4. STEP 1: 마켓플레이스 등록 ─────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "STEP 1 — 마켓플레이스 등록 (최초 1회)", "INSTALL", 4)
|
s = prs.slides.add_slide(BLANK); header(s, "STEP 1 — 마켓플레이스 등록 (최초 1회)", "INSTALL", 4)
|
||||||
codebox(s, 0.6, 1.6, 12.1, 1.7, "Claude Code 세션 안에서", [
|
chevrons(s, 1.36, STEPS, current=0)
|
||||||
|
codebox(s, 0.6, 2.1, 12.13, 1.3, "Claude Code 세션 안에서", [
|
||||||
"/plugin marketplace add https://git.zioinfo.co.kr/ythong/harness.git",
|
"/plugin marketplace add https://git.zioinfo.co.kr/ythong/harness.git",
|
||||||
])
|
])
|
||||||
codebox(s, 0.6, 3.5, 12.1, 1.7, "또는 터미널에서", [
|
codebox(s, 0.6, 3.52, 12.13, 1.3, "또는 터미널에서 (PowerShell·bash 동일)", [
|
||||||
"claude plugin marketplace add https://git.zioinfo.co.kr/ythong/harness.git",
|
"claude plugin marketplace add https://git.zioinfo.co.kr/ythong/harness.git",
|
||||||
])
|
])
|
||||||
text(s, 0.6, 5.5, 12.1, 1.2, [
|
card(s, 0.6, 4.97, 5.95, 1.9, "주의 — URL 끝 .git 필수", [
|
||||||
[("⚠ 비-GitHub git 저장소는 URL 끝에 ", 13, False, GRAY), (".git 필수", 13, True, NAVY),
|
"비-GitHub git 저장소는 .git 없으면 등록 실패",
|
||||||
(" — 없으면 \"expected object, received string\" 오류", 13, False, GRAY)],
|
"\"expected object, received string\" 오류 시 URL 재확인",
|
||||||
[("→ 성공 메시지: Successfully added marketplace: ythong", 12.5, False, BLUE)],
|
], accent=AMBER, tsize=14, glyph="!")
|
||||||
], space=6)
|
card(s, 6.78, 4.97, 5.95, 1.9, "성공 확인", [
|
||||||
|
[("▪ ", 10.5, True, BLUE), ("Successfully added marketplace: ythong", 11.5, True, INK)],
|
||||||
|
"/plugin marketplace list 로 등록 상태 재확인",
|
||||||
|
], accent=BLUE, tsize=14, glyph="✓")
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 5. STEP 2: 플러그인 설치 ─────────────────────────────────────────
|
# ── 5. STEP 2: 플러그인 설치 ─────────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "STEP 2 — 플러그인 설치 + 리로드", "INSTALL", 5)
|
s = prs.slides.add_slide(BLANK); header(s, "STEP 2 — 플러그인 설치 + 리로드", "INSTALL", 5)
|
||||||
codebox(s, 0.6, 1.6, 12.1, 2.0, "설치는 하나면 끝 (세션 안 2줄)", [
|
chevrons(s, 1.36, STEPS, current=1)
|
||||||
|
codebox(s, 0.6, 2.1, 12.13, 1.5, "설치는 하나면 끝 (세션 안 2줄)", [
|
||||||
"/plugin install zioinfo@ythong",
|
"/plugin install zioinfo@ythong",
|
||||||
"/reload-plugins",
|
"/reload-plugins",
|
||||||
])
|
])
|
||||||
text(s, 0.6, 3.75, 12.1, 1.5, [
|
card(s, 0.6, 3.75, 3.955, 1.65, "구버전 정리 (4→1 통합)", [
|
||||||
[("구버전 4개(harness·zio-harness·proposal-builder·구 zioinfo)를 쓰던 PC는 먼저 ", 12.5, False, GRAY),
|
"구 4개 플러그인 사용 PC는 재설치 전",
|
||||||
("claude plugin uninstall <이름>@ythong", 12.5, True, NAVY), (" 으로 제거", 12.5, False, GRAY)],
|
"claude plugin uninstall <이름>@ythong",
|
||||||
[("(선택) hermes 전달 완료 webhook 알림: ", 12.5, False, GRAY),
|
], accent=AMBER, tsize=13, glyph="!", lsize=10.5)
|
||||||
("/plugin configure zioinfo@ythong", 12.5, True, NAVY),
|
card(s, 4.685, 3.75, 3.955, 1.65, "webhook 알림 (선택)", [
|
||||||
(" 에서 notify_webhook_url 입력 — 비워두면 알림만 생략", 12.5, False, GRAY)],
|
"/plugin configure zioinfo@ythong",
|
||||||
], space=6)
|
"notify_webhook_url 입력 — 비우면 알림만 생략",
|
||||||
text(s, 0.6, 4.8, 12.1, 1.6, [
|
], accent=SKY, tsize=13, glyph="+", lsize=10.5)
|
||||||
[("설치 후 ", 13.5, False, GRAY), ("/reload-plugins", 13.5, True, NAVY),
|
card(s, 8.77, 3.75, 3.955, 1.65, "즉시 반영", [
|
||||||
(" 한 번이면 현재 세션에 즉시 반영 (재시작 불필요)", 13.5, False, GRAY)],
|
"/reload-plugins 한 번이면 현재 세션 반영",
|
||||||
[("→ 성공 메시지: Successfully installed plugin: <이름>@ythong (scope: user)", 12.5, False, BLUE)],
|
"Claude Code 재시작 불필요",
|
||||||
], space=6)
|
], accent=NAVY, tsize=13, glyph="▸", lsize=10.5)
|
||||||
|
card(s, 0.6, 5.55, 12.13, 1.32, "성공 메시지", [
|
||||||
|
[("▪ ", 11, True, BLUE), ("Successfully installed plugin: zioinfo@ythong (scope: user)", 12, True, INK),
|
||||||
|
(" — 커맨드 자동완성에 /zioinfo:pmo 가 보이면 로드 완료", 11.5, False, GRAY)],
|
||||||
|
], accent=BLUE, tsize=14, glyph="✓")
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 6. STEP 3: 설치 검증 ─────────────────────────────────────────────
|
# ── 6. STEP 3: 설치 검증 ─────────────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "STEP 3 — 설치 검증", "VERIFY", 6)
|
s = prs.slides.add_slide(BLANK); header(s, "STEP 3 — 설치 검증", "VERIFY", 6)
|
||||||
codebox(s, 0.6, 1.6, 5.95, 2.2, "설치 목록·상태", [
|
chevrons(s, 1.36, STEPS, current=2)
|
||||||
|
codebox(s, 0.6, 2.1, 5.95, 1.45, "설치 목록·상태", [
|
||||||
"claude plugin list",
|
"claude plugin list",
|
||||||
])
|
])
|
||||||
codebox(s, 6.8, 1.6, 5.95, 2.2, "컴포넌트 인벤토리", [
|
codebox(s, 6.78, 2.1, 5.95, 1.45, "컴포넌트 인벤토리", [
|
||||||
"claude plugin details zioinfo@ythong",
|
"claude plugin details zioinfo@ythong",
|
||||||
])
|
])
|
||||||
card(s, 0.6, 4.1, 12.15, 2.2, "정상 판정 기준 (zioinfo v2.1.0 실측)", [
|
col_ws6 = [2.3, 9.83]
|
||||||
"Skills (8): harness·hermes-delivery·pm-pmo-orchestrator·pmo·proposal·proposal-builder-orchestrator·wiki·zio-harness",
|
table_head(s, 0.6, 3.7, col_ws6, ["항목", "정상 판정 기준 (zioinfo v2.1.0 실측)"], h=0.48)
|
||||||
"Agents (16): hermes(전령) + proposal 7 + pm·pmo 8 / Hooks (1): SessionStart graphify / 오류 0",
|
verify_rows = [
|
||||||
"세션에서 /zioinfo:pmo 커맨드가 자동완성에 보이면 로드 완료",
|
("Skills 8", [[("harness · hermes-delivery · pm-pmo-orchestrator · pmo · proposal · proposal-builder-orchestrator · wiki · zio-harness", 11, False, GRAY)]]),
|
||||||
], accent=BLUE, tsize=16)
|
("Agents 16\nHooks 1", [[("hermes(전령) + proposal 7인 + pm·pmo 8인 / SessionStart graphify 훅 / 오류 0", 11, False, GRAY)]]),
|
||||||
|
("커맨드 3", [[("/zioinfo:pmo · /zioinfo:proposal · /zioinfo:wiki — 세션 자동완성에 보이면 로드 완료", 11, False, GRAY)]]),
|
||||||
|
]
|
||||||
|
y = 4.18
|
||||||
|
for i, (item, desc) in enumerate(verify_rows):
|
||||||
|
item_runs = [[(" " + ln, 12, True, NAVY)] for ln in item.split("\n")]
|
||||||
|
table_row(s, 0.6, y, col_ws6, [item_runs, desc], h=0.88, zebra=(i % 2 == 1))
|
||||||
|
icon_circle(s, 0.72, y + (0.88 - 0.3) / 2, 0.3, "✓", fill=BLUE, size=10)
|
||||||
|
y += 0.88
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 7. 플러그인별 사용법 ─────────────────────────────────────────────
|
# ── 7. 설치 후 바로 쓰기 ─────────────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "설치 후 바로 쓰기 — 트리거 한 마디", "USAGE", 7)
|
s = prs.slides.add_slide(BLANK); header(s, "설치 후 바로 쓰기 — 트리거 한 마디", "USAGE", 7)
|
||||||
card(s, 0.6, 1.55, 5.95, 2.45, "풀스택 개발 (zio-harness 트랙)", [
|
if os.path.exists(TEAM):
|
||||||
"\"기능 추가해줘\" · \"push하고 배포 확인해줘\" · \"매주 릴리즈 노트 예약\"",
|
try:
|
||||||
"→ 분석→디자인→구현→검증→전달(hermes: memory·cron·webhook)",
|
s.shapes.add_picture(TEAM, Inches(0.6), Inches(1.42), width=Inches(4.6))
|
||||||
], accent=BLUE, tsize=16)
|
except Exception: pass
|
||||||
card(s, 6.8, 1.55, 5.95, 2.45, "하네스 팩토리 (harness 트랙)", [
|
text(s, 0.6, 4.02, 4.6, 0.45, [
|
||||||
|
[("zio-harness 6인 파이프라인", 11, True, INK)],
|
||||||
|
[("analyst→designer→agent→bot→hermes", 10, False, GRAY)],
|
||||||
|
], align=PP_ALIGN.CENTER, space=1)
|
||||||
|
card(s, 5.45, 1.42, 7.28, 2.98, "풀스택 개발 (zio-harness 트랙)", [
|
||||||
|
"\"기능 추가해줘\" · \"버그 수정해줘\" · \"코드 분석해줘\" — 한 마디로 팀 가동",
|
||||||
|
"\"push하고 배포 확인해줘\" → hermes가 Gitea push·배포 확인·릴리즈 노트",
|
||||||
|
"\"매주 릴리즈 노트 예약해줘\" → cron 정기작업 + webhook 알림",
|
||||||
|
"\"PROJECT_MAP 업데이트해줘\" · Playwright E2E · DB MCP 작업",
|
||||||
|
"파이프라인: 분석 → 디자인(UI 시) → 구현 → 검증(bot PASS 게이트) → 전달",
|
||||||
|
], accent=BLUE, tsize=15, glyph="▸")
|
||||||
|
card(s, 0.6, 4.55, 3.955, 2.3, "하네스 팩토리", [
|
||||||
"\"이 프로젝트용 하네스 구성해줘\"",
|
"\"이 프로젝트용 하네스 구성해줘\"",
|
||||||
"→ 에이전트 팀 + 스킬 + CLAUDE.md 자동 생성",
|
"에이전트 팀 + 스킬 + CLAUDE.md 자동 생성",
|
||||||
], accent=NAVY, tsize=16)
|
"6개 팀 아키텍처 패턴 중 자동 선택",
|
||||||
card(s, 0.6, 4.25, 5.95, 2.45, "제안서 (/zioinfo:proposal)", [
|
], accent=NAVY, tsize=13.5, glyph="▸", lsize=10.5)
|
||||||
"/zioinfo:proposal ○○사업 제안서 또는 \"제안서 작성해줘\"",
|
card(s, 4.685, 4.55, 3.955, 2.3, "제안서", [
|
||||||
"→ RFP 분석→전략→아키텍처→본문→PPTX→QA",
|
"/zioinfo:proposal ○○사업 제안서",
|
||||||
], accent=SKY, tsize=16)
|
"RFP 분석→전략→아키텍처→본문→PPTX→QA",
|
||||||
card(s, 6.8, 4.25, 5.95, 2.45, "PM·PMO + LLM wiki", [
|
"시스템 구축(SI)·유지보수(SM) 제안 주력",
|
||||||
"/zioinfo:pmo 프로젝트 계획 · 주간보고 · 감리 준비",
|
], accent=SKY, tsize=13.5, glyph="▸", lsize=10.5)
|
||||||
"/zioinfo:wiki → graphify-out/wiki/ 코드베이스 위키 생성",
|
card(s, 8.77, 4.55, 3.955, 2.3, "PM·PMO + LLM wiki", [
|
||||||
], accent=STEEL, tsize=16)
|
"/zioinfo:pmo 프로젝트 계획·주간보고·감리",
|
||||||
|
"/zioinfo:wiki → graphify-out/wiki/ 코드 위키",
|
||||||
|
"AI 의뢰서(스티치 design.md·젠스파크) 생성",
|
||||||
|
], accent=STEEL, tsize=13.5, glyph="▸", lsize=10.5)
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 8. 업데이트 · 제거 ───────────────────────────────────────────────
|
# ── 8. 업데이트 · 제거 ───────────────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "업데이트 · 제거", "MAINTAIN", 8)
|
s = prs.slides.add_slide(BLANK); header(s, "업데이트 · 제거", "MAINTAIN", 8)
|
||||||
codebox(s, 0.6, 1.6, 5.95, 2.6, "업데이트 (마켓플레이스 갱신 후 재설치)", [
|
codebox(s, 0.6, 1.42, 5.95, 2.0, "업데이트 (마켓플레이스 갱신 후 재설치)", [
|
||||||
"claude plugin marketplace update ythong",
|
"claude plugin marketplace update ythong",
|
||||||
"claude plugin install zioinfo@ythong",
|
"claude plugin install zioinfo@ythong",
|
||||||
"/reload-plugins",
|
"/reload-plugins",
|
||||||
])
|
])
|
||||||
codebox(s, 6.8, 1.6, 5.95, 2.6, "제거", [
|
codebox(s, 6.78, 1.42, 5.95, 2.0, "제거", [
|
||||||
"claude plugin uninstall zioinfo@ythong",
|
"claude plugin uninstall zioinfo@ythong",
|
||||||
|
"claude plugin marketplace remove ythong (선택)",
|
||||||
])
|
])
|
||||||
card(s, 0.6, 4.5, 12.15, 1.9, "버전 정책", [
|
chevrons(s, 3.6, ["marketplace update", "install zioinfo", "/reload-plugins", "plugin list 확인"], h=0.55)
|
||||||
"플러그인 버전은 저장소 plugin.json이 진실원천 (Semantic Versioning)",
|
card(s, 0.6, 4.35, 5.95, 2.5, "버전 정책", [
|
||||||
"변경 이력은 저장소 CLAUDE.md 하네스 섹션·CHANGELOG 참조",
|
"plugins/zioinfo/.claude-plugin/plugin.json 이 버전 진실원천",
|
||||||
], accent=BLUE, tsize=16)
|
"Semantic Versioning — 현재 v2.1.0 (hermes 4대 특징)",
|
||||||
|
"marketplace.json 버전은 plugin.json과 동기 유지",
|
||||||
|
], accent=BLUE, tsize=14, glyph="✓")
|
||||||
|
card(s, 6.78, 4.35, 5.95, 2.5, "변경 이력 · 문의", [
|
||||||
|
"변경 이력: 저장소 CLAUDE.md 하네스 섹션 참조",
|
||||||
|
"카탈로그: docs/plugins.md",
|
||||||
|
"설치 문서: plugins/zioinfo/docs/INSTALL.md",
|
||||||
|
"문의: ZIO INFOTECH 인프라팀",
|
||||||
|
], accent=NAVY, tsize=14, glyph="▸")
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 9. 트러블슈팅 ────────────────────────────────────────────────────
|
# ── 9. 트러블슈팅 (표) ───────────────────────────────────────────────
|
||||||
s = prs.slides.add_slide(BLANK); header(s, "트러블슈팅", "FAQ", 9)
|
s = prs.slides.add_slide(BLANK); header(s, "트러블슈팅", "FAQ", 9)
|
||||||
|
col_ws9 = [4.35, 7.78]
|
||||||
|
table_head(s, 0.6, 1.42, col_ws9, ["증상", "원인 · 조치"], h=0.5)
|
||||||
rows = [
|
rows = [
|
||||||
("plugin not found", "마켓플레이스 add 여부 확인 → /plugin marketplace add ... (.git 포함)"),
|
("plugin not found", "마켓플레이스 add 여부 확인 → /plugin marketplace add ... (.git 포함)"),
|
||||||
("expected object, received string", "비-GitHub git URL에 .git 누락 — URL 끝에 .git을 붙여 재시도"),
|
("expected object, received string", "비-GitHub git URL에 .git 누락 — URL 끝에 .git 붙여 재시도"),
|
||||||
("invalid manifest", "plugins/<이름>/.claude-plugin/plugin.json 존재·JSON 유효성 확인 (BOM 없는 UTF-8)"),
|
("invalid manifest", "plugins/zioinfo/.claude-plugin/plugin.json 존재·JSON 유효성 확인 (BOM 없는 UTF-8)"),
|
||||||
("설치했는데 커맨드가 안 보임", "/reload-plugins 실행 또는 세션 재시작"),
|
("설치했는데 커맨드가 안 보임", "/reload-plugins 실행 또는 세션 재시작"),
|
||||||
("스킬이 트리거되지 않음", "명시적 표현 사용(\"제안서 작성\", \"프로젝트 계획\") 또는 /zioinfo:proposal·/zioinfo:pmo 직접 호출"),
|
("스킬이 트리거되지 않음", "명시적 표현 사용(\"제안서 작성\", \"프로젝트 계획\") 또는 /zioinfo:proposal·pmo 직접 호출"),
|
||||||
("팀 모드가 동작 안 함", "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 환경변수 확인"),
|
("팀 모드가 동작 안 함", "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 환경변수 확인"),
|
||||||
]
|
]
|
||||||
y = 1.5
|
y = 1.92
|
||||||
for prob, fix in rows:
|
for i, (prob, fix) in enumerate(rows):
|
||||||
box(s, 0.6, y, 12.1, 0.82, fill=CARD, line=RGBColor(0xDD, 0xE6, 0xF2), line_w=0.75, round_=True)
|
table_row(s, 0.6, y, col_ws9,
|
||||||
text(s, 0.85, y, 4.15, 0.82, [[(prob, 12.5, True, NAVY)]], anchor=MSO_ANCHOR.MIDDLE)
|
[[[(" " + prob, 11.5, True, NAVY)]],
|
||||||
text(s, 5.15, y, 7.4, 0.82, [[(fix, 11.5, False, GRAY)]], anchor=MSO_ANCHOR.MIDDLE)
|
[[("→ ", 11, True, BLUE), (fix, 11, False, GRAY)]]],
|
||||||
y += 0.92
|
h=0.82, zebra=(i % 2 == 1))
|
||||||
|
icon_circle(s, 0.74, y + (0.82 - 0.3) / 2, 0.3, "!", fill=AMBER, size=10)
|
||||||
|
y += 0.82
|
||||||
footer(s)
|
footer(s)
|
||||||
|
|
||||||
# ── 10. 마무리 ───────────────────────────────────────────────────────
|
# ── 10. 마무리 ───────────────────────────────────────────────────────
|
||||||
@ -270,13 +437,17 @@ box(s, 0, 0, 13.333, 7.5, fill=NAVY)
|
|||||||
box(s, 0, 0, 13.333, 0.18, fill=BLUE)
|
box(s, 0, 0, 13.333, 0.18, fill=BLUE)
|
||||||
box(s, 0, 7.32, 13.333, 0.18, fill=SKY)
|
box(s, 0, 7.32, 13.333, 0.18, fill=SKY)
|
||||||
if os.path.exists(ICON):
|
if os.path.exists(ICON):
|
||||||
try: s.shapes.add_picture(ICON, Inches(5.85), Inches(0.9), height=Inches(1.7))
|
try: s.shapes.add_picture(ICON, Inches(5.92), Inches(0.75), height=Inches(1.5))
|
||||||
except Exception: pass
|
except Exception: pass
|
||||||
text(s, 0.9, 2.9, 11.5, 2.2, [
|
text(s, 0.9, 2.5, 11.5, 1.6, [
|
||||||
[("설치 2줄, 팀이 도착한다.", 34, True, WHITE)],
|
[("설치 2줄, 팀이 도착한다.", 34, True, WHITE)],
|
||||||
[("/plugin install zioinfo@ythong · /reload-plugins", 18, True, SKY)],
|
], align=PP_ALIGN.CENTER)
|
||||||
], align=PP_ALIGN.CENTER, space=12)
|
bar = box(s, 2.7, 3.6, 7.93, 0.85, fill=DARK, line=SKY, line_w=1.0, round_=True)
|
||||||
text(s, 0.9, 5.4, 11.5, 1.2, [
|
shape_text(bar, "/plugin install zioinfo@ythong · /reload-plugins", 17, True, SKY)
|
||||||
|
cw = (11.53 - 3 * 0.13) / 4
|
||||||
|
for i, c in enumerate(["풀스택 개발 6인 팀", "하네스 팩토리", "제안서 자동완성", "PM·PMO · LLM wiki"]):
|
||||||
|
chip(s, 0.9 + i * (cw + 0.13), 4.9, cw, 0.6, c, RGBColor(0x1F, 0x4A, 0x9E), fg=WHITE, size=12, line=SKY)
|
||||||
|
text(s, 0.9, 5.95, 11.5, 1.1, [
|
||||||
[("문의: ZIO INFOTECH 인프라팀 · 저장소: git.zioinfo.co.kr/ythong/harness", 14, False, RGBColor(0xCF, 0xE4, 0xF5))],
|
[("문의: ZIO INFOTECH 인프라팀 · 저장소: git.zioinfo.co.kr/ythong/harness", 14, False, RGBColor(0xCF, 0xE4, 0xF5))],
|
||||||
[("사내 배포용 · 외부 공유 금지 · Apache-2.0", 12, False, RGBColor(0x9A, 0xAF, 0xD0))],
|
[("사내 배포용 · 외부 공유 금지 · Apache-2.0", 12, False, RGBColor(0x9A, 0xAF, 0xD0))],
|
||||||
], align=PP_ALIGN.CENTER, space=8)
|
], align=PP_ALIGN.CENTER, space=8)
|
||||||
|
|||||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user