페이지를 불러오는 중입니다...

애니메이션 카드 뉴스 생성 스킬 정리
애니메이션 카드 뉴스 생성 스킬 정리

1) newsletter.md 파일

# 뉴스레터 작성 스킬

업계 소식을 큐레이션하여 구독자에게 가치 있는 마크다운 뉴스레터를 작성하는 스킬.

---

## 작업 흐름

### 1단계: 정보 수집 (정보가 부족할 경우)

사용자에게 아래 정보를 확인하세요:

- **업계/주제**: 커피 업계 동향

- **발행 주기**: 주간

- **호수/날짜**: 몇 호인지, 발행 날짜는?

- **주요 소식**: 지정된 웹사이트(bwissue.com/news baristanews.co.kr coffeepot.me perfectdailygrind.com)의 최신 아티클을 Markdown 형식으로 수집하고, API 연결 상태를 상시 확인한다.

- **독자층**: 일반인, 바리스타 지원자

- **톤**: 친근하게

정보가 충분하다면 바로 2단계로 이동하세요.

---

### 2단계: 소식 수집 (필요 시)

사용자가 소식을 제공하지 않은 경우, 웹 검색으로 최신 정보를 수집하세요:

- 해당 업계 최신 뉴스 3~5개

- 주목할 트렌드 1~2개

- 유용한 리소스나 도구 1개

---

### 3단계: 뉴스레터 작성

아래 **마크다운 템플릿**을 기반으로 작성하세요.

---

## 마크다운 템플릿

```markdown

# 📬 피우 커피 위클리 — 제[N]호

> [발행일 (예: 2026년 3월 1주차)] | 핵심 키워드: [이번 호 전체를 관통하는 해시태그 3~5개]

안녕하세요! 👋

[이번 주 커피 업계를 관통하는 주요 테마와 거시적인 흐름을 4~5문장의 세밀하고 깊이 있는 단락으로 소개하세요. 독자가 이번 호를 통해 무엇을 얻어갈 수 있는지 기대감을 심어주세요.]

---

## 🔥 이번 주 하이라이트 (THIS WEEK)

> **[업계에 가장 큰 파급력을 가진 소식의 강력한 헤드라인]**

* **상세 내용:** [단순 요약이 아닌, 사건의 배경과 구체적인 진행 상황을 육하원칙에 입각하여 4~5문장(최소 150자 이상)으로 상세히 설명하세요. 세로형 카드에 꽉 차도록 분량을 충분히 확보하세요.]

* **임팩트:** [이 이슈가 앞으로 글로벌/국내 커피 시장, 또는 카페 오너들에게 미칠 구조적 변화나 파급력을 1~2문장의 핵심 메시지로 정리하세요.]

---

## 📰 주요 소식 (NEWS)

### 1. [시선을 끄는 구체적인 소식 제목]

* **상세 내용:** [짧은 요약을 피하고, 소식의 전후 맥락과 실제 데이터를 포함해 4~5문장으로 풍성하게 작성하세요.]

* **임팩트:** [이 뉴스가 커피 산업 종사자나 소비자에게 시사하는 바를 1~2문장으로 도출하세요.]

* [원문 보기](URL)

### 2. [시선을 끄는 구체적인 소식 제목]

* **상세 내용:** [소식의 전후 맥락과 실제 데이터를 포함해 4~5문장으로 풍성하게 작성하세요.]

* **임팩트:** [시사점 및 파급력 1~2문장]

* [원문 보기](URL)

### 3. [시선을 끄는 구체적인 소식 제목]

* **상세 내용:** [소식의 전후 맥락과 실제 데이터를 포함해 4~5문장으로 풍성하게 작성하세요.]

* **임팩트:** [시사점 및 파급력 1~2문장]

* [원문 보기](URL)

*(최소 4개 이상의 주요 소식을 위와 같은 형식으로 꽉 채워 작성하세요)*

---

## 💡 에디터 인사이트 (INSIGHT)

### 대주제: [위 뉴스들을 종합한 트렌드 분석 헤드라인]

* [인사이트 포인트 1: 구체적인 설명이 포함된 완전한 문장 (Full sentence)으로 작성]

* [인사이트 포인트 2: 구체적인 설명이 포함된 완전한 문장으로 작성]

* [인사이트 포인트 3: 구체적인 설명이 포함된 완전한 문장으로 작성]

---

## 📊 이번 주 숫자 (DATA)

* **[숫자 1]**: [이 숫자가 의미하는 바를 2~3문장으로 상세히 설명]

* **[숫자 2]**: [이 숫자가 의미하는 바를 2~3문장으로 상세히 설명]

* **[숫자 3]**: [이 숫자가 의미하는 바를 2~3문장으로 상세히 설명]

---

## 👋 마무리

[독자에게 전하는 따뜻한 조언이나, 급변하는 트렌드 속에서 바리스타/카페 창업자가 가져야 할 마인드셋 등을 4~5문장의 긴 단락으로 작성하세요.]

[다음 호 발행 일정 예고 및 구독 유도 멘트]

```

