Communitygithub.com

aubarcito48/portfolio

빌드된 웹 애플리케이션이나 React 컴포넌트에서 CSS와 이미지를 인라인 처리하여 자체 포함된 정적 HTML을 추출합니다. 특정 UI 상태를 캡처하거나, 페이지의 정적 버전을 공유하거나, Stitch 업로드를 위한 에셋을 준비해야 할 때 이 스킬을 사용하세요. 사용자가 단순히 'HTML을 저장'하거나 '뷰를 모킹'해 달라고 요청한 경우에도 유용합니다.

portfolio란 무엇인가요?

이 스킬은 모든 웹 애플리케이션에서 자체 포함된 정적 HTML 파일을 추출하는 강력한 방법을 제공합니다. Puppeteer를 사용한 전략 A(권장)는 완전히 렌더링된 DOM을 캡처하고, 모든 CSS를 인라인하며, 이미지를 base64로 변환하여 가장 높은 충실도를 제공합니다. 브라우저 서브에이전트 전략 B는 페이지와 상호작용(클릭, 양식 작성)이 필요할 때 유용하며, 앱을 로컬에서 실행할 수 없는 최후의 수단으로 MockPage.jsx 정적 폴백도 지원합니다. 이 스킬은 React, Next.js, Angular, Vue, Svelte 등 모든 주요 프레임워크와 호환되며, 인증이 필요한 페이지, 다크 모드, 캔버스 요소 인라인, 고정 요소 제거와 같은 고급 시나리오를 위한 다양한 플래그를 제공합니다. 요약하자면, 개발자가 로컬 개발 서버의 UI 스냅샷을 정적 HTML로 쉽게 캡처하고 저장하여 공유하거나 문서화하거나 Stitch에 업로드할 수 있도록 합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/aubarcito48/portfolio/tree/HEAD/.agents/skills/stitch-extract-static-html

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

정적 HTML 추출

웹 애플리케이션에서 자체 포함된 정적 HTML 파일을 추출합니다.

사용할 전략

진행하기 전에 반드시 사용자에게 어떤 전략을 사용할지 물어봐야 합니다. 옵션을 명확히 제시하고, 전략 A를 기본값으로 권장하며, 각 옵션에 대한 간단한 장단점 요약을 제공하여 사용자가 정보에 기반한 결정을 내릴 수 있도록 도와주세요.

전략 A (Puppeteer)전략 B (브라우저 서브에이전트)
사용 시기앱이 로컬에서 실행되고, 인증 장벽이 없음페이지와 먼저 상호작용(클릭, 양식 작성)이 필요함
충실도최고 — 계산된 스타일이 해석됨높음 — 렌더링된 DOM
설정제로 — 모의 객체 불필요제로 — 모의 객체 불필요
프레임워크모든 프레임워크모든 프레임워크
출력파일로 직접 기록 — 크기 제한 없음에이전트 컨텍스트에서 잘릴 수 있음

[!WARNING] 체크포인트 — 사용자 확인 필요. 진행하기 전에 반드시 사용자에게 어떤 전략을 선호하는지 물어봐야 합니다. 위의 비교 표를 제시하고, 전략 A를 기본값으로 권장하며, 명시적인 승인을 기다리세요. 직접 결정을 내리거나 사용자가 확인할 때까지 진행하지 마세요.


전략 A: Puppeteer 스냅샷 (권장)

Headless Chrome을 실행하고, 완전히 렌더링된 DOM을 캡처하며, 모든 CSS가 인라인되고 이미지가 base64로 변환된 자체 포함 HTML 파일을 생성합니다. 모든 프레임워크에서 작동합니다 — MockPage.jsx가 필요하지 않습니다.

사전 요구 사항

  • 앱이 로컬에서 실행 중 (예: npm run dev)
  • Node.js에 puppeteer 사용 가능 (확인: node -e "require('puppeteer')")

