mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-13 06:19:46 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7465f37dcf | |||
| 38a1b90db3 | |||
| b53a5db60a | |||
| 372e03cef3 | |||
| ea8ad82786 | |||
| 6fffe252c0 | |||
| 86a84739e8 |
@@ -6,7 +6,7 @@
|
|||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"description": "Skills shared by Baoyu for improving daily work efficiency",
|
"description": "Skills shared by Baoyu for improving daily work efficiency",
|
||||||
"version": "1.30.0"
|
"version": "1.30.3"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,25 @@
|
|||||||
|
|
||||||
English | [中文](./CHANGELOG.zh.md)
|
English | [中文](./CHANGELOG.zh.md)
|
||||||
|
|
||||||
|
## 1.30.3 - 2026-02-06
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
- `baoyu-article-illustrator`: optimize SKILL.md from 197 to 150 lines (24% reduction); apply progressive disclosure pattern with concise overview and detailed references.
|
||||||
|
|
||||||
|
## 1.30.2 - 2026-02-06
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
- `baoyu-cover-image`: optimize SKILL.md from 532 to 233 lines (56% reduction); extract reference image handling to `references/workflow/reference-images.md`; condense galleries to value-only tables with links.
|
||||||
|
|
||||||
|
## 1.30.1 - 2026-02-06
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- `baoyu-image-gen`: add OpenAI GPT Image edits support for reference images (`--ref`); auto-select Google or OpenAI when ref provided.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- `baoyu-image-gen`: change ref-related warnings to explicit errors with fix hints; add reference image validation.
|
||||||
|
- `baoyu-cover-image`: enhance reference image analysis with deep extraction template; require MUST INCORPORATE section for concrete visual elements.
|
||||||
|
|
||||||
## 1.30.0 - 2026-02-06
|
## 1.30.0 - 2026-02-06
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -2,6 +2,25 @@
|
|||||||
|
|
||||||
[English](./CHANGELOG.md) | 中文
|
[English](./CHANGELOG.md) | 中文
|
||||||
|
|
||||||
|
## 1.30.3 - 2026-02-06
|
||||||
|
|
||||||
|
### 重构
|
||||||
|
- `baoyu-article-illustrator`:优化 SKILL.md 从 197 行精简至 150 行(减少 24%);采用渐进式披露模式,主文件提供简洁概览,详细内容通过引用文件提供。
|
||||||
|
|
||||||
|
## 1.30.2 - 2026-02-06
|
||||||
|
|
||||||
|
### 重构
|
||||||
|
- `baoyu-cover-image`:优化 SKILL.md 从 532 行精简至 233 行(减少 56%);将参考图片处理流程提取到 `references/workflow/reference-images.md`;画廊改为纯值表格并链接到详细参考文件。
|
||||||
|
|
||||||
|
## 1.30.1 - 2026-02-06
|
||||||
|
|
||||||
|
### 新功能
|
||||||
|
- `baoyu-image-gen`:新增 OpenAI GPT Image edits 支持参考图片(`--ref`);提供 ref 时自动选择 Google 或 OpenAI。
|
||||||
|
|
||||||
|
### 修复
|
||||||
|
- `baoyu-image-gen`:将 ref 相关警告改为明确错误提示;新增参考图片验证。
|
||||||
|
- `baoyu-cover-image`:增强参考图片分析,使用深度提取模板;要求 MUST INCORPORATE 章节以包含具体可复现的视觉元素。
|
||||||
|
|
||||||
## 1.30.0 - 2026-02-06
|
## 1.30.0 - 2026-02-06
|
||||||
|
|
||||||
### 新功能
|
### 新功能
|
||||||
|
|||||||
@@ -11,55 +11,34 @@ Analyze articles, identify illustration positions, generate images with Type ×
|
|||||||
|
|
||||||
| Dimension | Controls | Examples |
|
| Dimension | Controls | Examples |
|
||||||
|-----------|----------|----------|
|
|-----------|----------|----------|
|
||||||
| **Type** | Information structure, layout | infographic, scene, flowchart, comparison, framework, timeline |
|
| **Type** | Information structure | infographic, scene, flowchart, comparison, framework, timeline |
|
||||||
| **Style** | Visual aesthetics, mood | notion, warm, minimal, blueprint, watercolor, elegant |
|
| **Style** | Visual aesthetics | notion, warm, minimal, blueprint, watercolor, elegant |
|
||||||
|
|
||||||
Type × Style can be freely combined. Example: `--type infographic --style blueprint`
|
Combine freely: `--type infographic --style blueprint`
|
||||||
|
|
||||||
## Illustration Purpose
|
## Types
|
||||||
|
|
||||||
Auto-detected during content analysis. Influences type/style recommendations.
|
|
||||||
|
|
||||||
| Purpose | Description | Best Types |
|
|
||||||
|---------|-------------|------------|
|
|
||||||
| **information** | Help understand abstract concepts | infographic, flowchart, comparison |
|
|
||||||
| **visualization** | Turn abstract ideas into concrete visuals | framework, comparison, infographic |
|
|
||||||
| **imagination** | Create atmosphere, spark imagination | scene, timeline |
|
|
||||||
|
|
||||||
## Type Gallery
|
|
||||||
|
|
||||||
| Type | Best For |
|
| Type | Best For |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
| `infographic` | Data, metrics, technical articles |
|
| `infographic` | Data, metrics, technical |
|
||||||
| `scene` | Narratives, personal stories, emotional content |
|
| `scene` | Narratives, emotional |
|
||||||
| `flowchart` | Tutorials, workflows, processes |
|
| `flowchart` | Processes, workflows |
|
||||||
| `comparison` | Side-by-side, before/after, options |
|
| `comparison` | Side-by-side, options |
|
||||||
| `framework` | Methodologies, models, architecture |
|
| `framework` | Models, architecture |
|
||||||
| `timeline` | History, progress, evolution |
|
| `timeline` | History, evolution |
|
||||||
|
|
||||||
## Styles
|
## Styles
|
||||||
|
|
||||||
See [references/styles.md](references/styles.md) for:
|
See [references/styles.md](references/styles.md) for Core Styles, full gallery, and Type × Style compatibility.
|
||||||
- **Core Styles**: Simplified tier for quick selection (vector, minimal-flat, sci-fi, hand-drawn, editorial, scene)
|
|
||||||
- **Style Gallery**: Full 20+ style options with descriptions
|
|
||||||
- **Auto Selection**: Content signals → Type/Style recommendations
|
|
||||||
- **Compatibility Matrix**: Type × Style combinations
|
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
```
|
```
|
||||||
Progress:
|
- [ ] Step 1: Pre-check (EXTEND.md, references, config)
|
||||||
- [ ] Step 1: Pre-check
|
- [ ] Step 2: Analyze content
|
||||||
- [ ] 1.5 Load preferences (EXTEND.md) ⛔ BLOCKING
|
- [ ] Step 3: Confirm settings (AskUserQuestion)
|
||||||
- [ ] 1.0 Reference images ⚠️ (if provided)
|
- [ ] Step 4: Generate outline
|
||||||
- [ ] 1.2-1.4 Config questions (1 AskUserQuestion, max 4 Qs)
|
- [ ] Step 5: Generate images
|
||||||
- [ ] Step 2: Setup & Analyze
|
|
||||||
- [ ] Step 3: Confirm Settings (1 AskUserQuestion, max 4 Qs)
|
|
||||||
- [ ] Q1: Type ⚠️
|
|
||||||
- [ ] Q2: Density ⚠️ MUST ASK
|
|
||||||
- [ ] Q3: Style ⚠️
|
|
||||||
- [ ] Step 4: Generate Outline
|
|
||||||
- [ ] Step 5: Generate Images
|
|
||||||
- [ ] Step 6: Finalize
|
- [ ] Step 6: Finalize
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -67,8 +46,6 @@ Progress:
|
|||||||
|
|
||||||
**1.5 Load Preferences (EXTEND.md) ⛔ BLOCKING**
|
**1.5 Load Preferences (EXTEND.md) ⛔ BLOCKING**
|
||||||
|
|
||||||
**CRITICAL**: If EXTEND.md not found, MUST complete first-time setup before ANY other steps.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
test -f .baoyu-skills/baoyu-article-illustrator/EXTEND.md && echo "project"
|
test -f .baoyu-skills/baoyu-article-illustrator/EXTEND.md && echo "project"
|
||||||
test -f "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "user"
|
test -f "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "user"
|
||||||
@@ -76,122 +53,98 @@ test -f "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "user"
|
|||||||
|
|
||||||
| Result | Action |
|
| Result | Action |
|
||||||
|--------|--------|
|
|--------|--------|
|
||||||
| Found | Read, parse, display summary → Continue |
|
| Found | Read, parse, display summary |
|
||||||
| Not found | ⛔ Run first-time setup ([references/config/first-time-setup.md](references/config/first-time-setup.md)) |
|
| Not found | ⛔ Run [first-time-setup](references/config/first-time-setup.md) |
|
||||||
|
|
||||||
**Supports**: Watermark | Preferred type/style | Custom styles | Language | Output directory
|
|
||||||
|
|
||||||
**1.0-1.4**: Handle reference images, determine input type, ask config questions.
|
|
||||||
|
|
||||||
Full procedures: [references/workflow.md](references/workflow.md#step-1-pre-check)
|
Full procedures: [references/workflow.md](references/workflow.md#step-1-pre-check)
|
||||||
|
|
||||||
---
|
### Step 2: Analyze
|
||||||
|
|
||||||
### Step 2: Setup & Analyze
|
| Analysis | Output |
|
||||||
|
|----------|--------|
|
||||||
| Analysis | Description |
|
|
||||||
|----------|-------------|
|
|
||||||
| Content type | Technical / Tutorial / Methodology / Narrative |
|
| Content type | Technical / Tutorial / Methodology / Narrative |
|
||||||
| Illustration purpose | information / visualization / imagination |
|
| Purpose | information / visualization / imagination |
|
||||||
| Core arguments | 2-5 main points to visualize |
|
| Core arguments | 2-5 main points |
|
||||||
| Visual opportunities | Positions where illustrations add value |
|
| Positions | Where illustrations add value |
|
||||||
|
|
||||||
**CRITICAL**: If article uses metaphors, do NOT illustrate literally. Visualize the **underlying concept**.
|
**CRITICAL**: Metaphors → visualize underlying concept, NOT literal image.
|
||||||
|
|
||||||
Full procedures: [references/workflow.md](references/workflow.md#step-2-setup--analyze)
|
Full procedures: [references/workflow.md](references/workflow.md#step-2-setup--analyze)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 3: Confirm Settings ⚠️
|
### Step 3: Confirm Settings ⚠️
|
||||||
|
|
||||||
**Do NOT skip.** Use ONE AskUserQuestion call with max 4 questions. **Q1, Q2, Q3 are ALL REQUIRED.**
|
**ONE AskUserQuestion, max 4 Qs. Q1-Q3 REQUIRED.**
|
||||||
|
|
||||||
| Question | Options |
|
| Q | Options |
|
||||||
|----------|---------|
|
|---|---------|
|
||||||
| **Q1: Type** ⚠️ | [Recommended], infographic, scene, flowchart, comparison, framework, timeline, mixed |
|
| **Q1: Type** | [Recommended], infographic, scene, flowchart, comparison, framework, timeline, mixed |
|
||||||
| **Q2: Density** ⚠️ | minimal (1-2), balanced (3-5), per-section (Recommended), rich (6+) |
|
| **Q2: Density** | minimal (1-2), balanced (3-5), per-section (Recommended), rich (6+) |
|
||||||
| **Q3: Style** ⚠️ | [Recommended], minimal-flat, sci-fi, hand-drawn, editorial, scene, Other |
|
| **Q3: Style** | [Recommended], minimal-flat, sci-fi, hand-drawn, editorial, scene, Other |
|
||||||
| **Q4: Language** | When article language ≠ EXTEND.md setting |
|
| Q4: Language | When article language ≠ EXTEND.md setting |
|
||||||
|
|
||||||
Full procedures: [references/workflow.md](references/workflow.md#step-3-confirm-settings-)
|
Full procedures: [references/workflow.md](references/workflow.md#step-3-confirm-settings-)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 4: Generate Outline
|
### Step 4: Generate Outline
|
||||||
|
|
||||||
Save as `outline.md` with frontmatter (type, density, style, image_count, references) and illustration entries:
|
Save `outline.md` with frontmatter (type, density, style, image_count) and entries:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
## Illustration 1
|
## Illustration 1
|
||||||
**Position**: [section] / [paragraph]
|
**Position**: [section/paragraph]
|
||||||
**Purpose**: [why this helps]
|
**Purpose**: [why]
|
||||||
**Visual Content**: [what to show]
|
**Visual Content**: [what]
|
||||||
**Filename**: 01-infographic-concept-name.png
|
**Filename**: 01-infographic-concept-name.png
|
||||||
```
|
```
|
||||||
|
|
||||||
Full template: [references/workflow.md](references/workflow.md#step-4-generate-outline)
|
Full template: [references/workflow.md](references/workflow.md#step-4-generate-outline)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 5: Generate Images
|
### Step 5: Generate Images
|
||||||
|
|
||||||
1. **Create Prompts**: Follow [references/prompt-construction.md](references/prompt-construction.md)
|
1. Create prompts per [references/prompt-construction.md](references/prompt-construction.md)
|
||||||
2. **Select Generation Skill**: Check available skills
|
2. Select generation skill from available skills
|
||||||
3. **Process References**: Handle `direct`/`style`/`palette` usage
|
3. Process references (`direct`/`style`/`palette`)
|
||||||
4. **Apply Watermark**: If enabled in EXTEND.md
|
4. Apply watermark if EXTEND.md enabled
|
||||||
5. **Generate**: Sequential, retry once on failure
|
5. Generate sequentially, retry once on failure
|
||||||
|
|
||||||
Full procedures: [references/workflow.md](references/workflow.md#step-5-generate-images)
|
Full procedures: [references/workflow.md](references/workflow.md#step-5-generate-images)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 6: Finalize
|
### Step 6: Finalize
|
||||||
|
|
||||||
**Update Article**: Insert `` after corresponding paragraphs.
|
Insert `` after paragraphs.
|
||||||
|
|
||||||
**Output Summary**:
|
|
||||||
```
|
```
|
||||||
Article Illustration Complete!
|
Article Illustration Complete!
|
||||||
Article: [path] | Type: [type] | Density: [level] | Style: [style]
|
Article: [path] | Type: [type] | Density: [level] | Style: [style]
|
||||||
Images: X/N generated
|
Images: X/N generated
|
||||||
Positions:
|
|
||||||
- 01-xxx.png → After "[Section]"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Output Directory
|
## Output Directory
|
||||||
|
|
||||||
```
|
```
|
||||||
illustrations/{topic-slug}/
|
illustrations/{topic-slug}/
|
||||||
├── source-{slug}.{ext}
|
├── source-{slug}.{ext}
|
||||||
├── references/ # Only if references provided
|
├── references/ # if provided
|
||||||
│ └── NN-ref-{slug}.png
|
|
||||||
├── outline.md
|
├── outline.md
|
||||||
├── prompts/
|
├── prompts/
|
||||||
│ └── illustration-{slug}.md
|
|
||||||
└── NN-{type}-{slug}.png
|
└── NN-{type}-{slug}.png
|
||||||
```
|
```
|
||||||
|
|
||||||
**Slug**: 2-4 word topic in kebab-case.
|
**Slug**: 2-4 words, kebab-case. **Conflict**: append `-YYYYMMDD-HHMMSS`.
|
||||||
**Conflict**: Append `-YYYYMMDD-HHMMSS` if exists.
|
|
||||||
|
|
||||||
## Modification
|
## Modification
|
||||||
|
|
||||||
| Action | Steps |
|
| Action | Steps |
|
||||||
|--------|-------|
|
|--------|-------|
|
||||||
| **Edit** | Update prompt file FIRST → Regenerate → Update reference |
|
| Edit | Update prompt → Regenerate → Update reference |
|
||||||
| **Add** | Identify position → Create prompt → Generate → Update outline → Insert |
|
| Add | Position → Prompt → Generate → Update outline → Insert |
|
||||||
| **Delete** | Delete files → Remove reference → Update outline |
|
| Delete | Delete files → Remove reference → Update outline |
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
| File | Content |
|
| File | Content |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| [references/workflow.md](references/workflow.md) | Detailed workflow procedures |
|
| [references/workflow.md](references/workflow.md) | Detailed procedures |
|
||||||
| [references/usage.md](references/usage.md) | Command syntax and options |
|
| [references/usage.md](references/usage.md) | Command syntax |
|
||||||
| [references/styles.md](references/styles.md) | Style gallery & compatibility |
|
| [references/styles.md](references/styles.md) | Style gallery |
|
||||||
| [references/prompt-construction.md](references/prompt-construction.md) | Prompt templates |
|
| [references/prompt-construction.md](references/prompt-construction.md) | Prompt templates |
|
||||||
| `references/styles/<style>.md` | Full style specifications |
|
| [references/config/first-time-setup.md](references/config/first-time-setup.md) | First-time setup |
|
||||||
| `references/config/preferences-schema.md` | EXTEND.md schema |
|
|
||||||
| `references/config/first-time-setup.md` | First-time setup flow |
|
|
||||||
|
|||||||
@@ -10,169 +10,94 @@ Generate elegant cover images for articles with 5-dimensional customization.
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Auto-select all dimensions based on content
|
# Auto-select dimensions based on content
|
||||||
/baoyu-cover-image path/to/article.md
|
/baoyu-cover-image path/to/article.md
|
||||||
|
|
||||||
# Quick mode: skip confirmation, use auto-selection
|
# Quick mode: skip confirmation
|
||||||
/baoyu-cover-image article.md --quick
|
/baoyu-cover-image article.md --quick
|
||||||
|
|
||||||
# Specify dimensions (new 5D system)
|
# Specify dimensions
|
||||||
/baoyu-cover-image article.md --type conceptual --palette warm --rendering flat-vector
|
/baoyu-cover-image article.md --type conceptual --palette warm --rendering flat-vector
|
||||||
/baoyu-cover-image article.md --text title-subtitle --mood bold
|
|
||||||
|
|
||||||
# Style presets (backward-compatible shorthand for palette + rendering)
|
# Style presets (shorthand for palette + rendering)
|
||||||
/baoyu-cover-image article.md --style blueprint
|
/baoyu-cover-image article.md --style blueprint
|
||||||
/baoyu-cover-image article.md --style blueprint --rendering hand-drawn # override rendering
|
|
||||||
|
|
||||||
# Visual only (no title text)
|
|
||||||
/baoyu-cover-image article.md --no-title
|
|
||||||
|
|
||||||
# Direct content input
|
|
||||||
/baoyu-cover-image
|
|
||||||
[paste content]
|
|
||||||
|
|
||||||
# Direct input with options
|
|
||||||
/baoyu-cover-image --palette mono --rendering digital --aspect 1:1 --quick
|
|
||||||
[paste content]
|
|
||||||
|
|
||||||
# With reference images
|
# With reference images
|
||||||
/baoyu-cover-image article.md --ref style-ref.png
|
/baoyu-cover-image article.md --ref style-ref.png
|
||||||
/baoyu-cover-image article.md --ref ref1.png ref2.png --quick
|
|
||||||
|
# Direct content input
|
||||||
|
/baoyu-cover-image --palette mono --aspect 1:1 --quick
|
||||||
|
[paste content]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
| Option | Description |
|
| Option | Description |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| `--type <name>` | Cover type: hero, conceptual, typography, metaphor, scene, minimal |
|
| `--type <name>` | hero, conceptual, typography, metaphor, scene, minimal |
|
||||||
| `--palette <name>` | Color palette: warm, elegant, cool, dark, earth, vivid, pastel, mono, retro |
|
| `--palette <name>` | warm, elegant, cool, dark, earth, vivid, pastel, mono, retro |
|
||||||
| `--rendering <name>` | Rendering style: flat-vector, hand-drawn, painterly, digital, pixel, chalk |
|
| `--rendering <name>` | flat-vector, hand-drawn, painterly, digital, pixel, chalk |
|
||||||
| `--style <name>` | Preset shorthand (expands to palette + rendering, see [Style Presets](references/style-presets.md)) |
|
| `--style <name>` | Preset shorthand (see [Style Presets](references/style-presets.md)) |
|
||||||
| `--text <level>` | Text density: none, title-only, title-subtitle, text-rich |
|
| `--text <level>` | none, title-only, title-subtitle, text-rich |
|
||||||
| `--mood <level>` | Emotional intensity: subtle, balanced, bold |
|
| `--mood <level>` | subtle, balanced, bold |
|
||||||
| `--font <name>` | Font style: clean, handwritten, serif, display |
|
| `--font <name>` | clean, handwritten, serif, display |
|
||||||
| `--aspect <ratio>` | 16:9 (default), 2.35:1, 4:3, 3:2, 1:1, 3:4 |
|
| `--aspect <ratio>` | 16:9 (default), 2.35:1, 4:3, 3:2, 1:1, 3:4 |
|
||||||
| `--lang <code>` | Title language (en, zh, ja, etc.) |
|
| `--lang <code>` | Title language (en, zh, ja, etc.) |
|
||||||
| `--no-title` | Alias for `--text none` |
|
| `--no-title` | Alias for `--text none` |
|
||||||
| `--quick` | Skip confirmation, use auto-selection for missing dimensions |
|
| `--quick` | Skip confirmation, use auto-selection |
|
||||||
| `--ref <files...>` | Reference images for style/composition guidance |
|
| `--ref <files...>` | Reference images for style/composition guidance |
|
||||||
|
|
||||||
## Five Dimensions
|
## Five Dimensions
|
||||||
|
|
||||||
| Dimension | Controls | Values | Default |
|
| Dimension | Values | Default |
|
||||||
|-----------|----------|--------|---------|
|
|-----------|--------|---------|
|
||||||
| **Type** | Visual composition, information structure | hero, conceptual, typography, metaphor, scene, minimal | auto |
|
| **Type** | hero, conceptual, typography, metaphor, scene, minimal | auto |
|
||||||
| **Palette** | Colors, color scheme, decorative hints | warm, elegant, cool, dark, earth, vivid, pastel, mono, retro | auto |
|
| **Palette** | warm, elegant, cool, dark, earth, vivid, pastel, mono, retro | auto |
|
||||||
| **Rendering** | Line quality, texture, depth, element style | flat-vector, hand-drawn, painterly, digital, pixel, chalk | auto |
|
| **Rendering** | flat-vector, hand-drawn, painterly, digital, pixel, chalk | auto |
|
||||||
| **Text** | Text density, information hierarchy | none, title-only, title-subtitle, text-rich | title-only |
|
| **Text** | none, title-only, title-subtitle, text-rich | title-only |
|
||||||
| **Mood** | Emotional intensity, visual weight | subtle, balanced, bold | balanced |
|
| **Mood** | subtle, balanced, bold | balanced |
|
||||||
| **Font** | Typography style, character feel | clean, handwritten, serif, display | clean |
|
| **Font** | clean, handwritten, serif, display | clean |
|
||||||
|
|
||||||
Dimensions can be freely combined. Auto-selection rules: [references/auto-selection.md](references/auto-selection.md)
|
Auto-selection rules: [references/auto-selection.md](references/auto-selection.md)
|
||||||
|
|
||||||
## Type Gallery
|
## Galleries
|
||||||
|
|
||||||
| Type | Description | Best For |
|
**Types**: hero, conceptual, typography, metaphor, scene, minimal
|
||||||
|------|-------------|----------|
|
→ Details: [references/types.md](references/types.md)
|
||||||
| `hero` | Large visual impact, title overlay | Product launch, brand promotion, major announcements |
|
|
||||||
| `conceptual` | Concept visualization, abstract core ideas | Technical articles, methodology, architecture design |
|
|
||||||
| `typography` | Text-focused layout, prominent title | Opinion pieces, quotes, insights |
|
|
||||||
| `metaphor` | Visual metaphor, concrete expressing abstract | Philosophy, growth, personal development |
|
|
||||||
| `scene` | Atmospheric scene, narrative feel | Stories, travel, lifestyle |
|
|
||||||
| `minimal` | Minimalist composition, generous whitespace | Zen, focus, core concepts |
|
|
||||||
|
|
||||||
Type composition details: [references/types.md](references/types.md)
|
**Palettes**: warm, elegant, cool, dark, earth, vivid, pastel, mono, retro
|
||||||
|
→ Details: [references/palettes/](references/palettes/)
|
||||||
|
|
||||||
## Palette Gallery
|
**Renderings**: flat-vector, hand-drawn, painterly, digital, pixel, chalk
|
||||||
|
→ Details: [references/renderings/](references/renderings/)
|
||||||
|
|
||||||
| Palette | Vibe | Primary Colors |
|
**Text Levels**: none (pure visual) | title-only (default) | title-subtitle | text-rich (with tags)
|
||||||
|---------|------|----------------|
|
→ Details: [references/dimensions/text.md](references/dimensions/text.md)
|
||||||
| `warm` | Friendly, approachable | Orange, golden yellow, terracotta |
|
|
||||||
| `elegant` | Sophisticated, refined | Soft coral, muted teal, dusty rose |
|
|
||||||
| `cool` | Technical, professional | Engineering blue, navy, cyan |
|
|
||||||
| `dark` | Cinematic, premium | Electric purple, cyan, magenta |
|
|
||||||
| `earth` | Natural, organic | Forest green, sage, earth brown |
|
|
||||||
| `vivid` | Energetic, bold | Bright red, neon green, electric blue |
|
|
||||||
| `pastel` | Gentle, whimsical | Soft pink, mint, lavender |
|
|
||||||
| `mono` | Clean, focused | Black, near-black, white |
|
|
||||||
| `retro` | Nostalgic, vintage | Muted orange, dusty pink, maroon |
|
|
||||||
|
|
||||||
Palette definitions: [references/palettes/](references/palettes/)
|
**Mood Levels**: subtle (low contrast) | balanced (default) | bold (high contrast)
|
||||||
|
→ Details: [references/dimensions/mood.md](references/dimensions/mood.md)
|
||||||
|
|
||||||
## Rendering Gallery
|
**Fonts**: clean (sans-serif) | handwritten | serif | display (bold decorative)
|
||||||
|
→ Details: [references/dimensions/font.md](references/dimensions/font.md)
|
||||||
| Rendering | Description | Key Characteristics |
|
|
||||||
|-----------|-------------|---------------------|
|
|
||||||
| `flat-vector` | Clean modern vector | Uniform outlines, flat fills, geometric icons |
|
|
||||||
| `hand-drawn` | Sketchy organic illustration | Imperfect strokes, paper texture, doodles |
|
|
||||||
| `painterly` | Soft watercolor/paint | Brush strokes, color bleeds, soft edges |
|
|
||||||
| `digital` | Polished modern digital | Precise edges, subtle gradients, UI components |
|
|
||||||
| `pixel` | Retro 8-bit pixel art | Pixel grid, dithering, chunky shapes |
|
|
||||||
| `chalk` | Chalk on blackboard | Chalk strokes, dust effects, board texture |
|
|
||||||
|
|
||||||
Rendering definitions: [references/renderings/](references/renderings/)
|
|
||||||
|
|
||||||
## Text & Mood
|
|
||||||
|
|
||||||
| Text Level | Title | Subtitle | Tags | Use Case |
|
|
||||||
|------------|:-----:|:--------:|:----:|----------|
|
|
||||||
| `none` | - | - | - | Pure visual, no text |
|
|
||||||
| `title-only` | ✓ | - | - | Simple headline (default) |
|
|
||||||
| `title-subtitle` | ✓ | ✓ | - | Title + supporting context |
|
|
||||||
| `text-rich` | ✓ | ✓ | ✓ (2-4) | Information-dense |
|
|
||||||
|
|
||||||
| Mood | Contrast | Saturation | Weight | Use Case |
|
|
||||||
|------|:--------:|:----------:|:------:|----------|
|
|
||||||
| `subtle` | Low | Muted | Light | Corporate, thought leadership |
|
|
||||||
| `balanced` | Medium | Normal | Medium | General articles (default) |
|
|
||||||
| `bold` | High | Vivid | Heavy | Announcements, promotions |
|
|
||||||
|
|
||||||
Full guides: [references/dimensions/text.md](references/dimensions/text.md) | [references/dimensions/mood.md](references/dimensions/mood.md)
|
|
||||||
|
|
||||||
## Font Gallery
|
|
||||||
|
|
||||||
| Font | Description | Best For |
|
|
||||||
|------|-------------|----------|
|
|
||||||
| `clean` | Modern geometric sans-serif | Tech, professional, minimal |
|
|
||||||
| `handwritten` | Warm hand-lettered style | Personal, friendly, lifestyle |
|
|
||||||
| `serif` | Classic elegant typography | Editorial, academic, luxury |
|
|
||||||
| `display` | Bold decorative headlines | Announcements, entertainment |
|
|
||||||
|
|
||||||
Full guide: [references/dimensions/font.md](references/dimensions/font.md)
|
|
||||||
|
|
||||||
## Style Presets & Compatibility
|
|
||||||
|
|
||||||
- **Style Presets**: `--style X` expands to palette + rendering. See [references/style-presets.md](references/style-presets.md)
|
|
||||||
- **Compatibility Matrices**: Palette×Rendering, Type×Rendering, Type×Text, Type×Mood. See [references/compatibility.md](references/compatibility.md)
|
|
||||||
- ✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
|
|
||||||
|
|
||||||
## File Structure
|
## File Structure
|
||||||
|
|
||||||
Output directory depends on `default_output_dir` preference:
|
Output directory per `default_output_dir` preference:
|
||||||
|
- `same-dir`: `{article-dir}/`
|
||||||
| Preference | Output Path |
|
- `imgs-subdir`: `{article-dir}/imgs/`
|
||||||
|------------|-------------|
|
- `independent` (default): `cover-image/{topic-slug}/`
|
||||||
| `same-dir` | `{article-dir}/` |
|
|
||||||
| `imgs-subdir` | `{article-dir}/imgs/` |
|
|
||||||
| `independent` (default) | `cover-image/{topic-slug}/` |
|
|
||||||
| Pasted content | `cover-image/{topic-slug}/` (always) |
|
|
||||||
|
|
||||||
```
|
```
|
||||||
<output-dir>/
|
<output-dir>/
|
||||||
├── source-{slug}.{ext} # Source files (text, images, etc.)
|
├── source-{slug}.{ext} # Source files
|
||||||
├── refs/ # Reference images (if provided)
|
├── refs/ # Reference images (if provided)
|
||||||
│ ├── ref-01-{slug}.{ext}
|
│ ├── ref-01-{slug}.{ext}
|
||||||
│ ├── ref-01-{slug}.md # Description file (optional)
|
│ └── ref-01-{slug}.md # Description file
|
||||||
│ ├── ref-02-{slug}.{ext}
|
|
||||||
│ ├── ref-02-{slug}.md # Description file (optional)
|
|
||||||
│ └── extracted-style.md # Verbally extracted style (if no file path)
|
|
||||||
├── prompts/cover.md # Generation prompt
|
├── prompts/cover.md # Generation prompt
|
||||||
└── cover.png # Output image
|
└── cover.png # Output image
|
||||||
```
|
```
|
||||||
|
|
||||||
**Slug**: Extract main topic (2-4 words, kebab-case). Example: "The Future of AI" → `future-of-ai`
|
**Slug**: 2-4 words, kebab-case. Conflict: append `-YYYYMMDD-HHMMSS`
|
||||||
**Conflict**: If directory exists, append timestamp: `{topic-slug}-YYYYMMDD-HHMMSS`
|
|
||||||
**Source Files**: Copy all sources with naming `source-{slug}.{ext}` (multiple supported)
|
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
@@ -181,20 +106,10 @@ Output directory depends on `default_output_dir` preference:
|
|||||||
```
|
```
|
||||||
Cover Image Progress:
|
Cover Image Progress:
|
||||||
- [ ] Step 0: Check preferences (EXTEND.md) ⛔ BLOCKING
|
- [ ] Step 0: Check preferences (EXTEND.md) ⛔ BLOCKING
|
||||||
- [ ] Found → load preferences → continue
|
- [ ] Step 1: Analyze content + save refs + determine output dir
|
||||||
- [ ] Not found → run first-time setup → MUST complete before Step 1
|
- [ ] Step 2: Confirm options (6 dimensions) ⚠️ unless --quick
|
||||||
- [ ] Step 1: Analyze content + determine output directory
|
|
||||||
- [ ] 1.1 Reference images ⚠️ (if provided)
|
|
||||||
- [ ] File path given → saved to refs/ ✓
|
|
||||||
- [ ] No path → asked user OR extracted verbally
|
|
||||||
- [ ] 1.2 Output directory determined
|
|
||||||
- [ ] Step 2: Confirm options (6 dimensions) ⚠️ REQUIRED unless --quick or all specified
|
|
||||||
- [ ] Step 3: Create prompt
|
- [ ] Step 3: Create prompt
|
||||||
- [ ] References in prompt ONLY if files exist in refs/
|
|
||||||
- [ ] Extracted style/palette appended to prompt body (if no file)
|
|
||||||
- [ ] Step 4: Generate image
|
- [ ] Step 4: Generate image
|
||||||
- [ ] 4.1 References verified before generation
|
|
||||||
- [ ] 4.2 Pass refs via --ref if skill supports AND files exist
|
|
||||||
- [ ] Step 5: Completion report
|
- [ ] Step 5: Completion report
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -202,146 +117,40 @@ Cover Image Progress:
|
|||||||
|
|
||||||
```
|
```
|
||||||
Input → [Step 0: Preferences] ─┬─ Found → Continue
|
Input → [Step 0: Preferences] ─┬─ Found → Continue
|
||||||
│
|
└─ Not found → First-Time Setup ⛔ BLOCKING → Save EXTEND.md → Continue
|
||||||
└─ Not found → First-Time Setup ⛔ BLOCKING
|
|
||||||
│
|
|
||||||
└─ Complete setup → Save EXTEND.md → Continue
|
|
||||||
│
|
|
||||||
┌───────────────────────────────────────────────────────────────────────────┘
|
|
||||||
↓
|
↓
|
||||||
Analyze + Save Refs → [Output Dir ⚠️] → [Confirm: 6 Dimensions] → Prompt → Generate → Complete
|
Analyze + Save Refs → [Output Dir] → [Confirm: 6 Dimensions] → Prompt → Generate → Complete
|
||||||
↓
|
↓
|
||||||
(skip if --quick or all specified)
|
(skip if --quick or all specified)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 0: Load Preferences (EXTEND.md) ⛔ BLOCKING
|
### Step 0: Load Preferences ⛔ BLOCKING
|
||||||
|
|
||||||
**Purpose**: Load user preferences or run first-time setup.
|
|
||||||
|
|
||||||
**CRITICAL**: If EXTEND.md not found, MUST complete first-time setup before ANY other questions or steps. Do NOT proceed to content analysis, do NOT ask about reference images, do NOT ask about dimensions — ONLY complete the preferences setup first.
|
|
||||||
|
|
||||||
Use Bash to check EXTEND.md existence (priority order):
|
|
||||||
|
|
||||||
|
Check EXTEND.md existence (priority: project → user):
|
||||||
```bash
|
```bash
|
||||||
# Check project-level first
|
|
||||||
test -f .baoyu-skills/baoyu-cover-image/EXTEND.md && echo "project"
|
test -f .baoyu-skills/baoyu-cover-image/EXTEND.md && echo "project"
|
||||||
|
|
||||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
|
||||||
test -f "$HOME/.baoyu-skills/baoyu-cover-image/EXTEND.md" && echo "user"
|
test -f "$HOME/.baoyu-skills/baoyu-cover-image/EXTEND.md" && echo "user"
|
||||||
```
|
```
|
||||||
|
|
||||||
| Result | Action |
|
| Result | Action |
|
||||||
|--------|--------|
|
|--------|--------|
|
||||||
| Found | Read, parse, display preferences summary → Continue to Step 1 |
|
| Found | Load, display summary → Continue |
|
||||||
| Not found | ⛔ **BLOCKING**: Run first-time setup ONLY ([references/config/first-time-setup.md](references/config/first-time-setup.md)) → Complete and save EXTEND.md → Then continue to Step 1 |
|
| Not found | ⛔ Run first-time setup ([references/config/first-time-setup.md](references/config/first-time-setup.md)) → Save → Continue |
|
||||||
|
|
||||||
**Preferences Summary** (when found):
|
**CRITICAL**: If not found, complete setup BEFORE any other steps or questions.
|
||||||
|
|
||||||
```
|
|
||||||
Preferences loaded from [project/user]:
|
|
||||||
• Watermark: [enabled/disabled] [content if enabled]
|
|
||||||
• Type/Palette/Rendering: [value or "auto"]
|
|
||||||
• Text: [value or "title-only"] | Mood: [value or "balanced"]
|
|
||||||
• Aspect: [default_aspect] | Output: [dir or "not set — will ask in Step 1.5"]
|
|
||||||
• Quick mode: [enabled/disabled] | Language: [value or "auto"]
|
|
||||||
```
|
|
||||||
|
|
||||||
**EXTEND.md Supports**: Watermark | Preferred type | Preferred palette | Preferred rendering | Preferred text | Preferred mood | Preferred font | Default aspect ratio | Default output directory | Quick mode | Custom palette definitions | Language preference
|
|
||||||
|
|
||||||
Schema: [references/config/preferences-schema.md](references/config/preferences-schema.md)
|
|
||||||
|
|
||||||
### Step 1: Analyze Content
|
### Step 1: Analyze Content
|
||||||
|
|
||||||
**1.0 Detect & Save Reference Images** ⚠️ REQUIRED if images provided
|
1. **Save reference images** (if provided) → [references/workflow/reference-images.md](references/workflow/reference-images.md)
|
||||||
|
2. **Save source content** (if pasted, save to `source.md`)
|
||||||
Check if user provided reference images. Handle based on input type:
|
3. **Analyze content**: topic, tone, keywords, visual metaphors
|
||||||
|
4. **Deep analyze references** ⚠️: Extract specific, concrete elements (see reference-images.md)
|
||||||
| Input Type | Action |
|
5. **Detect language**: Compare source, user input, EXTEND.md preference
|
||||||
|------------|--------|
|
6. **Determine output directory**: Per File Structure rules
|
||||||
| Image file path provided | Copy to `refs/` subdirectory → can use `--ref` |
|
|
||||||
| Image in conversation (no path) | **ASK user for file path** with AskUserQuestion |
|
|
||||||
| User can't provide path | Extract style/palette verbally → append to prompt (NO frontmatter references) |
|
|
||||||
|
|
||||||
**CRITICAL**: Only add `references` to prompt frontmatter if files are ACTUALLY SAVED to `refs/` directory.
|
|
||||||
|
|
||||||
**If user provides file path**:
|
|
||||||
1. Copy to `refs/ref-NN-{slug}.{ext}` (NN = 01, 02, ...)
|
|
||||||
2. Create description: `refs/ref-NN-{slug}.md`
|
|
||||||
3. Verify files exist before proceeding
|
|
||||||
|
|
||||||
**If user can't provide path** (extracted verbally):
|
|
||||||
1. Analyze image visually, extract: colors, style, composition
|
|
||||||
2. Create `refs/extracted-style.md` with extracted info
|
|
||||||
3. DO NOT add `references` to prompt frontmatter
|
|
||||||
4. Instead, append extracted style/colors directly to prompt text
|
|
||||||
|
|
||||||
**Description File Format** (only when file saved):
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
ref_id: NN
|
|
||||||
filename: ref-NN-{slug}.{ext}
|
|
||||||
usage: direct | style | palette
|
|
||||||
---
|
|
||||||
[User's description or auto-generated description]
|
|
||||||
```
|
|
||||||
|
|
||||||
| Usage | When to Use |
|
|
||||||
|-------|-------------|
|
|
||||||
| `direct` | Reference matches desired output closely |
|
|
||||||
| `style` | Extract visual style characteristics only |
|
|
||||||
| `palette` | Extract color scheme only |
|
|
||||||
|
|
||||||
**Verification** (only for saved files):
|
|
||||||
```
|
|
||||||
Reference Images Saved:
|
|
||||||
- ref-01-{slug}.png ✓ (can use --ref)
|
|
||||||
- ref-02-{slug}.png ✓ (can use --ref)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Or for extracted style**:
|
|
||||||
```
|
|
||||||
Reference Style Extracted (no file):
|
|
||||||
- Colors: #E8756D coral, #7ECFC0 mint...
|
|
||||||
- Style: minimal flat vector, clean lines...
|
|
||||||
→ Will append to prompt text (not --ref)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**1.1 Save Source Content**
|
|
||||||
- If pasted, save to `source.md` in target directory; if file path, use as-is
|
|
||||||
- **Backup rule**: If `source.md` exists, rename to `source-backup-YYYYMMDD-HHMMSS.md`
|
|
||||||
|
|
||||||
**1.2 Content Analysis**
|
|
||||||
- Extract topic, core message, tone, keywords
|
|
||||||
- Identify visual metaphors
|
|
||||||
- Detect content type
|
|
||||||
|
|
||||||
**1.3 Reference Image Analysis** (if provided in Step 1.0)
|
|
||||||
|
|
||||||
For each reference image:
|
|
||||||
|
|
||||||
| Analysis | Description |
|
|
||||||
|----------|-------------|
|
|
||||||
| Visual characteristics | Style, colors, composition |
|
|
||||||
| Content/subject | What the reference depicts |
|
|
||||||
| Style match | Which type/palette/rendering align |
|
|
||||||
| Usage recommendation | `direct` / `style` / `palette` |
|
|
||||||
|
|
||||||
**1.4 Language Detection**
|
|
||||||
- Detect source language
|
|
||||||
- Note user's input language
|
|
||||||
- Compare with EXTEND.md preference
|
|
||||||
|
|
||||||
**1.5 Determine Output Directory**
|
|
||||||
- Per File Structure rules
|
|
||||||
- If no `default_output_dir` preference + file path input, include in Step 2 Q4
|
|
||||||
|
|
||||||
### Step 2: Confirm Options ⚠️
|
### Step 2: Confirm Options ⚠️
|
||||||
|
|
||||||
Validate all 6 dimensions + aspect ratio. Full confirmation flow: [references/workflow/confirm-options.md](references/workflow/confirm-options.md)
|
Full confirmation flow: [references/workflow/confirm-options.md](references/workflow/confirm-options.md)
|
||||||
|
|
||||||
**Skip Conditions**:
|
|
||||||
|
|
||||||
| Condition | Skipped | Still Asked |
|
| Condition | Skipped | Still Asked |
|
||||||
|-----------|---------|-------------|
|
|-----------|---------|-------------|
|
||||||
@@ -350,92 +159,24 @@ Validate all 6 dimensions + aspect ratio. Full confirmation flow: [references/wo
|
|||||||
|
|
||||||
### Step 3: Create Prompt
|
### Step 3: Create Prompt
|
||||||
|
|
||||||
**Backup rule**: If `prompts/cover.md` exists, rename to `prompts/cover-backup-YYYYMMDD-HHMMSS.md`
|
Save to `prompts/cover.md`. Template: [references/workflow/prompt-template.md](references/workflow/prompt-template.md)
|
||||||
|
|
||||||
Save to `prompts/cover.md`. Full template: [references/workflow/prompt-template.md](references/workflow/prompt-template.md)
|
**CRITICAL - References in Frontmatter**:
|
||||||
|
- Files saved to `refs/` → Add to frontmatter `references` list
|
||||||
|
- Style extracted verbally (no file) → Omit `references`, describe in body
|
||||||
|
- Before writing → Verify: `test -f refs/ref-NN-{slug}.{ext}`
|
||||||
|
|
||||||
**CRITICAL - References in YAML Frontmatter**:
|
**Reference elements in body** MUST be detailed, prefixed with "MUST"/"REQUIRED", with integration approach.
|
||||||
|
|
||||||
When reference files are saved to `refs/`, **MUST add `references` field in frontmatter**:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
type: cover
|
|
||||||
palette: warm
|
|
||||||
rendering: flat-vector
|
|
||||||
references:
|
|
||||||
- ref_id: 01
|
|
||||||
filename: refs/ref-01-podcast-thumbnail.jpg
|
|
||||||
usage: style
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
| Rule | Action |
|
|
||||||
|------|--------|
|
|
||||||
| Files saved to `refs/` | Add to frontmatter `references` list |
|
|
||||||
| Style extracted verbally (no file) | Omit `references` field, describe in body |
|
|
||||||
| Before writing | Verify: `test -f refs/ref-NN-{slug}.{ext}` |
|
|
||||||
|
|
||||||
**Reference Embedding**:
|
|
||||||
|
|
||||||
| Situation | Frontmatter | Body |
|
|
||||||
|-----------|-------------|------|
|
|
||||||
| Reference file saved to `refs/` | Add to `references` ✓ | Brief style note |
|
|
||||||
| Style extracted verbally (no file) | Omit `references` | Full style description |
|
|
||||||
| File in frontmatter but doesn't exist | ERROR - fix or remove | — |
|
|
||||||
|
|
||||||
### Step 4: Generate Image
|
### Step 4: Generate Image
|
||||||
|
|
||||||
**4.1 Backup existing** `cover.png` → `cover-backup-YYYYMMDD-HHMMSS.png` (if regenerating)
|
1. **Backup existing** `cover.png` if regenerating
|
||||||
|
2. **Check image generation skills**; if multiple, ask preference
|
||||||
**4.2 Check available image generation skills**; if multiple, ask user preference
|
3. **Process references** from prompt frontmatter:
|
||||||
|
- `direct` usage → pass via `--ref` (use ref-capable backend)
|
||||||
**4.3 Process References** ⚠️ REQUIRED if references in frontmatter
|
- `style`/`palette` → extract traits, append to prompt
|
||||||
|
4. **Generate**: Call skill with prompt file, output path, aspect ratio
|
||||||
**Read `references` from prompt frontmatter** and process each entry:
|
5. On failure: auto-retry once
|
||||||
|
|
||||||
1. **Parse frontmatter** to get references list:
|
|
||||||
```yaml
|
|
||||||
references:
|
|
||||||
- ref_id: 01
|
|
||||||
filename: refs/ref-01-podcast-thumbnail.jpg
|
|
||||||
usage: style
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **VERIFY each file exists**:
|
|
||||||
```bash
|
|
||||||
test -f refs/ref-NN-{slug}.{ext} && echo "exists" || echo "MISSING"
|
|
||||||
```
|
|
||||||
- If file MISSING → ERROR, fix prompt or remove from references
|
|
||||||
- If file exists → proceed with processing
|
|
||||||
|
|
||||||
3. Process based on `usage` type:
|
|
||||||
|
|
||||||
| Usage | Action | Example |
|
|
||||||
|-------|--------|---------|
|
|
||||||
| `direct` | Add reference path to `--ref` parameter | `--ref refs/ref-01-brand.png` |
|
|
||||||
| `style` | Analyze reference, append style traits to prompt | "Style: clean lines, gradient backgrounds..." |
|
|
||||||
| `palette` | Extract colors from reference, append to prompt | "Colors: #E8756D coral, #7ECFC0 mint..." |
|
|
||||||
|
|
||||||
3. Check image generation skill capability:
|
|
||||||
|
|
||||||
| Skill Supports `--ref` | Action |
|
|
||||||
|------------------------|--------|
|
|
||||||
| Yes (e.g., baoyu-image-gen with Google) | Pass reference images via `--ref` |
|
|
||||||
| No | Convert to text description, append to prompt |
|
|
||||||
|
|
||||||
**Verification**: Before generating, confirm reference processing:
|
|
||||||
```
|
|
||||||
Reference Processing:
|
|
||||||
- ref-01-brand.png: using as direct reference ✓
|
|
||||||
- ref-02-style.png: extracted palette ✓
|
|
||||||
```
|
|
||||||
|
|
||||||
**4.4 Generate**
|
|
||||||
|
|
||||||
1. Call selected skill with prompt file path, output path (`cover.png`), aspect ratio
|
|
||||||
2. If references with `direct` usage AND skill supports `--ref`: include `--ref` parameter
|
|
||||||
3. On failure: auto-retry once before reporting error
|
|
||||||
|
|
||||||
### Step 5: Completion Report
|
### Step 5: Completion Report
|
||||||
|
|
||||||
@@ -445,66 +186,48 @@ Cover Generated!
|
|||||||
Topic: [topic]
|
Topic: [topic]
|
||||||
Type: [type] | Palette: [palette] | Rendering: [rendering]
|
Type: [type] | Palette: [palette] | Rendering: [rendering]
|
||||||
Text: [text] | Mood: [mood] | Font: [font] | Aspect: [ratio]
|
Text: [text] | Mood: [mood] | Font: [font] | Aspect: [ratio]
|
||||||
Title: [title text or "visual only"]
|
Title: [title or "visual only"]
|
||||||
Language: [lang] | Watermark: [enabled/disabled]
|
Language: [lang] | Watermark: [enabled/disabled]
|
||||||
References: [N images (direct/style/palette) or "extracted style" or "none"]
|
References: [N images or "extracted style" or "none"]
|
||||||
Location: [directory path]
|
Location: [directory path]
|
||||||
|
|
||||||
Files:
|
Files:
|
||||||
✓ source-{slug}.{ext}
|
✓ source-{slug}.{ext}
|
||||||
[✓ refs/ref-01-{slug}.{ext} ... (if references saved)]
|
|
||||||
[✓ refs/ref-01-{slug}.md ... (description files)]
|
|
||||||
[✓ refs/extracted-style.md (if style extracted verbally)]
|
|
||||||
✓ prompts/cover.md
|
✓ prompts/cover.md
|
||||||
✓ cover.png
|
✓ cover.png
|
||||||
[✓ cover-backup-{timestamp}.png (if regenerated)]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Image Modification
|
## Image Modification
|
||||||
|
|
||||||
| Action | Steps |
|
| Action | Steps |
|
||||||
|--------|-------|
|
|--------|-------|
|
||||||
| **Regenerate** | Backup existing → **Update prompt file FIRST** → Regenerate with same settings |
|
| **Regenerate** | Backup → Update prompt file FIRST → Regenerate |
|
||||||
| **Change dimension** | Backup existing → Confirm new value → **Update prompt file FIRST** → Regenerate |
|
| **Change dimension** | Backup → Confirm new value → Update prompt → Regenerate |
|
||||||
|
|
||||||
**IMPORTANT**: When regenerating, ALWAYS update the prompt file (`prompts/cover.md`) FIRST before regenerating. This ensures changes are documented and reproducible.
|
## Composition Principles
|
||||||
|
|
||||||
All modifications automatically backup existing `cover.png` before regenerating.
|
- **Whitespace**: 40-60% breathing room
|
||||||
|
- **Visual anchor**: Main element centered or offset left
|
||||||
|
- **Characters**: Simplified silhouettes; NO realistic humans
|
||||||
|
- **Title**: Use exact title from user/source; never invent
|
||||||
|
|
||||||
## Notes
|
## Extension Support
|
||||||
|
|
||||||
- Cover must be readable at small preview sizes
|
Custom configurations via EXTEND.md. See **Step 0** for paths.
|
||||||
- Visual metaphors > literal representations
|
|
||||||
- Title: readable, impactful
|
|
||||||
- Two confirmation points: Step 0 (first-time setup) + Step 2 (6 dimensions) - skip Step 2 with `--quick`
|
|
||||||
- Use confirmed language for title text
|
|
||||||
- Maintain watermark consistency if enabled
|
|
||||||
- Check compatibility matrices when selecting combinations
|
|
||||||
- `--no-title` is alias for `--text none`
|
|
||||||
- `--style` presets are backward-compatible; explicit `--palette`/`--rendering` override preset values
|
|
||||||
|
|
||||||
### Composition Principles
|
Supports: Watermark | Preferred dimensions | Default aspect/output | Quick mode | Custom palettes | Language
|
||||||
|
|
||||||
- **Generous whitespace**: 40-60% breathing room; avoid cluttered layouts
|
Schema: [references/config/preferences-schema.md](references/config/preferences-schema.md)
|
||||||
- **Visual anchor**: Main element centered or offset left (reserve right for title)
|
|
||||||
- **Character handling**: Simplified silhouettes or icon-style figures; NO realistic humans
|
|
||||||
- **Icon vocabulary**: Use simple, recognizable symbols (see [references/visual-elements.md](references/visual-elements.md))
|
|
||||||
|
|
||||||
### Title Handling
|
|
||||||
|
|
||||||
- **Source**: Use the exact title provided by user, or extract from source content
|
|
||||||
- **Do NOT invent titles**: Stay faithful to the original
|
|
||||||
- If no title in source and user doesn't provide one, ask user to specify
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
**Dimensions**: [text.md](references/dimensions/text.md) | [mood.md](references/dimensions/mood.md) | [font.md](references/dimensions/font.md)
|
**Dimensions**: [text.md](references/dimensions/text.md) | [mood.md](references/dimensions/mood.md) | [font.md](references/dimensions/font.md)
|
||||||
**Palettes**: [references/palettes/](references/palettes/)
|
**Palettes**: [references/palettes/](references/palettes/)
|
||||||
**Renderings**: [references/renderings/](references/renderings/)
|
**Renderings**: [references/renderings/](references/renderings/)
|
||||||
|
**Types**: [references/types.md](references/types.md)
|
||||||
**Auto-Selection**: [references/auto-selection.md](references/auto-selection.md)
|
**Auto-Selection**: [references/auto-selection.md](references/auto-selection.md)
|
||||||
**Style Presets**: [references/style-presets.md](references/style-presets.md)
|
**Style Presets**: [references/style-presets.md](references/style-presets.md)
|
||||||
**Compatibility**: [references/compatibility.md](references/compatibility.md)
|
**Compatibility**: [references/compatibility.md](references/compatibility.md)
|
||||||
**Types**: [references/types.md](references/types.md)
|
|
||||||
**Visual Elements**: [references/visual-elements.md](references/visual-elements.md)
|
**Visual Elements**: [references/visual-elements.md](references/visual-elements.md)
|
||||||
**Workflow**: [confirm-options.md](references/workflow/confirm-options.md) | [prompt-template.md](references/workflow/prompt-template.md)
|
**Workflow**: [confirm-options.md](references/workflow/confirm-options.md) | [prompt-template.md](references/workflow/prompt-template.md) | [reference-images.md](references/workflow/reference-images.md)
|
||||||
**Config**: [preferences-schema.md](references/config/preferences-schema.md) | [first-time-setup.md](references/config/first-time-setup.md) | [watermark-guide.md](references/config/watermark-guide.md)
|
**Config**: [preferences-schema.md](references/config/preferences-schema.md) | [first-time-setup.md](references/config/first-time-setup.md) | [watermark-guide.md](references/config/watermark-guide.md)
|
||||||
|
|||||||
@@ -68,9 +68,15 @@ Palette notes: [key characteristics from palette definition]
|
|||||||
|
|
||||||
[Watermark section if enabled]
|
[Watermark section if enabled]
|
||||||
|
|
||||||
[Reference images section if provided — see below]
|
[Reference images section if provided — REQUIRED, see below]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Reference-Driven Design ⚠️ HIGH PRIORITY
|
||||||
|
|
||||||
|
When reference images are provided, they are the **primary visual input** and MUST strongly influence the output. The cover should look like it belongs to the same visual family as the references.
|
||||||
|
|
||||||
|
**Passing `--ref` alone is NOT enough.** Image generation models often ignore reference images unless the prompt text explicitly describes what to reproduce. Always combine `--ref` with detailed textual instructions.
|
||||||
|
|
||||||
## Content-Driven Design
|
## Content-Driven Design
|
||||||
|
|
||||||
- Article title and summary inform the visual metaphor choice
|
- Article title and summary inform the visual metaphor choice
|
||||||
@@ -175,63 +181,67 @@ For each reference image, extract:
|
|||||||
- **Color mood**: Palette characteristics (without specific colors)
|
- **Color mood**: Palette characteristics (without specific colors)
|
||||||
- **Elements**: Key visual elements and symbols used
|
- **Elements**: Key visual elements and symbols used
|
||||||
|
|
||||||
### Step 2: Embed in Prompt
|
### Step 2: Embed in Prompt ⚠️ CRITICAL
|
||||||
|
|
||||||
**If file saved AND skill supports `--ref`** (e.g., baoyu-image-gen with Google):
|
**Passing `--ref` alone is NOT enough.** Image generation models frequently ignore reference images unless the prompt text explicitly and forcefully describes what to reproduce. You MUST always write detailed textual instructions regardless of whether `--ref` is used.
|
||||||
- Pass ref images directly via `--ref` parameter
|
|
||||||
- Add brief style note in prompt:
|
**If file saved (with or without `--ref` support)**:
|
||||||
|
- Pass ref images via `--ref` parameter if skill supports it
|
||||||
|
- **ALWAYS** add a detailed mandatory section in the prompt body:
|
||||||
|
|
||||||
```
|
```
|
||||||
# Reference Style
|
# Reference Style — MUST INCORPORATE
|
||||||
Follow the visual style of the attached reference image(s):
|
|
||||||
- [1-2 sentence style summary from analysis]
|
CRITICAL: The generated cover MUST visually reference the provided images. The cover must feel like it belongs to the same visual family.
|
||||||
|
|
||||||
|
## From Ref 1 ([filename]) — REQUIRED elements:
|
||||||
|
- [Brand element]: [Specific description of logo/wordmark treatment, e.g., "The logo uses vertical parallel lines (|||) for the letter 'm'. Reproduce this exact treatment."]
|
||||||
|
- [Signature pattern]: [Specific description, e.g., "Woven intersecting curves forming a diamond/lozenge grid pattern. This MUST appear prominently as a banner, border, or background section."]
|
||||||
|
- [Colors]: [Exact hex values, e.g., "Dark teal #2D4A3E background, cream #F5F0E0 text"]
|
||||||
|
- [Typography]: [Specific treatment, e.g., "Uppercase text with wide letter-spacing"]
|
||||||
|
- [Layout element]: [Specific spatial element, e.g., "Bottom banner strip in dark color"]
|
||||||
|
|
||||||
|
## From Ref 2 ([filename]) — REQUIRED elements:
|
||||||
|
[Same detailed breakdown]
|
||||||
|
|
||||||
|
## Integration approach:
|
||||||
|
[Specific layout instruction describing how reference elements combine with the cover content, e.g., "Use a SPLIT LAYOUT: main illustration area (warm cream background) occupies ~65% of the image, while a dark teal BANNER STRIP (with the woven line pattern from Ref 2) runs along the bottom ~35%, containing branding elements from Ref 1."]
|
||||||
```
|
```
|
||||||
|
|
||||||
**If file saved BUT skill does NOT support `--ref`**:
|
**Key rules**:
|
||||||
- Embed detailed text description in prompt:
|
- Each visual element gets its own bullet with "MUST" or "REQUIRED"
|
||||||
|
- Descriptions must be **specific enough to reproduce** — not vague ("clean style")
|
||||||
```
|
- The integration approach must describe **exact spatial arrangement**
|
||||||
# Reference Style (Text Description)
|
- After generation, verify reference elements are visible; if not, strengthen and regenerate
|
||||||
Emulate the following visual style from reference image(s):
|
|
||||||
|
|
||||||
Reference 1: [filename]
|
|
||||||
- Style: [detailed rendering technique description]
|
|
||||||
- Composition: [layout and hierarchy description]
|
|
||||||
- Elements: [key visual elements used]
|
|
||||||
- Mood: [emotional tone and visual weight]
|
|
||||||
|
|
||||||
[Repeat for additional references]
|
|
||||||
|
|
||||||
Apply these style characteristics to the cover design while maintaining the specified Type, Palette, and Rendering dimensions.
|
|
||||||
```
|
|
||||||
|
|
||||||
**If style/palette extracted verbally (NO file saved)**:
|
**If style/palette extracted verbally (NO file saved)**:
|
||||||
- DO NOT add references metadata to prompt
|
- DO NOT add references metadata to prompt
|
||||||
- Append extracted info directly to prompt body:
|
- Append extracted info directly to prompt body using the same MUST INCORPORATE format above:
|
||||||
|
|
||||||
```
|
```
|
||||||
# Extracted Style (from reference)
|
# Reference Style — MUST INCORPORATE (extracted from visual analysis)
|
||||||
|
|
||||||
COLORS (from reference):
|
CRITICAL: Apply these specific visual elements extracted from the reference images.
|
||||||
- Primary: #E8756D coral
|
|
||||||
- Secondary: #7ECFC0 mint
|
|
||||||
...
|
|
||||||
|
|
||||||
STYLE (from reference):
|
## REQUIRED elements:
|
||||||
- Clean lines, minimal shadows
|
- [Same detailed bullet format as above]
|
||||||
- Gradient backgrounds
|
|
||||||
- Flat vector icons
|
## Integration approach:
|
||||||
...
|
[Same spatial layout instruction]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Reference Analysis Template
|
### Reference Analysis Template
|
||||||
|
|
||||||
Use this format when analyzing reference images:
|
Use this format when analyzing reference images. Extract **specific, concrete, reproducible** details — not vague summaries.
|
||||||
|
|
||||||
| Aspect | Analysis Points |
|
| Aspect | Analysis Points | Good Example | Bad Example |
|
||||||
|--------|-----------------|
|
|--------|-----------------|--------------|-------------|
|
||||||
| **Rendering** | Line quality (clean/sketchy/painted), texture presence, depth treatment |
|
| **Brand elements** | Logos, wordmarks, distinctive typography | "Logo 'm' formed by 3 vertical lines" | "Has a logo" |
|
||||||
| **Composition** | Element placement, whitespace ratio, visual flow |
|
| **Signature patterns** | Unique motifs, textures, geometric patterns | "Woven curves forming diamond grid" | "Has patterns" |
|
||||||
| **Typography** | Font style, text placement, hierarchy (if present) |
|
| **Colors** | Exact hex values or close approximations | "#2D4A3E dark teal, #F5F0E0 cream" | "Dark and light" |
|
||||||
| **Elements** | Icon vocabulary, decorative motifs, character style |
|
| **Layout** | Spatial zones, banner placement, proportions | "Bottom 30% is dark banner with branding" | "Has a banner" |
|
||||||
| **Mood** | Contrast level, saturation, visual weight |
|
| **Typography** | Font style, weight, case, spacing, position | "Uppercase, wide letter-spacing, right-aligned" | "Has text" |
|
||||||
|
| **Rendering** | Line quality, texture, depth treatment | "Topographic contour lines as background texture" | "Clean style" |
|
||||||
|
| **Elements** | Icon vocabulary, decorative motifs | "Geometric intersecting line ornaments at corners" | "Has decorations" |
|
||||||
|
|
||||||
|
**Output**: Each extracted element should be written as a **copy-pasteable prompt instruction** prefixed with "MUST" or "REQUIRED".
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# Reference Image Handling
|
||||||
|
|
||||||
|
Guide for processing user-provided reference images in cover generation.
|
||||||
|
|
||||||
|
## Input Detection
|
||||||
|
|
||||||
|
| Input Type | Action |
|
||||||
|
|------------|--------|
|
||||||
|
| Image file path provided | Copy to `refs/` → can use `--ref` |
|
||||||
|
| Image in conversation (no path) | **ASK user for file path** with AskUserQuestion |
|
||||||
|
| User can't provide path | Extract style/palette verbally → append to prompt (NO frontmatter references) |
|
||||||
|
|
||||||
|
**CRITICAL**: Only add `references` to prompt frontmatter if files are ACTUALLY SAVED to `refs/` directory.
|
||||||
|
|
||||||
|
## File Saving
|
||||||
|
|
||||||
|
**If user provides file path**:
|
||||||
|
1. Copy to `refs/ref-NN-{slug}.{ext}` (NN = 01, 02, ...)
|
||||||
|
2. Create description: `refs/ref-NN-{slug}.md`
|
||||||
|
3. Verify files exist before proceeding
|
||||||
|
|
||||||
|
**Description File Format**:
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
ref_id: NN
|
||||||
|
filename: ref-NN-{slug}.{ext}
|
||||||
|
usage: direct | style | palette
|
||||||
|
---
|
||||||
|
[User's description or auto-generated description]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Usage | When to Use |
|
||||||
|
|-------|-------------|
|
||||||
|
| `direct` | Reference matches desired output closely |
|
||||||
|
| `style` | Extract visual style characteristics only |
|
||||||
|
| `palette` | Extract color scheme only |
|
||||||
|
|
||||||
|
## Verbal Extraction (No File)
|
||||||
|
|
||||||
|
When user can't provide file path:
|
||||||
|
1. Analyze image visually, extract: colors, style, composition
|
||||||
|
2. Create `refs/extracted-style.md` with extracted info
|
||||||
|
3. DO NOT add `references` to prompt frontmatter
|
||||||
|
4. Append extracted style/colors directly to prompt text
|
||||||
|
|
||||||
|
## Deep Analysis ⚠️ CRITICAL
|
||||||
|
|
||||||
|
References are high-priority inputs. Extract **specific, concrete, reproducible** elements:
|
||||||
|
|
||||||
|
| Analysis | Description | Example (good vs bad) |
|
||||||
|
|----------|-------------|----------------------|
|
||||||
|
| **Brand elements** | Logos, wordmarks, specific typography | Good: "Logo uses vertical parallel lines for 'm'" / Bad: "Has a logo" |
|
||||||
|
| **Signature patterns** | Unique decorative motifs, textures | Good: "Woven intersecting curves forming diamond grid" / Bad: "Has patterns" |
|
||||||
|
| **Color palette** | Exact hex values for key colors | Good: "#2D4A3E dark teal, #F5F0E0 cream" / Bad: "Dark and light colors" |
|
||||||
|
| **Layout structure** | Specific spatial arrangement | Good: "Bottom 30% dark banner with branding" / Bad: "Has a banner" |
|
||||||
|
| **Typography** | Font style, weight, spacing, case | Good: "Uppercase, wide letter-spacing" / Bad: "Has text" |
|
||||||
|
| **Content/subject** | What the reference depicts | Factual description |
|
||||||
|
| **Usage recommendation** | `direct` / `style` / `palette` | Based on analysis |
|
||||||
|
|
||||||
|
**Output format**: List each element as bullet that can be copy-pasted into prompt as mandatory instruction.
|
||||||
|
|
||||||
|
## Verification Output
|
||||||
|
|
||||||
|
**For saved files**:
|
||||||
|
```
|
||||||
|
Reference Images Saved:
|
||||||
|
- ref-01-{slug}.png ✓ (can use --ref)
|
||||||
|
- ref-02-{slug}.png ✓ (can use --ref)
|
||||||
|
```
|
||||||
|
|
||||||
|
**For extracted style**:
|
||||||
|
```
|
||||||
|
Reference Style Extracted (no file):
|
||||||
|
- Colors: #E8756D coral, #7ECFC0 mint...
|
||||||
|
- Style: minimal flat vector, clean lines...
|
||||||
|
→ Will append to prompt text (not --ref)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Priority Rules
|
||||||
|
|
||||||
|
When user provides references, they are **HIGH PRIORITY**:
|
||||||
|
|
||||||
|
- **References override defaults**: If reference conflicts with preferred palette/rendering, reference takes precedence
|
||||||
|
- **Concrete > abstract**: Extract specific elements — not vague "clean style"
|
||||||
|
- **Mandatory language**: Use "MUST", "REQUIRED" in prompt for reference elements
|
||||||
|
- **Visible in output**: Verify elements are present after generation; strengthen prompt if not
|
||||||
@@ -60,9 +60,12 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --quali
|
|||||||
# From prompt files
|
# From prompt files
|
||||||
npx -y bun ${SKILL_DIR}/scripts/main.ts --promptfiles system.md content.md --image out.png
|
npx -y bun ${SKILL_DIR}/scripts/main.ts --promptfiles system.md content.md --image out.png
|
||||||
|
|
||||||
# With reference images (Google multimodal only)
|
# With reference images (Google multimodal or OpenAI edits)
|
||||||
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Make blue" --image out.png --ref source.png
|
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Make blue" --image out.png --ref source.png
|
||||||
|
|
||||||
|
# With reference images (explicit provider/model)
|
||||||
|
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Make blue" --image out.png --provider google --model gemini-3-pro-image-preview --ref source.png
|
||||||
|
|
||||||
# Specific provider
|
# Specific provider
|
||||||
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider openai
|
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider openai
|
||||||
|
|
||||||
@@ -78,12 +81,12 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "一只可爱的猫" --image ou
|
|||||||
| `--promptfiles <files...>` | Read prompt from files (concatenated) |
|
| `--promptfiles <files...>` | Read prompt from files (concatenated) |
|
||||||
| `--image <path>` | Output image path (required) |
|
| `--image <path>` | Output image path (required) |
|
||||||
| `--provider google\|openai\|dashscope` | Force provider (default: google) |
|
| `--provider google\|openai\|dashscope` | Force provider (default: google) |
|
||||||
| `--model <id>`, `-m` | Model ID |
|
| `--model <id>`, `-m` | Model ID (`--ref` with OpenAI requires GPT Image model, e.g. `gpt-image-1.5`) |
|
||||||
| `--ar <ratio>` | Aspect ratio (e.g., `16:9`, `1:1`, `4:3`) |
|
| `--ar <ratio>` | Aspect ratio (e.g., `16:9`, `1:1`, `4:3`) |
|
||||||
| `--size <WxH>` | Size (e.g., `1024x1024`) |
|
| `--size <WxH>` | Size (e.g., `1024x1024`) |
|
||||||
| `--quality normal\|2k` | Quality preset (default: 2k) |
|
| `--quality normal\|2k` | Quality preset (default: 2k) |
|
||||||
| `--imageSize 1K\|2K\|4K` | Image size for Google (default: from quality) |
|
| `--imageSize 1K\|2K\|4K` | Image size for Google (default: from quality) |
|
||||||
| `--ref <files...>` | Reference images (Google multimodal only) |
|
| `--ref <files...>` | Reference images. Supported by Google multimodal and OpenAI edits (GPT Image models). If provider omitted: Google first, then OpenAI |
|
||||||
| `--n <count>` | Number of images |
|
| `--n <count>` | Number of images |
|
||||||
| `--json` | JSON output |
|
| `--json` | JSON output |
|
||||||
|
|
||||||
@@ -105,9 +108,10 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "一只可爱的猫" --image ou
|
|||||||
|
|
||||||
## Provider Selection
|
## Provider Selection
|
||||||
|
|
||||||
1. `--provider` specified → use it
|
1. `--ref` provided + no `--provider` → auto-select Google first, then OpenAI
|
||||||
2. Only one API key available → use that provider
|
2. `--provider` specified → use it (if `--ref`, must be `google` or `openai`)
|
||||||
3. Multiple available → default to Google
|
3. Only one API key available → use that provider
|
||||||
|
4. Multiple available → default to Google
|
||||||
|
|
||||||
## Quality Presets
|
## Quality Presets
|
||||||
|
|
||||||
@@ -157,7 +161,7 @@ Supported: `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `2.35:1`
|
|||||||
- Missing API key → error with setup instructions
|
- Missing API key → error with setup instructions
|
||||||
- Generation failure → auto-retry once
|
- Generation failure → auto-retry once
|
||||||
- Invalid aspect ratio → warning, proceed with default
|
- Invalid aspect ratio → warning, proceed with default
|
||||||
- Reference images with non-multimodal model → warning, ignore refs
|
- Reference images with unsupported provider/model → error with fix hint (switch to Google multimodal or OpenAI GPT Image edits)
|
||||||
|
|
||||||
## Extension Support
|
## Extension Support
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import process from "node:process";
|
import process from "node:process";
|
||||||
import { homedir } from "node:os";
|
import { homedir } from "node:os";
|
||||||
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
||||||
import type { CliArgs, Provider, ExtendConfig } from "./types";
|
import type { CliArgs, Provider, ExtendConfig } from "./types";
|
||||||
|
|
||||||
function printUsage(): void {
|
function printUsage(): void {
|
||||||
@@ -20,7 +20,7 @@ Options:
|
|||||||
--size <WxH> Size (e.g., 1024x1024)
|
--size <WxH> Size (e.g., 1024x1024)
|
||||||
--quality normal|2k Quality preset (default: 2k)
|
--quality normal|2k Quality preset (default: 2k)
|
||||||
--imageSize 1K|2K|4K Image size for Google (default: from quality)
|
--imageSize 1K|2K|4K Image size for Google (default: from quality)
|
||||||
--ref <files...> Reference images (Google multimodal only)
|
--ref <files...> Reference images (Google multimodal or OpenAI edits)
|
||||||
--n <count> Number of images (default: 1)
|
--n <count> Number of images (default: 1)
|
||||||
--json JSON output
|
--json JSON output
|
||||||
-h, --help Show help
|
-h, --help Show help
|
||||||
@@ -323,12 +323,26 @@ function normalizeOutputImagePath(p: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function detectProvider(args: CliArgs): Provider {
|
function detectProvider(args: CliArgs): Provider {
|
||||||
|
if (args.referenceImages.length > 0 && args.provider && args.provider !== "google" && args.provider !== "openai") {
|
||||||
|
throw new Error(
|
||||||
|
"Reference images require a ref-capable provider. Use --provider google (Gemini multimodal) or --provider openai (GPT Image edits)."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (args.provider) return args.provider;
|
if (args.provider) return args.provider;
|
||||||
|
|
||||||
const hasGoogle = !!(process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY);
|
const hasGoogle = !!(process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY);
|
||||||
const hasOpenai = !!process.env.OPENAI_API_KEY;
|
const hasOpenai = !!process.env.OPENAI_API_KEY;
|
||||||
const hasDashscope = !!process.env.DASHSCOPE_API_KEY;
|
const hasDashscope = !!process.env.DASHSCOPE_API_KEY;
|
||||||
|
|
||||||
|
if (args.referenceImages.length > 0) {
|
||||||
|
if (hasGoogle) return "google";
|
||||||
|
if (hasOpenai) return "openai";
|
||||||
|
throw new Error(
|
||||||
|
"Reference images require Google or OpenAI. Set GOOGLE_API_KEY/GEMINI_API_KEY or OPENAI_API_KEY, or remove --ref."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const available = [hasGoogle && "google", hasOpenai && "openai", hasDashscope && "dashscope"].filter(Boolean) as Provider[];
|
const available = [hasGoogle && "google", hasOpenai && "openai", hasDashscope && "dashscope"].filter(Boolean) as Provider[];
|
||||||
|
|
||||||
if (available.length === 1) return available[0]!;
|
if (available.length === 1) return available[0]!;
|
||||||
@@ -340,11 +354,34 @@ function detectProvider(args: CliArgs): Provider {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function validateReferenceImages(referenceImages: string[]): Promise<void> {
|
||||||
|
for (const refPath of referenceImages) {
|
||||||
|
const fullPath = path.resolve(refPath);
|
||||||
|
try {
|
||||||
|
await access(fullPath);
|
||||||
|
} catch {
|
||||||
|
throw new Error(`Reference image not found: ${fullPath}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ProviderModule = {
|
type ProviderModule = {
|
||||||
getDefaultModel: () => string;
|
getDefaultModel: () => string;
|
||||||
generateImage: (prompt: string, model: string, args: CliArgs) => Promise<Uint8Array>;
|
generateImage: (prompt: string, model: string, args: CliArgs) => Promise<Uint8Array>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isRetryableGenerationError(error: unknown): boolean {
|
||||||
|
const msg = error instanceof Error ? error.message : String(error);
|
||||||
|
const nonRetryableMarkers = [
|
||||||
|
"Reference image",
|
||||||
|
"not supported",
|
||||||
|
"only supported",
|
||||||
|
"No API key found",
|
||||||
|
"is required",
|
||||||
|
];
|
||||||
|
return !nonRetryableMarkers.some((marker) => msg.includes(marker));
|
||||||
|
}
|
||||||
|
|
||||||
async function loadProviderModule(provider: Provider): Promise<ProviderModule> {
|
async function loadProviderModule(provider: Provider): Promise<ProviderModule> {
|
||||||
if (provider === "google") {
|
if (provider === "google") {
|
||||||
return (await import("./providers/google")) as ProviderModule;
|
return (await import("./providers/google")) as ProviderModule;
|
||||||
@@ -387,6 +424,10 @@ async function main(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mergedArgs.referenceImages.length > 0) {
|
||||||
|
await validateReferenceImages(mergedArgs.referenceImages);
|
||||||
|
}
|
||||||
|
|
||||||
const provider = detectProvider(mergedArgs);
|
const provider = detectProvider(mergedArgs);
|
||||||
const providerModule = await loadProviderModule(provider);
|
const providerModule = await loadProviderModule(provider);
|
||||||
|
|
||||||
@@ -408,7 +449,7 @@ async function main(): Promise<void> {
|
|||||||
imageData = await providerModule.generateImage(prompt, model, mergedArgs);
|
imageData = await providerModule.generateImage(prompt, model, mergedArgs);
|
||||||
break;
|
break;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!retried) {
|
if (!retried && isRetryableGenerationError(e)) {
|
||||||
retried = true;
|
retried = true;
|
||||||
console.error("Generation failed, retrying...");
|
console.error("Generation failed, retrying...");
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ export async function generateImage(
|
|||||||
if (!apiKey) throw new Error("DASHSCOPE_API_KEY is required");
|
if (!apiKey) throw new Error("DASHSCOPE_API_KEY is required");
|
||||||
|
|
||||||
if (args.referenceImages.length > 0) {
|
if (args.referenceImages.length > 0) {
|
||||||
console.error("Warning: Reference images not yet supported with DashScope, ignoring.");
|
throw new Error(
|
||||||
|
"Reference images are not supported with DashScope provider in baoyu-image-gen. Use --provider google with a Gemini multimodal model."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const size = args.size ? normalizeSize(args.size) : getSizeFromAspectRatio(args.aspectRatio, args.quality);
|
const size = args.size ? normalizeSize(args.size) : getSizeFromAspectRatio(args.aspectRatio, args.quality);
|
||||||
|
|||||||
@@ -216,13 +216,17 @@ export async function generateImage(
|
|||||||
): Promise<Uint8Array> {
|
): Promise<Uint8Array> {
|
||||||
if (isGoogleImagen(model)) {
|
if (isGoogleImagen(model)) {
|
||||||
if (args.referenceImages.length > 0) {
|
if (args.referenceImages.length > 0) {
|
||||||
console.error("Warning: Reference images not supported with Imagen models, ignoring.");
|
throw new Error(
|
||||||
|
"Reference images are not supported with Imagen models. Use gemini-3-pro-image-preview or gemini-3-flash-preview."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return generateWithImagen(prompt, model, args);
|
return generateWithImagen(prompt, model, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isGoogleMultimodal(model) && args.referenceImages.length > 0) {
|
if (!isGoogleMultimodal(model) && args.referenceImages.length > 0) {
|
||||||
console.error("Warning: Reference images are only supported with Gemini multimodal models.");
|
throw new Error(
|
||||||
|
"Reference images are only supported with Gemini multimodal models. Use gemini-3-pro-image-preview or gemini-3-flash-preview."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return generateWithGemini(prompt, model, args);
|
return generateWithGemini(prompt, model, args);
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
import { readFile } from "node:fs/promises";
|
||||||
import type { CliArgs } from "../types";
|
import type { CliArgs } from "../types";
|
||||||
|
|
||||||
export function getDefaultModel(): string {
|
export function getDefaultModel(): string {
|
||||||
return process.env.OPENAI_IMAGE_MODEL || "gpt-image-1.5";
|
return process.env.OPENAI_IMAGE_MODEL || "gpt-image-1.5";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OpenAIImageResponse = { data: Array<{ url?: string; b64_json?: string }> };
|
||||||
|
|
||||||
function parseAspectRatio(ar: string): { width: number; height: number } | null {
|
function parseAspectRatio(ar: string): { width: number; height: number } | null {
|
||||||
const match = ar.match(/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/);
|
const match = ar.match(/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/);
|
||||||
if (!match) return null;
|
if (!match) return null;
|
||||||
@@ -66,20 +70,32 @@ export async function generateImage(
|
|||||||
|
|
||||||
if (!apiKey) throw new Error("OPENAI_API_KEY is required");
|
if (!apiKey) throw new Error("OPENAI_API_KEY is required");
|
||||||
|
|
||||||
if (args.referenceImages.length > 0) {
|
|
||||||
console.error("Warning: Reference images not supported with OpenAI, ignoring.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const size = args.size || getOpenAISize(model, args.aspectRatio, args.quality);
|
const size = args.size || getOpenAISize(model, args.aspectRatio, args.quality);
|
||||||
|
|
||||||
const body: Record<string, any> = {
|
if (args.referenceImages.length > 0) {
|
||||||
model,
|
if (model.includes("dall-e-2") || model.includes("dall-e-3")) {
|
||||||
prompt,
|
throw new Error(
|
||||||
size,
|
"Reference images with OpenAI in this skill require GPT Image models. Use --model gpt-image-1.5 (or another gpt-image model)."
|
||||||
};
|
);
|
||||||
|
}
|
||||||
|
return generateWithOpenAIEdits(baseURL, apiKey, prompt, model, size, args.referenceImages, args.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
return generateWithOpenAIGenerations(baseURL, apiKey, prompt, model, size, args.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateWithOpenAIGenerations(
|
||||||
|
baseURL: string,
|
||||||
|
apiKey: string,
|
||||||
|
prompt: string,
|
||||||
|
model: string,
|
||||||
|
size: string,
|
||||||
|
quality: CliArgs["quality"]
|
||||||
|
): Promise<Uint8Array> {
|
||||||
|
const body: Record<string, any> = { model, prompt, size };
|
||||||
|
|
||||||
if (model.includes("dall-e-3")) {
|
if (model.includes("dall-e-3")) {
|
||||||
body.quality = args.quality === "2k" ? "hd" : "standard";
|
body.quality = quality === "2k" ? "hd" : "standard";
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`${baseURL}/images/generations`, {
|
const res = await fetch(`${baseURL}/images/generations`, {
|
||||||
@@ -96,7 +112,62 @@ export async function generateImage(
|
|||||||
throw new Error(`OpenAI API error: ${err}`);
|
throw new Error(`OpenAI API error: ${err}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = (await res.json()) as { data: Array<{ url?: string; b64_json?: string }> };
|
const result = (await res.json()) as OpenAIImageResponse;
|
||||||
|
return extractImageFromResponse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateWithOpenAIEdits(
|
||||||
|
baseURL: string,
|
||||||
|
apiKey: string,
|
||||||
|
prompt: string,
|
||||||
|
model: string,
|
||||||
|
size: string,
|
||||||
|
referenceImages: string[],
|
||||||
|
quality: CliArgs["quality"]
|
||||||
|
): Promise<Uint8Array> {
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("model", model);
|
||||||
|
form.append("prompt", prompt);
|
||||||
|
form.append("size", size);
|
||||||
|
|
||||||
|
if (model.includes("gpt-image")) {
|
||||||
|
form.append("quality", quality === "2k" ? "high" : "medium");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const refPath of referenceImages) {
|
||||||
|
const bytes = await readFile(refPath);
|
||||||
|
const filename = path.basename(refPath);
|
||||||
|
const mimeType = getMimeType(filename);
|
||||||
|
const blob = new Blob([bytes], { type: mimeType });
|
||||||
|
form.append("image[]", blob, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(`${baseURL}/images/edits`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${apiKey}`,
|
||||||
|
},
|
||||||
|
body: form,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
const err = await res.text();
|
||||||
|
throw new Error(`OpenAI edits API error: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = (await res.json()) as OpenAIImageResponse;
|
||||||
|
return extractImageFromResponse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMimeType(filename: string): string {
|
||||||
|
const ext = path.extname(filename).toLowerCase();
|
||||||
|
if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
|
||||||
|
if (ext === ".webp") return "image/webp";
|
||||||
|
if (ext === ".gif") return "image/gif";
|
||||||
|
return "image/png";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function extractImageFromResponse(result: OpenAIImageResponse): Promise<Uint8Array> {
|
||||||
const img = result.data[0];
|
const img = result.data[0];
|
||||||
|
|
||||||
if (img?.b64_json) {
|
if (img?.b64_json) {
|
||||||
|
|||||||
Reference in New Issue
Block a user