---

## 작성 원칙

### ✅ 반드시 지킬 것

- **스캔 가능하게**: 독자가 훑어봐도 핵심을 파악할 수 있도록 소제목과 볼드 활용

- **큐레이션 가치 강조**: 단순 나열이 아닌, "왜 이 소식이 중요한가"를 설명

- **에디터의 목소리**: 기계적인 요약이 아닌, 에디터의 관점과 해석 포함

- **독자 중심**: "당신에게 이것이 왜 중요한가"를 항상 염두에 두기

- **분량 적절히**: 읽는 데 5~8분이 적당 (소식 3~5개, 총 800~1500자 내외)

### ❌ 피할 것

- 뉴스 제목만 나열하는 단순 목록

- 지나치게 긴 소식 요약 (각 소식당 3문장 이내)

- 딱딱하고 보도자료 같은 문체

- 링크 없이 "~에 따르면" 식의 모호한 출처

---

## 톤 & 문체 가이드

| 독자층 | 권장 톤 | 예시 표현 |

|--------|---------|----------|

| B2B 전문가 | 신뢰감 있되 친근하게 | "이번 주 주목할 움직임이 있었습니다" |

| 스타트업/창업자 | 에너지 있고 실용적 | "빠르게 짚고 넘어갈게요" |

| 일반 독자 | 쉽고 따뜻하게 | "복잡해 보이지만, 사실 이런 의미예요" |

| 테크 종사자 | 정확하고 간결하게 | "핵심만: ..." |

---

## 섹션 커스터마이징 옵션

필요에 따라 아래 섹션을 추가하거나 교체할 수 있습니다:

- **📊 숫자로 보는 한 주**: 업계 주요 통계/데이터 3개

- **🎙️ 이번 주 인용**: 업계 인사의 주목할 발언

- **🤔 생각해볼 질문**: 독자에게 던지는 사색 유도 질문

- **📅 업계 캘린더**: 다가오는 컨퍼런스, 마감, 이벤트

- **🏆 이번 주 Pick**: 에디터가 고른 최고의 콘텐츠 1개

---

## 출력 형식

- 언제나 **마크다운 문서**로 출력

- 파일로 저장 요청 시 `.md` 확장자로 저장

- 이모지는 섹션 제목에만 사용, 본문에서는 절제

2) nano_background.md 

---

name: nano_background

description: this-week.txt를 읽어 10장 카드뉴스용 배경 이미지를 nanobanana로 생성하고 public/images/cards/에 저장하는 스킬. '배경 이미지 생성', '카드 배경 만들어줘', 'nano_background' 요청 시 사용.

---

# nano_background — 카드뉴스 배경 이미지 생성 스킬

`src/news/this-week.txt`를 읽어 10장 테마를 추출하고, nanobanana JSON 프롬프트를 작성한 뒤

`scripts/generate_cards.py`로 한 번에 생성합니다.

---

## 실행 순서

### 1단계: 뉴스레터 읽기

Read 툴로 `src/news/this-week.txt`를 읽고 파악하세요:

- 뉴스레터 이름 & 호수

- 발행 날짜 → `YYYYMMDD` 형식 (파일명에 사용)