워크플로

  1. 앱을 시작하고 포트를 기록합니다.

    [!WARNING] 체크포인트 — 사용자 확인 필요. 로컬 서버를 시작한 후 반드시 잠시 멈추고 스냅샷 스크립트를 실행하거나 브라우저 서브에이전트를 실행하기 전에 사용자에게 확인을 요청해야 합니다. 사용자가 앱이 실행 중이고 올바르게 렌더링되는지 확인할 수 있도록 URL과 포트를 보고합니다. 사용자가 확인할 때까지 스냅샷 단계로 진행하지 마세요.

  2. 스냅샷 스크립트 실행:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 \
      --output .stitch/home.html \
      --wait 2000
    
  3. 여러 페이지 — 각 경로에 대해 한 번씩 실행:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 --output .stitch/home.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/pricing --output .stitch/pricing.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/dashboard --output .stitch/dashboard.html --wait 2000 --html-class dark
    
  4. 개발 서버 정리: 스냅샷 추출을 위해 로컬 개발 서버를 시작한 경우, 추출이 완료되면 서버 프로세스를 중지하거나 백그라운드 작업을 종료해야 합니다.

스크립트 플래그

플래그기본값설명
--url(필수)캡처할 URL
--output(필수)출력 파일 경로
--wait1000네트워크 유휴 후 추가 대기 시간(ms). 지연 로딩 앱의 경우 값을 늘리세요.
--viewport1280x800뷰포트 크기 (WIDTHxHEIGHT 형식)
--html-class—<html> 요소에 추가할 클래스(예: dark)
--remove-fixedfalse고정/스티키 요소 제거 (쿠키 배너, 채팅 위젯)
--full-heightfalse전체 스크롤 높이로 뷰포트 크기 조정
--title—페이지 제목 재정의 (경로 이름으로 설정, 예: /dashboard 또는 /settings/profile)
--auth-script—인증을 위한 async (page) => void 함수를 기본 내보내기하는 JS/TS 모듈 경로
--inline-canvasfalse<canvas> 요소 (ECharts, Chart.js, D3)를 base64 <img> 태그로 변환

자동 수행 작업

  • document.styleSheets의 모든 CSSOM 규칙 캡처 (동적 Vite/Tailwind 개발 스타일 및 CSS-in-JS 유지)
  • 모든 <link rel="stylesheet">를 <style> 블록으로 인라인
  • <img>의 src 및 srcset 을 base64 데이터 URI로 변환 (외부 글꼴 제외)
  • 동일 출처 및 상대 아이콘 글꼴 파일(@font-face)을 base64 데이터 URI로 인라인 처리하여 합자가 ASCII 텍스트로 렌더링되지 않도록 방지
  • <source srcset> URL을 base64로 인라인
  • 실패/죽은 srcset 항목을 제거하여 브라우저가 인라인된 src로 폴백하도록 함
  • <script> 태그, Vite HMR 개발 스타일 블록 (createHotContext, import.meta.hot), 개발 오버레이 제거
  • 인라인 전에 상대 CSS url() 경로를 절대 경로로 변환

프레임워크 참고 사항

