
    i*                        d Z ddlZddlZddlZg ddddgfg ddd	dgfg d
dddgfdgdddgfddgdddgfg dddg fddgdddgfddgddg fddgddg fg dddg fddgdddgfd d!gdd"g fd#d$gdd%g fg d&dd'dgfgZdg d(d)fdg d*d+fgZd8d,ed-ed.ed/e	fd0Z
d1ed/efd2Zd3e	d/dfd4Zd/ej                  fd5Zd/efd6Zed7k(  r ej"                   e              yy)9u  
image-skill-router.py
이미지 작업 유형/키워드를 입력받아 최적 이미지 생성 스킬을 추천하는 CLI 도구.

Usage:
    python3 tools/image-skill-router.py --type "광고 배너"
    python3 tools/image-skill-router.py --type "카드뉴스" --json
    python3 tools/image-skill-router.py --type "SNS 메인 이미지" --urgent
    python3 tools/image-skill-router.py --type "인포그래픽" --count 15
    N)u   광고 배너u   meta 배너u   google 배너u   광고 소재hybrid-imageu1   사진 배경 + 정확한 한글 텍스트 필수gemini-image)   카드뉴스   인포그래픽	   비교표
   표/차트   데이터 차트satori-cardnewsu   텍스트 중심, 초고속, $0)   sns 메인 이미지u   sns 홍보 이미지u   sns 이미지   포토리얼   사진 이미지u   포토리얼, 텍스트 최소u   블로그 썸네일u   사진 + 제목 텍스트u!   블로그 대표 이미지+포토u   블로그 대표 이미지)u   a/b 테스트 변형u   대량 생성u   배치u   대량 빠른 생성   프리미엄 브랜딩   브랜드 이미지u   최고 품질 포토리얼u   블로그 텍스트 배너u   블로그 ctau   텍스트 중심u   google 정적 배너150kbu4   벡터 기반 가벼운 파일 (150KB 제한 충족))u   네이버 gfa smart channelu   네이버 gfa smartz	gfa smartzsmart channelu   PNG+150KB 제한 충족u   네이버 gfa feedzgfa feeduH   텍스트 중심일 때 satori 추천 (포토리얼이면 hybrid 고려)u   카카오 비즈보드u   비즈보드u   극도로 좁은 비율 대응u   meta 캐러셀 텍스트u   캐러셀 텍스트u   텍스트 중심 캐러셀)u   meta 캐러셀 포토u   캐러셀 포토u   meta 캐러셀u   포토리얼 배경 필요)r   r   r   r   r   u   satori-cardnews는 포토리얼 배경 생성을 지원하지 않습니다. 배경이 단색/그라데이션으로 제한됩니다.)r   r   r   r   r	   u   데이터 시각화u   정확한 텍스트u   gemini-image는 데이터 시각화 및 정확한 텍스트 렌더링이 어렵습니다. 한글 텍스트 깨짐 위험이 있습니다.	task_typeurgentcountreturnc                 P   | j                         j                         }g }d}d}g }t        D ]'  \  }}	}
}|D ]  }||v s|	}|
}t        |      } n |s' n |sddg ddg| dS t        D ]-  \  }	}}||	k(  s|D ]  }||v s|j                  d|         - / |dk\  r:|dk7  r5|j                  d	| d
|        ||vr|j                  d|       d}d| d}|rE|dk7  r/|j                  d|        ||vr|j                  d|       d}d}n|j                  d       ||||| dS )u  
    작업 유형 문자열을 입력받아 최적 스킬 추천 결과를 반환.

    Args:
        task_type: 이미지 작업 유형 (예: "광고 배너", "카드뉴스")
        urgent: 긴급 플래그. True 시 satori-cardnews 강제
        count: 생성 수량. 10 이상이면 satori-cardnews 강제

    Returns:
        {
            "recommended_skill": str,
            "reason": str,
            "alternatives": list[str],
            "warnings": list[str],
            "input_type": str,
        }
    Nu>   키워드가 라우팅 테이블과 일치하지 않습니다.)r   r
   r   ud   매칭 실패: 수동으로 스킬을 선택하거나 더 구체적인 키워드를 입력하세요.)recommended_skillreasonalternativeswarnings