- 섹션 구성: 표지 / 하이라이트 / 소식 3~5개 / 인사이트 / 데이터 / 마무리

### 2단계: 10장 테마 추출 & JSON 프롬프트 작성

| 카드 # | 슬러그 | 유형 | 이미지 컨셉 |

|--------|--------|------|------------|

| 01 | cover | 표지 | 이번 호 전체 분위기를 대표하는 커피 이미지 |

| 02 | highlight | 하이라이트 | 메인 소식을 시각적으로 표현 |

| 03 | news1 | 소식 1 | 첫 번째 주요 소식의 핵심 시각 요소 |

| 04 | news2 | 소식 2 | 두 번째 주요 소식의 핵심 시각 요소 |

| 05 | news3 | 소식 3 | 세 번째 주요 소식의 핵심 시각 요소 |

| 06 | news4 | 소식 4 | 네 번째 소식 (없으면 인사이트 추가) |

| 07 | news5 | 소식 5 | 다섯 번째 소식 또는 추가 인사이트 |

| 08 | insight1 | 인사이트 1 | 에디터 관점 — 업계 트렌드 추상 시각화 |

| 09 | insight2 | 인사이트 2 / 데이터 | 숫자·통계 분위기 또는 두 번째 인사이트 |

| 10 | closing | 마무리 | 따뜻하고 평화로운 커피 한 잔 마무리 장면 |

각 카드의 JSON을 `prompts/cards/card-{NN}.json`으로 저장하세요.

**파일명 예시**: `prompts/cards/card-01.json`, `prompts/cards/card-02.json`

**nanobanana JSON 스키마**:

```json

{

  "meta": { "aspect_ratio": "4:5", "resolution": "1K", "thinking_level": "high" },

  "subject": [ { "type": "...", "name": "...", "details": "...", "position": "..." } ],

  "scene": {

    "location": "...",

    "lighting": { "type": "...", "direction": "...", "quality": "..." },

    "background_blur": "..."

  },

  "camera": { "model": "...", "lens": "...", "aperture": "...", "angle": "...", "framing": "..." },

  "style": {

    "aesthetic": "...",

    "color_grading": "spring bright airy ...",

    "mood": "...",

    "film_stock": "Kodak Portra 400",

    "post_processing": "grain, vignette"

  },

  "negative_prompt": "blurry, dark background, cartoon, text, logos, gloomy, stock photo feel"

}

```

**공통 스타일 규칙**:

- 봄 화사한 무드 (어둡고 칙칙한 배경 금지)

- Photorealistic (일러스트·만화 금지)

- 텍스트·로고 없음

- 커피 업계 테마

### 3단계: generate_cards.py CARDS 목록 업데이트

```python

CARDS = [

    ("prompts/cards/card-01.json", "public/images/cards/01.png"),

    ("prompts/cards/card-02.json", "public/images/cards/02.png"),

    ("prompts/cards/card-03.json", "public/images/cards/03.png"),

    ("prompts/cards/card-04.json", "public/images/cards/04.png"),

    ("prompts/cards/card-05.json", "public/images/cards/05.png"),

    ("prompts/cards/card-06.json", "public/images/cards/06.png"),

    ("prompts/cards/card-07.json", "public/images/cards/07.png"),

    ("prompts/cards/card-08.json", "public/images/cards/08.png"),

    ("prompts/cards/card-09.json", "public/images/cards/09.png"),

    ("prompts/cards/card-10.json", "public/images/cards/10.png"),

]

```

### 4단계: 이미지 생성 실행

```bash

mkdir -p public/images/cards

python3 scripts/generate_cards.py

```

- 이미 존재하는 파일은 덮어씌웁니다

- 실패 시 stderr 출력 확인 후 해당 카드만 재시도

### 5단계: 완료 보고

생성된 10장을 Read 툴로 미리보기하고 결과를 보고합니다.

---

## 주의사항

- `GOOGLE_AI_KEY` 환경변수 필요 — 없으면 즉시 중단하고 사용자에게 알릴 것

- 생성은 `generate_cards.py`가 **순차 처리** (병렬 금지)

