플러그인 설치: 설정 또는 새로고침 명령 전에 이 스킬이 HyperFrames 플러그인 내부에 있을 때는 플러그인 실행 규칙을 따릅니다. 독립 실행형 설치는 아래 업데이트 지침을 유지합니다.
먼저, 이 스킬을 최신 상태로 유지하세요 — 사용자에게 실행 확인 후:
npx hyperframes skills update figma. 모든 것이 최신 상태이면 빠른 no-op입니다. 그렇지 않으면 이 스킬과 이 스킬이 의존하는 핵심 도메인 스킬을 새로고침합니다.
Figma → HyperFrames
사용자의 Figma 작업을 컴포지션으로 가져옵니다. 기능별 분할 (디자인 사양 §2):
| 단계 | 내용 | 전송 방식 | 표면 |
|---|---|---|---|
| 1 | 정적 에셋 | REST | hyperframes figma asset |
| 2 | 브랜드 토큰/스타일 | REST | hyperframes figma tokens |
| 3 | 컴포넌트 → HTML | REST | hyperframes figma component |
| 4 | 모션 → GSAP | 사용 가능 시 커넥터 | 모션 컨텍스트 사용 |
| 5 | 셰이더 | 커넥터 / 수동 내보내기 | 커넥터 또는 네이티브 내보내기 사용 |
REST는 가능한 모든 곳에서 사용됩니다 (대량 처리, 헤드리스). 모션 및 셰이더 데이터에는 호환 가능한 Figma 커넥터가 선택 사항입니다. 없으면 네이티브 내보내기를 요청하세요. 모든 경로는 에셋을 로컬에 프리즈하여 렌더링이 결정론적이도록 보장합니다. 스토리보드 재구성은 에이전트 기반 타임라인 어셈블리와 Phase-1 에셋 내보내기(REST)를 결합합니다 — 커넥터가 필요 없습니다. 기존 프리즈된 에셋, 매니페스트 레코드 및 바인딩은 라우팅 변경의 영향을 받지 않습니다 — 분할은 다음 가져오기에 사용될 자격 증명만 변경합니다.
인증 — 두 개의 자격 증명, 범위 지정
사전 점검 — 첫 번째 CLI 호출 전, 토큰 존재 여부 확인: 셸 환경 변수 ([ -n "$FIGMA_TOKEN" ]) 또는 프로젝트 .env 파일 (CLI가 자동 로드 — .env 항목은 구성된 것으로 간주). 둘 다 없으면 오류를 얻기 위해 명령을 실행하지 말고 먼저 사용자에게 일회성 설정을 안내한 후 중단하고 기다리세요:
- figma.com/settings → Security → Personal access tokens → 새 토큰 생성.
- 범위 — 이 통합에 필요한 것은 읽기 전용입니다 (Figma에 쓰지 않음): File content: Read-only + File metadata: Read-only. Enterprise 플랜이 아닌 경우
tokens를 실행하려면 Library content: Read-only를 추가하세요 — 게시된 스타일 폴백이/v1/files/:key/styles를 호출하는데, 이는 범위가 없으면 403 오류가 발생합니다 (이전 설정 텍스트에서 누락된 범위). 브랜드 변수를 위한 선택적 Variables: Read-only — Enterprise 전용; 없으면tokens가 자동으로 게시된 스타일로 저하됩니다 (예상된 동작, 오류가 아님 — 그렇게 말하세요). 이제 403은 정확히 누락된 범위를 알려주고, 429는 자동으로 재시도합니다 (분당 제한,Retry-After준수). - 사용자가 셸 프로필 또는 프로젝트
.env에FIGMA_TOKEN을 설정하도록 하세요. 대화에 토큰을 붙여넣도록 요청하지 마세요.
온보딩 중에 한 번에 기대치를 설정하세요: 모든 가져오기는 로컬 프리즈 파일과 기록된 출처로 저장됩니다 — 렌더링은 Figma를 호출하지 않으며, 명령을 다시 실행하면 Figma에서 변경된 내용만 다시 가져오며, 하나의 토큰으로 Figma 계정이 볼 수 있는 모든 파일의 에셋, 브랜드 토큰 및 컴포넌트에 대해 작동합니다.
- Phases 4–5 (모션/셰이더): 호환 가능한 Figma 커넥터 (토큰과 별도의 인증 필요). 사용할 수 없거나 인증되지 않은 경우 사용자에게 연결하거나 네이티브 내보내기를 제공하도록 요청한 후 중단하세요.
- 실패하는 단계에 정확히 어떤 자격 증명이 필요한지 말하세요 — 분할이 고장난 것으로 제시하지 마세요.
BAD_TOKEN(401) 흐름 중 → 토큰이 만료/취소되었습니다. 다시 발급받으세요.FORBIDDEN(403) → 메시지에 정확히 누락된 범위 이름이 있습니다 (예: 스타일 폴백의 경우library_content:read) — 추가하거나 파일을 계정에서 볼 수 없습니다.REQUIRES_ENTERPRISE(변수 403) → 실패 아님: 스타일 폴백이 이미 실행되었습니다.RATE_LIMITED(429) → 클라이언트가 이미 백오프로 재시도했습니다 (이는 에셋, 토큰, 스타일, 노드 트리, 버전 등 모든 읽기에 적용됩니다. 재시도는 공유 요청 경로에 있습니다.Retry-After는 60초 제한으로 준수됩니다). 그래도 표시되면 1분 기다리거나 호출당 더 적은 노드를 가져오세요.
속도 제한 인식 (사양 §2.1): 커넥터 할당량은 Figma 플랜에 따라 다릅니다 — 부모 프레임 요청을 배치하고, 요청하지 않으면 확인 스크린샷을 건너뛰고, 원시 응답을 캐시하여 재파생이 두 번째 호출을 낭비하지 않도록 합니다. REST는 분당 제한이 있습니다 (분당 10개 이상, 엔드포인트별 버킷) — 대량 처리에는 충분하며, 429에서 백오프합니다.
라우팅
parseFigmaRef(URL, fileKey:nodeId, bare fileKey)로 사용자의 figma 링크를 파싱합니다. 그런 다음 의도에 따라:
- "이 레이어 / 로고 / 이미지 사용" → Asset (CLI)
- "내 브랜드 / 색상 / 토큰 가져오기" → Tokens (CLI)
- "이 프레임에서 장면 만들기" → Component (CLI)
- "이 애니메이션 / 모션 가져오기" → Motion (가능한 경우 커넥터, 아래 참조)
- 스토리보드 섹션 / 장면 프레임의 필름스트립 → Storyboard (아래 참조)
- 셰이더 채우기/효과 → Shaders (아래 참조)
사용자에게 모든 단계를 설명하세요 — 각 명령 전에 Figma에서 무엇을 가져올 것인지 말하고, 그 후에 아티팩트가 어디에 저장되었는지 (프리즈 경로 / 사이드카 / 컴포넌트 디렉토리), 컴포지션에서 무엇이 변경되었는지, 그리고 즉시 수행할 다음 작업 (미리보기, 인쇄된 변수 추가, 바인딩 연결을 위한 재가져오기)을 말하세요. 사용자가 "작동했나요?" 또는 "이제 뭐죠?"라고 묻지 않아야 합니다.
에셋 (Phase 1 — CLI)
hyperframes figma asset '<url-or-fileKey:nodeId>' [추가 refs…] [--format svg|png|jpg|pdf] [--scale 2] [--description "..."] [--entity "..."]
REST를 통해 렌더링하고, SVG를 정리하고, .media/images/ 아래에 프리즈하고, 출처와 함께 매니페스트를 추가하고, .media/index.md (공유 미디어 사용 인벤토리)를 재생성하고, <img> 스니펫을 출력합니다. fileKey:nodeId:format:scale:version별로 멱등적입니다. 벡터/로고에는 SVG를 선호합니다 (확장 가능, 애니메이션 가능). 래스터 충실도를 위해 PNG --scale 2를 선호합니다. 항상 --description "<무엇인지>"를 전달하세요 (인덱스 행 + <img alt>가 됩니다). 명명된 브랜드 마크에는 --entity "<이름>"을 추가하여 나중에 media-use resolve --entity가 찾을 수 있도록 합니다 (엔티티는 이미지/아이콘 일치에 적용됨).
하나의 요청으로 여러 노드 배치 — 동일한 파일의 여러 ref를 전달하세요 (공백 또는 쉼표로 구분): hyperframes figma asset 'KEY:1-2' 'KEY:3-4' 'KEY:5-6'. 모든 노드가 단일 /v1/images 호출로 렌더링되며, 이는 Figma 자체의 분당 속도 제한에 대한 답변입니다 — 전체 프레임의 에셋을 가져올 때 N개의 개별 명령보다 선호하세요. --description/--entity는 배치의 모든 노드에 적용되므로, 목적이 동일한 노드를 배치하세요. 429는 또한 백오프와 함께 자동으로 재시도됩니다.
토큰 (Phase 2 — CLI)
hyperframes figma tokens <fileKey>
변수를 컴포지션 브랜드-변수 항목 + figma-tokens.json 사이드카 + 바인딩 인덱스 레코드 (.media/figma-bindings.jsonl)로 가져옵니다. 변수는 Enterprise 게이트입니다: 다른 플랜에서는 명령이 게시된 스타일 메타데이터로 저하됩니다 (값은 컴포넌트 가져오기 시간에 해석됨). 인쇄된 항목을 컴포지션의 data-composition-variables에 추가하세요.
컴포넌트 전에 토큰을 가져오세요 — 둘 다 원할 때. 이렇게 하면 컴포넌트 색상이 중복을 굽는 대신 브랜드 변수에 연결될 수 있습니다.
비-Enterprise 변수 경로 (현장 테스트 완료): REST 변수는 Enterprise 게이트이지만, 호환 가능한 커넥터가 변수 정의를 제공할 수 있습니다. tokens가 REQUIRES_ENTERPRISE를 보고하고 커넥터를 사용할 수 있는 경우, 부모 장면의 변수를 한 번 검색하고, 원시 응답을 .media/figma-cache/에 캐시하고, 이를 사용하여 바인딩 인덱스를 구축하세요. REST 노드 트리의 boundVariables는 속성별 VariableID를 제공합니다. 노드와 속성별로 조인한 다음 .media/figma-bindings.jsonl 행 ({kind:"binding", figmaId, sourceFileKey, compositionVariableId: "figma:<name>", version})과 컴포지션 변수 항목을 작성하세요. 모든 다운스트림 (컴포넌트 var() 해석, 새로고침, 런타임 CSS 변수)은 출하된 메커니즘입니다. 사용자에게 다음과 같이 레이블을 지정하세요: "Figma 커넥터를 통한 토큰 — Enterprise 플랜은 hyperframes figma tokens에서 직접 가져옵니다."
런타임은 모든 선언된 컴포지션 변수를 CSS 사용자 정의 속성 (문서 루트 + 하위 컴포스트 호스트)으로 정의하므로, 가져온 var(--슬러그, 리터럴) 채우기는 변수 기본값이 변경될 때 다시 칠합니다. data-composition-variables에서 하나의 값을 업데이트하면 아무것도 다시 가져오지 않고 모든 가져온 컴포넌트가 리브랜딩됩니다. hyperframes render --variables '<json>'는 렌더링 시 이를 재정의합니다.
컴포넌트 (Phase 3 — CLI)
hyperframes figma component '<url-or-fileKey:nodeId>'
노드 트리 → 정확한 Figma 지오메트리의 편집 가능한 HTML로, compositions/components/<name>/ 아래의 레지스트리 항목으로 패키징됩니다. 벡터/부울 연산은 Phase-1 내보내기를 통해 자동 래스터화됩니다. 바인딩 패스 (사양 §7.1, 정확한 ID만 — 값 일치 절대 안 함):
- 정적 충실도 자체 점검 (히어로 콘텐츠의 경우 필수): 가져온 후 조각을 렌더링하고 Figma 자체 픽셀과 비교합니다 —
figma asset <동일 노드> --format png가 실제 기준입니다. 텍스트는 알려진 드리프트 축입니다: 라인 높이보다 짧은 Figma 텍스트 상자는 수직으로 잘린 경계입니다 (매퍼는 이에 대해text-box-trim을 내보냅니다. 이 없이 측정된 드리프트는 70px 글꼴에서 ~6px였습니다). 비교에서 매퍼가 포함하지 않는 드리프트가 표시되면 보고하세요 — 조각을 자동으로 수정하지 마세요. - 가져온 토큰에 바인딩된 채우기 →
var(--슬러그, #리터럴)— 브랜드 새로고침이 전파됩니다. - 알 수 없는 토큰에 바인딩 → 리터럴 +
data-figma-unresolved플래그. 명령이 알려줍니다. 사용자에게 옵션을 제공하세요: 소스 (또는 라이브러리) 파일에서tokens를 실행한 다음 컴포넌트를 다시 가져와 연결합니다. 알 수 없는 라이브러리당 한 번 어떤 파일인지 묻습니다. 추측하지 말고, 16진수로 일치시키지 마세요.
모션 (Phase 4 — 커넥터 지원)
사용량 비콘: 커넥터 지원 단계에는 CLI 접점이 없으므로, 시작과 종료 시 스킬 비콘을 실행하세요 (익명, 동의 기반, 절대 실패하지 않음): 작업을 시작할 때 npx hyperframes events --skill=figma-motion, 완료 시 npx hyperframes events --skill=figma-motion --event=skill_completed --outcome=success|error. 셰이더(figma-shaders) 및 스토리보드(figma-storyboard)에도 동일하게 적용됩니다.
REST 대응 항목이 없습니다. 호환 가능한 커넥터를 사용할 수 있는 경우, 이를 사용하고 출력을 @hyperframes/core/figma의 순수 헬퍼에 전달하세요. 그렇지 않으면 네이티브 내보내기를 요청하세요:
- 요소별 하나의 요청이 아닌 하나의 재귀적 요청으로 부모 프레임의 모션 컨텍스트를 검색하세요. 원시 JSON을 프로젝트 옆 (
.media/figma-cache/)에 저장하여 재번역이 무료가 되도록 하세요. @hyperframes/core/figma의motionContextToDocs(rawResponse, { selectorFor, repeat })로MotionDoc으로 정규화하세요 — 수동으로 키프레임 번호를 필사하지 마세요. 헬퍼는 기계적으로 현장 테스트된 디코딩 규칙을 인코딩합니다: motion.dev 스니펫(신뢰할 수 있는 인코딩 — CSS 스니펫은 지속 시간을 늘리고 불일치할 수 있습니다. 무시됩니다)을 파싱하고, 루프 래프 테일 키프레임(시간 ≈0.9999→1의 서브 밀리초 세그먼트는 루프의 즉시 리셋이며, 작성된 모션이 아닙니다 — 랩은repeat재시작에 의해 실현됩니다)을 제거하고, 베지어 이징을 그대로 유지합니다.selectorFor는 Phase-3 컴포넌트 가져오기의 ID를 반환해야 합니다. 노드 이름에서 선택기를 파생시키지 마세요. 2b. 완료되었다고 하기 전에 실제 기준과 비교하여 검증하세요 — 필수: 사용 가능한 커넥터를 통해 코호트의 루트 프레임을 내보내고node skills/figma/scripts/verify-motion.mjs --reference <export.mp4> --render <render.mp4> --crop WxH+X+Y를 실행하세요 — 모션 에너지 델타를 비교합니다 (정적 가져오기 충실도는 상쇄됨). 최소 모션-PSNR 15dB 미만이면 실패합니다 (보정됨: 충실함 ≈ 20+, 발산 ≈ 5).--crop을 렌더링의 실제 카드 가장자리에서 측정하고 추측하지 마세요. FAIL은 임계값이 아닌 번역을 다시 확인해야 함을 의미합니다.motionToGsap(doc)→emitTimelineScript(spec)→ GSAP + CustomEase CDN 태그 뒤에<script>로 주입합니다. 일시 중지, 유한,window.__timelines에 리터럴 키로 등록.- 번역 불가능한 트랙 (셰이더 기반, 지원되지 않는 속성, 복잡한 마스크) → 커넥터를 통해 내보내고, MP4를 프리즈한 다음
<video class="clip">로 임베드합니다. 예외: 셰이더 기반 트랙 — Figma의 내보내기 경로는 셰이더를 기본 색상으로 평탄화합니다 (아래 셰이더 참조). 따라서 그곳에서 베이크하면 자동으로 셰이더가 손실됩니다. 대신 사용자에게 네이티브 Figma 내보내기를 요청하세요. 항상 어떤 경로를 사용했는지와 그 이유를 말하세요. 매핑된 세트 외부의 명명된 이징은 선형으로 대체됩니다 — 매핑 테이블은motionEase.ts에 있습니다. 실행 시 사용자에게 대체를 알리세요. - 완료하기 전에
npx hyperframes check를 실행하세요.
셰이더 (Phase 5 — 대부분 수동)
Figma의 커넥터 렌더링 경로는 셰이더를 실행하지 않습니다 (기본 색상으로 평탄화됨). 셰이더 소스는 라이브러리에 게시된 스타일(유료 Full 시트)에만 접근 가능합니다. 기본 경로: 사용자에게 Figma에서 네이티브로 셰이더 프레임을 내보내도록 요청하세요 (PNG 또는 모션 MP4). 그런 다음 Phase-1 에셋/클립으로 가져오세요. 커넥터 픽셀 캡처로 셰이더를 캡처하지 마세요 — 자동으로 잘못된 결과를 생성합니다.
스토리보드 (장면 프레임 섹션 → 애니메이션)
핵심 규칙: 스토리보드 프레임은 키프레임이지 슬라이드가 아닙니다. 동일한 요소를 포함하는 두 개의 프레임은 시간에 따른 해당 요소의 상태를 설명합니다. 상태 간의 ELEMENT에 애니메이션을 적용하세요. 프레임을 정지 영상 시퀀스로 재생하지 마세요. 연속된 네 개의 프레임에 내림차순 y로 그려진 로고는 네 개의 키프레임을 통해 상승하는 하나의 ELEMENT입니다. 스토리보드 프레임을 연속적으로 재생하는 것은 실패 모드입니다. 그것들이 암시하는 요소 타임라인을 재구성하는 것이 작업입니다.
스토리보드 파일은 기계적으로 파싱할 수 있는 문법을 따릅니다. 눈으로 확인하지 말고 디코드하세요:
- 씬 유닛: SECTION 내에서 모든 프레임 크기 노드는 씬입니다 — 명명된 FRAME 뿐만 아니라 느슨한 전체 프레임 RECTANGLE도 포함됩니다 (디자이너는 여전히를 섹션에 바로 붙여넣습니다). 노드 유형이나 이름이 아닌 크기(예: 구성 종횡비, >1400×900)로 필터링하세요.
- 순서 = x-위치 (스트립이 줄바꿈되면 행 우선).
absoluteBoundingBox.x로 씬을 정렬하세요. - 인접한 씬 간의 차이점 찾기: (두 번째 프레임에만 있는 새로운 요소, 이동한 요소, 사라진 요소). 이를 하나의 요소의 상태 전환으로 취급하세요.
- REST 에셋 가져오기 모든 씬에 있는 모든 요소의 경우 Phase 1 사용 — 그런 다음 상태 간 요소 차이에서 GSAP 타임라인을 합성하세요.
- 프레임이 셰이더를 정의하면 Phase 5 지침을 따르세요.
- 마지막 씬 이후에 요소가 사라지면 페이드아웃하거나 제거하세요. 첫 번째 씬 이전에는 요소가 없으면 페이드인하거나 나타나게 하세요.
예 (@hyperframes/core/figma의 storyboardToMotion — 기계적, 추측 없음):
const scenes = parseStoryboardScenes(sectionNode);
const diffs = diffAdjacentScenes(scenes);
const timeline = diffs.flatMap(d => ({
element: d.id,
from: d.prevState, // {x, y, w, h, rotation, opacity, fill}
to: d.nextState,
duration: 0.3, // 씬 지속 시간으로부터 유추
}));
emitTimelineScript(timeline);
결과: 사용자가 "이 스토리보드를 비디오로 만들어 줘"라고 말하면 4개의 PNG와 로고의 위아래로 움직이는 애니메이션을 볼 수 있습니다. 4개의 슬라이드 쇼가 아닙니다.
검증 및 종료 기준
작업 완료를 선언하기 전에 다음을 충족하세요:
- 에셋이 로컬로 프리즈되었습니까? —
.media/images/및 매니페스트 항목을 확인하세요. - 토큰이 컴포지션 변수에 연결되었습니까? — 전체 컴포지션을 확인하거나 연결되지 않은 토큰 참조를 확인하는 테스트 파일을 렌더링하세요.
- 모든 모션 키프레임이 인코딩되었습니까? — 수동 생략 없음, 대체되지 않은 모션이 없음.
npx hyperframes check가 통과되었습니까? — 마지막 단계로 실행하세요.- 설명이 완료되었습니까? — 사용자는 방금 작동한 내용과 다음 할 일을 정확히 알아야 합니다.
빠른 참조
| 명령 | 목적 |
|---|---|
hyperframes figma asset | 정적 에셋 가져오기 (SVG, PNG, JPG, PDF) |
hyperframes figma tokens | 브랜드 변수/스타일 가져오기 |
hyperframes figma component | Figma 노드 → HTML 컴포넌트 |
npx hyperframes check | 무결성 확인 실행 |
npx hyperframes skills update figma | 이 스킬을 최신 상태로 유지 |