input_typeu   [금지 규칙 경고] 
   r
   u   [SLA 보호] 수량 uH   개 >= 10개: satori-cardnews로 강제 전환합니다. 원래 추천: r   u   대량 생성 (u)   개) - SLA 보호를 위한 강제 전환ub   [긴급 모드] --urgent 옵션 감지: satori-cardnews로 강제 전환합니다. 원래 추천: u.   긴급 모드 강제 전환 (초고속 생성)uR   [긴급 모드] --urgent 옵션 감지: 이미 satori-cardnews가 추천됩니다.)lowerstripROUTING_TABLElistPROHIBITION_RULESappendinsert)r   r   r   
task_lowerr   matched_skillmatched_reasonmatched_alternativeskeywordsskillr   r   kwdanger_keywordswarning_msgdkws                   I/home/jay/workspace/.worktrees/task-2116-dev1/tools/image-skill-router.pyroute_skillr.      s   $ "((*JHMN 2? -% 	BZ %!''+L'9$	  !%VO  A#
 	
 0A +E!& *$OO&=k]$KL {--OO&ug .""/2 $88$++A}=-M.ug5^_N --OO""/2 $88$++A}=-MMNOOpq + ,     	task_descc                 D    t        |       }|j                  d      }|r|S y)uZ  
    작업 설명에서 키워드를 추출하여 추천 스킬 이름을 반환.
    dispatch.py에서 design 팀 위임 시 프롬프트에 포함할 용도.

    Args:
        task_desc: 자유 형식의 작업 설명 문자열

    Returns:
        추천 스킬 이름 (str). 매칭 실패 시 "hybrid-image" 반환 (안전 기본값).
    r   r   )r.   get)r0   resultrecommendeds      r-   get_skill_recommendationr5      s)     #F**01Kr/   r3   c                 X   | d   }|t        d       t        d| d           nt        d|        t        d| d           | j                  d	g       }|rt        d
dj                  |              nt        d       | j                  dg       }|r|D ]  }t        d|         yy)u6   사람이 읽기 쉬운 형식으로 결과를 출력.r   NuK   ❌ 매칭 실패: 라우팅 테이블에 해당 키워드가 없습니다.u      입력: r   u   ✅ 추천: u   📝 이유: r   r   u   🔄 대안: z, u   🔄 대안: 없음r   u   ⚠️  )printr2   join)r3   r(   r   r   ws        r-   print_human_readabler:      s    &'E}[\F<0123UG$%fX./01::nb1Ldii5678#$zz*b)H 	"AHQC.!	" r/   c                      t        j                  dd      } | j                  ddddd	       | j                  d
ddd       | j                  dt        ddd       | j                  ddddd       | S )Nzimage-skill-routerud   이미지 작업 유형/키워드를 입력받아 최적 이미지 생성 스킬을 추천합니다.)progdescriptionz--typer   T	TASK_TYPEuV   이미지 작업 유형 (예: "광고 배너", "카드뉴스", "SNS 메인 이미지"))destrequiredmetavarhelpz--urgent
store_trueFuB   긴급 플래그: satori-cardnews 강제 전환 (초고속 생성))actiondefaultrB   z--count   NuG   생성 수량. N >= 10이면 satori-cardnews 강제 전환 (SLA 보호))typerE   rA   rB   z--jsonoutput_jsonu7   JSON 형식으로만 출력 (프로그래매틱 사용))r?   rD   rE   rB   )argparseArgumentParseradd_argumentint)parsers    r-   build_parserrO     s    $$!zF e   Q	   V   F   Mr/   c                     t               } | j                         }t        |j                  |j                  |j
                        }|j                  r"t        t        j                  |dd             nt        |       |d   yy)N)r   r   r   F   )ensure_asciiindentr   rF   r   )rO   
parse_argsr.   r   r   r   rI   r7   jsondumpsr:   )rN   argsr3   s      r-   mainrX   1  sr    ^FD..{{jjF djjeA>?V$ !"*r/   __main__)FrF   )__doc__rJ   rU   sysr   r    strboolrM   dictr.   r5   r:   rK   rO   rX   __name__exit r/   r-   <module>rb      s+  	   
 	K;		 	[)		 	n(		 
#		 
-.JK#		 	<
	 
"#89$		 
&7
	 
 )>
	 	]!
	 
z*R		 
">2(
	 
$%:;$
	 	H$		_Ut 	u 	N 	 	I 	T $U3 U US U Ux  ." "$ "4 h--  Fc * zCHHTV r/   