- `public/images/cards/`는 Vite public 폴더 → 앱에서 `/images/cards/{파일명}`으로 직접 접근

- card-news 스킬의 `bgImage` 경로: `images/cards/{YYYYMMDD}_{N}.png` (`import.meta.env.BASE_URL` 접두사 붙여 사용)

3) card-news.md

---

name: card-news

description: 뉴스레터나 글을 10장짜리 인터랙티브 카드뉴스 React 컴포넌트로 변환하는 스킬. 사용자가 "카드뉴스 만들어줘", "슬라이드로 만들어줘", "카드 형식으로 정리해줘", "뉴스레터를 카드뉴스로", "인스타그램 카드뉴스" 같은 요청을 할 때 반드시 이 스킬을 사용하세요. newsletter 스킬로 발행한 뉴스레터를 시각화할 때도 즉시 트리거하세요.

---

# 카드뉴스 생성 스킬 (로컬 이미지 배경 & 고정 레이아웃)

뉴스레터 또는 텍스트 콘텐츠를 **10장짜리 세로형(9:16) 인터랙티브 React 카드뉴스**로 변환하는 스킬.

배경 이미지는 `~/public/images/cards/` 디렉토리에 미리 저장된 PNG 파일을 사용합니다.

---

## 작업 흐름

### 1단계: 콘텐츠 파악 및 10장 구성

입력된 뉴스에서 카테고리, 제목, 본문을 추출하여 10장(표지 1장, 소식 2~7장, 인사이트 8~9장, 마무리 10장)으로 분배하세요. 본문은 한 문장 단위로 줄바꿈(`\n`)하여 4~6줄로 만듭니다.

| 카드 번호 | 유형 | 내용 |

|----------|------|------|

| 1장 | 표지 | 시리즈명, 발행일, 메인 타이틀 |

| 2장 | 하이라이트 | 이번 호 가장 중요한 핵심 소식 |

| 3~7장 | 소식 카드 | 주요 소식 각 1개씩 (카테고리 분류 포함) |

| 8장 | 인사이트 | 에디터의 깊이 있는 관점 & 트렌드 분석 |

| 9장 | 데이터 | 이번 주 숫자 |

| 10장 | 마무리 | 클로징 멘트 |

### 2단계: `~/public/images/cards/` 이미지 파일 확인

코드 작성 전, Glob 툴로 `~/public/images/cards/` 디렉토리의 파일 목록을 확인하세요.

```

Glob: ~/public/images/cards/*.{png,jpg,webp}

```

- 파일이 10개 이상이면 카드 순서대로 1:1 매핑합니다.

- 파일이 10개 미만이면 순환(index % files.length)하여 재사용합니다.

- 디렉토리가 없거나 파일이 없으면 사용자에게 알리고, `bgImage` 없이 그라디언트 폴백 테마만으로 계속 진행합니다.

### 3단계: React 컴포넌트 작성

확보한 이미지 경로를 `bgImage` 필드에 넣고 아래 디자인 시스템에 맞춰 `.tsx` 코드를 작성하세요.

---

## 디자인 시스템

### 배경 이미지 적용 방식 (텍스트 패널 분리)

배경 이미지가 최대한 선명하게 보이도록 전체 오버레이는 최소화하고,

텍스트 가독성은 콘텐츠 영역 하단 패널로만 확보합니다.

```tsx

{/* 1. 배경 이미지 */}

<img

  src={`${import.meta.env.BASE_URL}images/cards/${card.bgImage}`}

  alt="" aria-hidden

  className="absolute inset-0 w-full h-full object-cover transition-opacity duration-500"

  style={{ opacity: imgLoaded ? 1 : 0 }}

  onLoad={() => setImgLoaded(true)}

/>

{/* 2. 최소 틴트 오버레이 — 이미지가 있으면 거의 투명, 없으면 그라디언트 폴백 */}

<div

  className="absolute inset-0"

  style={{

    background: imgLoaded

      ? 'linear-gradient(to top, rgba(0,0,0,0.18) 0%, rgba(0,0,0,0.08) 100%)'

      : 'linear-gradient(to top, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.2) 100%)',

  }}

/>

{/* 3. 콘텐츠는 상단 정렬, 텍스트 패널로 가독성 확보 */}

<div className="absolute inset-0 flex flex-col justify-start z-10">

  <div

    className="px-6 pt-12 pb-6"

    style={{

      background: 'linear-gradient(to bottom, rgba(0,0,0,0.88) 60%, rgba(0,0,0,0.60) 85%, transparent 100%)',

    }}

  >

    {/* 카드 콘텐츠 */}

  </div>

</div>

{/* bgImage가 없을 때: 그라디언트 폴백 */}

<div className={`absolute inset-0 bg-gradient-to-br ${card.theme.gradient}`} />

```