프레임워크참고 사항
React + Vite별다른 설정 없이 작동합니다. --wait 1000.
Next.jsSSR 수화를 위해 --wait 3000. URL: http://localhost:3000. /_next/image의 <img srcset>는 자동으로 base64로 인라인됩니다.
Angular (@angular/cli / v17+)ng serve와 함께 별다른 설정 없이 작동합니다 (기본 URL: http://localhost:4200). Angular Material / PrimeNG 애니메이션 수화 및 지연 로딩 경로를 위해 --wait 2000.
Vue / Nuxt별다른 설정 없이 작동합니다.
Svelte / SvelteKit별다른 설정 없이 작동합니다.
Storybook스토리 URL 사용: --url http://localhost:6006/?path=/story/...
SSR (Webpack)더 긴 --wait이 필요할 수 있습니다.

문제 해결

문제해결 방법
이미지 누락--wait 증가
서버 중단 후 이미지가 깨져서 표시됨srcset이 인라인되었는지 확인 — 로그에서 "Inlined N images" 확인. srcset URL이 실패하면 자동으로 제거되어 src(인라인됨)가 사용됩니다.
아이콘이 텍스트 / Serif 스타일 없는 글꼴로 표시됨snapshot.ts가 document.styleSheets에서 CSSOM을 캡처하고(0단계) 동일 출처 아이콘 글꼴(@font-face)이 base64 데이터 URI로 인라인되었는지 확인하세요.
Next.js /_next/image가 인라인되지 않음스냅샷 실행 시 개발 서버가 실행 중인지 확인하세요 — 스크립트가 실행 중인 서버에서 최적화된 이미지를 가져옵니다.
다크 모드가 적용되지 않음--html-class dark
출력에 쿠키 배너가 포함됨--remove-fixed
페이지에 로그인 필요--auth-script ./auth.ts 사용 (아래 인증 필요 페이지 참조)
차트/그래프가 빈 상자로 표시됨--inline-canvas를 사용하여 <canvas>를 base64 <img>로 직렬화
Cannot find module 'puppeteer'npm install -g puppeteer

인증 필요 페이지

로그인 가드가 있는 앱 (Vue Router beforeEach, React ProtectedRoute 등)의 경우, Puppeteer 세션에서 실행되는 작은 인증 스크립트를 만드세요:

// auth-myapp.ts
import type { Page } from 'puppeteer';

export default async function authenticate(page: Page) {
  // 예제 1: 로그인 양식 작성 및 제출
  await page.type('#username', 'admin');
  await page.type('#password', 'password123');
  await page.click('#login-button');
  await page.waitForNavigation({ waitUntil: 'networkidle2' });

  // 예제 2: 쿠키/localStorage 직접 주입
  // await page.evaluate(() => {
  //   localStorage.setItem('token', 'mock-jwt-token');
  // });

  // 예제 3: 모듈 주입을 통해 앱 자체 로그인 API 호출 (Vue/Vite)
  // await page.evaluate(() => {
  //   return new Promise((resolve) => {
  //     const script = document.createElement('script');
  //     script.type = 'module';
  //     script.textContent = `
  //       import { useUserStore } from '/src/store/modules/user.ts';
  //       import { fetchLogin } from '/src/api/auth.ts';
  //       const res = await fetchLogin({ userName: 'Admin', password: '123456' });
  //       useUserStore().setToken(res.token, res.refreshToken);
  //       window.dispatchEvent(new CustomEvent('auth-done'));
  //     `;
  //     document.head.appendChild(script);
  //     window.addEventListener('auth-done', () => resolve(true), { once: true });
  //   });
  // });
}

그런 다음 다음과 같이 사용하세요:

npx tsx <SKILL_DIR>/scripts/snapshot.ts \
  --url http://localhost:5173/#/dashboard \
  --output .stitch/dashboard.html \
  --auth-script ./auth-myapp.ts \
  --inline-canvas \
  --wait 5000

스크립트는 먼저 --url로 이동하고(로그인 페이지로 리디렉션될 수 있음), 인증 함수를 실행한 다음, 인증된 세션으로 원래 --url로 다시 이동합니다.


전략 B: 브라우저 서브에이전트 캡처

캡처하기 전에 페이지와 상호작용(버튼 클릭, 양식 작성, 탭 이동)이 필요할 때 사용합니다. 브라우저 서브에이전트는 완전한 제어를 제공하지만, 대규모 페이지의 경우 출력이 잘릴 수 있습니다.

워크플로

  1. 앱을 로컬에서 시작합니다.

  2. 브라우저 서브에이전트를 사용하여 이동합니다.

  3. 필요에 따라 상호작용합니다(클릭, 스크롤, 양식 작성).

  4. DOM 추출: document.documentElement.outerHTML

    [!WARNING] 대규모 페이지는 잘릴 수 있습니다. 이를 처리하려면:

    • 추출 전에 <style> 태그 제거: document.querySelectorAll('style').forEach(el => el.remove())
    • 스타일을 정적으로 다시 추가 (Tailwind CDN 링크, 소스 CSS)
  5. 파일로 저장합니다.


부록: 정적 폴백 (MockPage.jsx)

[!NOTE] 이 방법은 앱을 로컬에서 실행할 수 없는 경우(종속성 손상, 백엔드 누락, 우회 불가능한 인증 장벽)의 최후의 수단입니다. React 컴포넌트를 수동으로 단일 JSX 파일로 평탄화해야 합니다. 가능하면 전략 A를 사용하세요.

사용 시기

  • 앱을 로컬에서 전혀 실행할 수 없음
  • 페이지에 우회 방법이 없는 인증이 필요함
  • 탐색으로 도달하기 불가능한 특정 UI 상태(오류 화면, 빈 상태)가 필요함

빠른 참조

npx tsx <SKILL_DIR>/scripts/extract_inline_html.ts \
  --index-css src/css/App.css \
  --extra-css index.html \
  --outdir .stitch \
  --page src/MockPage.jsx:Page.html:"Page Title"

주요 플래그: --no-tailwind (Tailwind를 사용하지 않는 앱), --html-class dark (다크 모드), --css-files (추가 CSS 파일).

자동 감지: Tailwind 설정은 자동으로 감지됩니다. @apply 지시문은 자동으로 <style type="text/tailwindcss">를 사용합니다.

MockPage.jsx 규칙

  1. 전체 레이아웃 포함 — 헤더, 사이드바, 푸터 (먼저 App.js 읽기)
  2. 모든 조건문 평탄화 — 하나의 상태를 선택하고, 모든 삼항 연산자와 && 가드를 제거
  3. 모든 데이터 하드코딩 — {variable}을 구체적인 값으로 바꾸고, .map() 루프를 펼침
  4. 로고 유지 — 로컬 경로와 함께 <img> 사용 (후처리에서 인라인 처리됨)
  5. 부동 요소 제거 — 쿠키 배너, 채팅 위젯, 피드백 버튼

후처리

로컬 이미지 인라인:

npx tsx <SKILL_DIR>/scripts/post_process.ts \
  .stitch/Page.html --base-dir <app-directory>

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

aubarcito48/portfolio

Transforms vague UI ideas into polished, Stitch-optimized prompts. Enhances specificity, adds UI/UX keywords, injects design system context, and structures output for better generation results.

aubarcito48/portfolio

>- Convert frontend code (Vite, React, Angular, Vue, etc.) to a Stitch Design by chaining static HTML extraction, design system extraction, and file upload. **ALWAYS** use this skill when the user's intent is to move existing web apps or React/Angular/Vue components into Stitch (e.g., requests to "save", "migrate", or "upload"). You must use this skill even for simple "save" operations, as it is the only way to ensure the design system is extracted and assets are properly linked.

aubarcito48/portfolio

>- Extract a comprehensive design system (DESIGN.md) directly from frontend source code — React, Vue, Svelte, Angular, plain HTML/CSS, or any web framework. Analyzes component files, stylesheets, Tailwind configs, theme definitions, and design tokens to produce a rich, Stitch-compatible design system document. Use this skill whenever the user wants to reverse-engineer a design system from an existing codebase, audit the visual language of a project, extract design tokens from source files, or understand the styling patterns in a frontend repo — even if they just say "what does this app look like?" or "pull out the design from this code.

aubarcito48/portfolio

>- Generate new screens from text prompts or images, edit existing screens with prompts and design system tokens, and generate design variants using Stitch MCP. Includes prompt enhancement pipeline, design mappings, professional UI/UX terminology, design tokens and theme system capabilities.

관련 스킬