- 이미지 상단 40~50%가 거의 원본 그대로 보임

- 텍스트 영역(하단)은 `rgba(0,0,0,0.88)`로 가독성 유지

- `pt-12`로 콘텐츠 위 여백 확보 (이미지가 자연스럽게 보이는 영역 형성)

### 컬러 & 타이포그래피

- **포인트 컬러**: 오렌지 (`text-orange-500`, `#F97316`) — 라벨, 진행도, 강조 텍스트, 구분선

- **기본 텍스트**: `text-white` (제목), `text-gray-200` (본문)

- **폰트 웨이트**: 제목 `font-black`, 라벨 `font-bold tracking-widest`, 본문 `font-medium`

### 카드 레이아웃 (9:16 세로형, 좌측 정렬)

```

┌───────────────────────────────────┐

│ 08 / 10                  [브랜딩] │ ← 좌: 진행도(포인트 컬러), 우: 발행자 정보(회색)

├───────────────────────────────────┤

│                                   │

│ [CATEGORY LABEL]                  │ ← 포인트 컬러, 대문자, 넓은 자간

│ [메인 제목]                       │ ← White, font-black, 줄바꿈 적극 활용

│ ────                              │ ← 짧은 포인트 컬러 구분선

│                                   │

│ [본문 1]                          │ ← leading-relaxed, 문장 단위 줄바꿈

│ [본문 2]                          │

│ [본문 3]                          │

│                                   │

│ [강조/결론]                       │ ← 포인트 컬러, 하단 배치

└───────────────────────────────────┘

```

### 카드 타입별 내용 분량

- **표지**: 뉴스레터 이름(2줄 이상), 호수·발행일, 핵심 해시태그 3~5개

- **하이라이트·소식(2~7장)**: 제목 2~3줄, 본문 최소 100~150자(3~4줄), 임팩트 1~2문장, 출처가 있으면 카드 하단에 출처 도메인 표기 (예: `perfectdailygrind.com`, `bwissue.com`)

- **인사이트(8~9장)**: 타이틀 2줄, 완전한 문장의 포인트 3~4개

- **마무리(10장)**: 헤드라인 2~3줄, 감사 인사·다음 호 예고 3~4문장

---

## React 컴포넌트 구현 가이드

### 카드 데이터 구조

```typescript

type CardTheme = { gradient: string; accent: string };

type CardData = CoverCard | HighlightCard | NewsCard | InsightCard | ClosingCard;

// 각 타입은 bgImage: string 필드를 포함 (없으면 빈 문자열 '')

// 하이라이트·소식 타입은 source?: string 필드를 포함 (출처 도메인, 없으면 생략)

const cards: CardData[] = [

  {

    id: 1, type: 'cover',

    bgImage: '~/public/images/cards/01.png', // 없으면 ''

    theme: { gradient: 'from-stone-900 via-stone-800 to-stone-950', accent: '#F97316' },

    // ...

  },

  {

    id: 2, type: 'highlight',

    source: 'perfectdailygrind.com', // 출처가 있으면 도메인만 표기

    // ...

  },

  // ...

];

```

### 필수 기능

```tsx

// 1. 상태 & 네비게이션

const [current, setCurrent] = useState(0);

const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);

// 2. 키보드 네비게이션 + 반응형 감지

useEffect(() => {

  const handleKey = (e: KeyboardEvent) => {

    if (e.key === 'ArrowRight') goNext();

    if (e.key === 'ArrowLeft') goPrev();

  };

  const onResize = () => setIsMobile(window.innerWidth <= 768);

  window.addEventListener('keydown', handleKey);

  window.addEventListener('resize', onResize);

  return () => {

    window.removeEventListener('keydown', handleKey);

    window.removeEventListener('resize', onResize);

  };

}, []);

// 3. 카드 크기 — 모바일: 360×640, 데스크탑: min(1100px, 92vw)×640

const cardStyle = isMobile

  ? { width: '360px', height: '640px', flexShrink: 0 }

  : { width: 'min(1100px, 92vw)', height: '640px', flexShrink: 0 };

// 4. 상단 진행 바

<div style={{ width: `${((current + 1) / cards.length) * 100}%` }}

     className="h-0.5 bg-orange-500 transition-all duration-300" />

// 5. 터치/스와이프 — touchstart·touchend 이벤트로 감지

```

### 스타일링 원칙

- **반응형 카드 크기**: `isMobile` state로 분기 — `cardStyle`을 inline style로 지정

- **외부 래퍼**: `width: 'min(1100px, 92vw)', margin: isMobile ? '24px auto 40px' : '34px auto 56px'`

```tsx

// ✅ 올바른 방법

const cardStyle = isMobile

  ? { width: '360px', height: '640px', flexShrink: 0 }

  : { width: 'min(1100px, 92vw)', height: '640px', flexShrink: 0 };

return (

  <div style={{ width: 'min(1100px, 92vw)', margin: isMobile ? '24px auto 40px' : '34px auto 56px' }}>

    <div className="relative flex flex-col rounded-3xl overflow-hidden" style={cardStyle}>

      {/* 카드 콘텐츠 */}

    </div>

  </div>

);

// ❌ 잘못된 방법

<div className="w-full max-w-sm lg:max-w-none aspect-[9/16] lg:aspect-auto lg:h-full">

```

---

## 출력 형식

- **파일**: `src/components/common/CardNews.tsx`

- **default export**: `export default function CardNews`

- **props**: `className?: string` 하나만 허용

- 모든 카드 데이터는 컴포넌트 내부에 하드코딩

---

## 작성 원칙

### ✅ 반드시 지킬 것

- `~/public/images/cards/` 파일 목록을 먼저 확인하고 실제 존재하는 경로만 `bgImage`에 사용할 것

- `bgImage`가 있으면 이미지 + 오버레이, 없으면 그라디언트 폴백

- `import.meta.env.BASE_URL` 접두사로 이미지 경로 구성

- 텍스트는 배열(`body: string[]`)로 줄바꿈 처리

- 카드 컨테이너 크기는 `isMobile` state + `cardStyle` inline style로 지정 (Tailwind `max-w-*`/`aspect-*` 클래스 혼용 금지)

### ❌ 피할 것

- 존재하지 않는 이미지 경로를 하드코딩하는 것

- nanobanana 스킬 호출 (이미지 생성은 별도 스킬에서 처리)

- Tailwind `max-w-sm`, `aspect-[9/16]`, `lg:max-w-none` 등으로 카드 크기를 지정하는 것 (`isMobile` + `cardStyle` 패턴을 사용할 것)

- 밝은 배경 + 밝은 텍스트 조합 (명도 대비 확보 필수)

4) scripts/generate_cards.py 

"""Generate all 10 card images for 피우 커피 위클리 제3호."""

import json, os, sys, requests, base64

CARDS = [

    ("prompts/cards/card-01.json",    "public/images/cards/01.png"),

    ("prompts/cards/card-02.json",    "public/images/cards/02.png"),

    ("prompts/cards/card-03.json",    "public/images/cards/03.png"),

    ("prompts/cards/card-04.json",    "public/images/cards/04.png"),

    ("prompts/cards/card-05.json",    "public/images/cards/05.png"),

    ("prompts/cards/card-06.json",    "public/images/cards/06.png"),

    ("prompts/cards/card-07.json",    "public/images/cards/07.png"),

    ("prompts/cards/card-08.json",    "public/images/cards/08.png"),

    ("prompts/cards/card-09.json",    "public/images/cards/09.png"),

    ("prompts/cards/card-10.json",    "public/images/cards/10.png"),

]

def generate(prompt_path, output_path):

    with open(prompt_path) as f:

        data = json.load(f)

    prompt_text = json.dumps(data, indent=2)

    response = requests.post(

        "https://generativelanguage.googleapis.com/v1beta/models/"

        "gemini-3.1-flash-image-preview:generateContent",

        params={"key": os.environ["GOOGLE_AI_KEY"]},

        json={

            "contents": [{"parts": [{"text": prompt_text}]}],

            "generationConfig": {

                "responseModalities": ["TEXT", "IMAGE"],

                "imageConfig": {

                    "aspectRatio": data.get("meta", {}).get("aspect_ratio", "1:1"),

                    "imageSize": data.get("meta", {}).get("resolution", "1K")

                }

            }

        }

    )

    result = response.json()

    for part in result["candidates"][0]["content"]["parts"]:

        if "inlineData" in part:

            img_data = base64.b64decode(part["inlineData"]["data"])

            os.makedirs(os.path.dirname(output_path), exist_ok=True)

            with open(output_path, "wb") as f:

                f.write(img_data)

            print(f"Saved: {output_path}")

            return output_path

    print(f"ERROR: no image in response for {prompt_path}", file=sys.stderr)

    print(json.dumps(result, indent=2), file=sys.stderr)

    return None

if __name__ == "__main__":

    for prompt_path, output_path in CARDS:

        generate(prompt_path, output_path)

1) 2) 3) 번 스킬은 자신의 project directory 아래 .claude 아래 commands 아래에 파일을 생성하고 copy-paste 해 놓으시면 됩니다. 그 후에 claude 실행시키시고, 각 skill을 순서대로 실행해줘라고 명령어를 쓰면, claude 가 차근히 실행해 줍니다.

4) python 파일은 scripts/generate_cards.py 파일을 만드시고, 위 내용을 copy-paste 해 놓으시면 됩니다. 대신 자신의 서버에 python이 설치되어 있어햐 해요.

실질적인 도움이 되시면 합니다.

View on Threads

작성일: 2026-03-22 | 카테고리: Playing with AI | 방문자수: 286
LinkedIn Instagram
의견 혹은 질문을 남겨주세요. (0)

아직 의견이 없습니다.

관련 콘텐츠

도구가 작동하는 방식이 바뀌고 있다.

최근들어 몇몇 프로젝트를 인공지능 서비스인 claude를 사용하여 진행하고 있다. 이종호 님의 강2026년 제주 발표…

자동으로 insta_toons를 만들고 발행해주는 claude skill 입니다.

toons 디렉토리를 생성한 후에 public>character_sheet, public>episodes, public>referenc…

Airbnb 마케팅 포인트 도출 스킬 공개합니다.

# 영종도 에어비앤비 주간 리서치 스킬 (Firecrawl MCP) --- name: airbnb-research de…

Fashion Trend를 조사, 분석 리포트까지 작성하는 Skill

# Fashion Trend React Component Generator Skill (with Firecrawl MCP) You…

카드 뉴스를 발행하는 skill 정리합니다.

https://www.threads.com/@06am_draw/post/DV7DjOsihwk?xmt=AQF00wmvK6QkpssJhCKyfaI…

인공지능을 활용할 때 주의할 점은?

"지금 우리는 아주 말을 잘 알아듣는 컴퓨터에게 아주 인간의 말을 잘 알아듣지 못하는 컴퓨터를 위한 일을 시키기 위한 방법을 배우고 있다" 라…

Nano Banana 를 통한 채색 Upgrade

Your browser does not support the video t…

Beautiful Antigravity

Antigravity를 사용해 본 후에, 싸~~한 느낌이 들어서 곰곰히 생각해 봤어. 지금까지 내가 chatGPT나 Perflexity를…

드디어 A14U = 당신을 위한 AI 매거진의 틀이 완성되었습니다.

2026년 1월 8일 그동안 Vibe Coding 을 실천하면서 목표로 삼은 것이 내가 지금 작성한 HTML 기반의 웹사이트를 React…