Compare commits

..

25 Commits

Author SHA1 Message Date
Jim Liu 宝玉 5e597f0a8b chore: release v1.23.0 2026-01-26 11:36:06 -06:00
Jim Liu 宝玉 40f4d2f730 refactor(baoyu-cover-image): replace 20 styles with 5D palette×rendering system
Migrate from 4-dimension (Type×Style×Text×Mood) to 5-dimension
(Type×Palette×Rendering×Text×Mood) system. 9 palettes × 6 renderings
= 54 combinations replacing 20 fixed styles. Add style presets for
backward compatibility, v2→v3 schema migration, and new reference
structure (palettes/, renderings/, workflow/).
2026-01-26 11:32:30 -06:00
Jim Liu 宝玉 b12ae7374d chore: release v1.22.0 2026-01-25 21:05:37 -06:00
Jim Liu 宝玉 1afa6f5a58 refactor(baoyu-post-to-x): simplify image placeholders from bracket format to XIMGPH 2026-01-25 21:05:08 -06:00
Jim Liu 宝玉 977598d5ae feat(baoyu-post-to-wechat): add theme selection, HTML preview, and simplify image placeholders 2026-01-25 21:05:04 -06:00
Jim Liu 宝玉 eb738aa61a feat(baoyu-cover-image): add default_output_dir preference with output directory selection 2026-01-25 21:04:59 -06:00
Jim Liu 宝玉 e9a030f917 feat(baoyu-article-illustrator): add imgs-subdir output option and improve style selection 2026-01-25 21:04:56 -06:00
Jim Liu 宝玉 e6a9b217e6 chore: release v1.21.4 2026-01-25 16:10:08 -06:00
Jim Liu 宝玉 ec1743592c fix(baoyu-post-to-wechat): fix regressions from Windows compatibility PR
- Fix broken md-to-wechat-fixed.ts/wechat-article-fixed.ts filename
  references that cause runtime crash (files were never renamed)
- Restore frontmatter quote stripping for title/summary values
- Restore --title CLI parameter functionality (was silently ignored)
- Fix summary extraction to properly skip headings, quotes, lists
- Fix argument parsing to reject single-dash args as file paths
- Remove debug console.error logs left from development
2026-01-25 16:09:24 -06:00
Jim Liu 宝玉 fe647a11bb Merge pull request #20 from JadeLiang003/fix/windows-copy-paste-support
Fix: Windows compatibility for baoyu-post-to-wechat
2026-01-25 16:04:01 -06:00
JadeLiang 5a11b49b00 Fix: Windows compatibility for baoyu-post-to-wechat
## Problem
The baoyu-post-to-wechat skill failed on Windows due to:
1. `new URL(import.meta.url).pathname` returns incorrect path format on Windows
2. Copy/paste operations used `xdotool` (Linux tool) which doesn't exist on Windows

## Solution
1. **md-to-wechat.ts**: Use `fileURLToPath()` to correctly resolve file paths on Windows
2. **wechat-article.ts**: Use CDP `Input.dispatchKeyEvent` for copy/paste operations
   - Replaces system-dependent tools (xdotool/osascript)
   - Works consistently across Windows/macOS/Linux
   - More reliable as it operates within Chrome session

## Changes
- Import `fileURLToPath` from 'node:url'
- Replace `new URL(import.meta.url).pathname` with `fileURLToPath(import.meta.url)`
- Replace system tool calls with CDP keyboard events for Ctrl+C and Ctrl+V
- Add platform-specific modifier handling (Cmd for macOS, Ctrl for Windows/Linux)

## Testing
- Tested successfully on Windows 11
- Markdown conversion works correctly
- HTML copy/paste to WeChat editor works correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-25 15:24:04 +08:00
Jim Liu 宝玉 04692515bb fix: remove opacity of watermark 2026-01-24 17:23:04 -06:00
Jim Liu 宝玉 eb54c2a2e7 chore: release v1.21.3 2026-01-24 17:20:02 -06:00
Jim Liu 宝玉 a39c8eb0bd refactor(baoyu-article-illustrator): extract content to reference files
- Simplify SKILL.md by extracting usage and prompt templates
- Add references/usage.md for command syntax
- Add references/prompt-construction.md for prompt templates
- Add default_output_dir preference option
- Reorganize workflow from 5 to 6 steps with Pre-check phase
2026-01-24 17:19:42 -06:00
Jim Liu 宝玉 715555c2ab chore: release v1.21.2 2026-01-24 13:37:58 -06:00
Jim Liu 宝玉 02b039f2ff feat(baoyu-image-gen): add parallel generation documentation 2026-01-24 13:37:42 -06:00
Jim Liu 宝玉 00306414fe docs(release-skills): add skill grouping and user confirmation workflow 2026-01-24 13:37:38 -06:00
Jim Liu 宝玉 db1179e057 chore: release v1.21.1 2026-01-24 13:25:15 -06:00
Jim Liu 宝玉 7b0c9ca372 chore: release v1.21.0 2026-01-24 03:33:10 -06:00
Jim Liu 宝玉 e7255efdd6 chore: release v1.20.0 2026-01-24 02:30:28 -06:00
Jim Liu 宝玉 b15a95e73d chore: release v1.19.0 2026-01-24 01:24:41 -06:00
Jim Liu 宝玉 07af3c4c21 chore: release v1.18.3 2026-01-23 21:08:11 -06:00
Jim Liu 宝玉 7842e4d188 chore: release v1.18.2 2026-01-23 16:10:04 -06:00
Jim Liu 宝玉 fcd49cd5ea chore: release v1.18.1 2026-01-23 14:59:23 -06:00
Jim Liu 宝玉 f454257b5c chore: release v1.18.0 2026-01-23 14:32:21 -06:00
97 changed files with 6001 additions and 3386 deletions
+1 -1
View File
@@ -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.17.1" "version": "1.23.0"
}, },
"plugins": [ "plugins": [
{ {
+141 -39
View File
@@ -186,18 +186,61 @@ Japanese (CHANGELOG.ja.md):
- コネクションプールのメモリリークを修正 - コネクションプールのメモリリークを修正
``` ```
### Step 5: Check README Updates ### Step 5: Group Changes by Skill/Module
**IMPORTANT**: Before updating version file, check if README needs updates. Analyze commits since last tag and group by affected skill/module:
1. **Scan for README files**: `README*.md` in project root 1. **Identify changed files** per commit
2. **For each skill/feature changed**, check if README documentation matches: 2. **Group by skill/module**:
- Options/flags documented correctly - `skills/<skill-name>/*` → Group under that skill
- Usage examples reflect current syntax - Root files (CLAUDE.md, etc.) → Group as "project"
- Feature descriptions are accurate - Multiple skills in one commit → Split into multiple groups
3. **If README is outdated**: 3. **For each group**, identify related README updates needed
- Update README.md (and README.zh.md if exists) to reflect changes
- Include in release commit **Example Grouping**:
```
baoyu-cover-image:
- feat: add new style options
- fix: handle transparent backgrounds
→ README updates: options table
baoyu-comic:
- refactor: improve panel layout algorithm
→ No README updates needed
project:
- docs: update CLAUDE.md architecture section
```
### Step 6: Commit Each Skill/Module Separately
For each skill/module group (in order of changes):
1. **Check README updates needed**:
- Scan `README*.md` for mentions of this skill/module
- Verify options/flags documented correctly
- Update usage examples if syntax changed
- Update feature descriptions if behavior changed
2. **Stage and commit**:
```bash
git add skills/<skill-name>/*
git add README.md README.zh.md # If updated for this skill
git commit -m "<type>(<skill-name>): <meaningful description>"
```
3. **Commit message format**:
- Use conventional commit format: `<type>(<scope>): <description>`
- `<type>`: feat, fix, refactor, docs, perf, etc.
- `<scope>`: skill name or "project"
- `<description>`: Clear, meaningful description of changes
**Example Commits**:
```bash
git commit -m "feat(baoyu-cover-image): add watercolor and minimalist styles"
git commit -m "fix(baoyu-comic): improve panel layout for long dialogues"
git commit -m "docs(project): update architecture documentation"
```
**Common README Updates Needed**: **Common README Updates Needed**:
| Change Type | README Section to Check | | Change Type | README Section to Check |
@@ -208,11 +251,13 @@ Japanese (CHANGELOG.ja.md):
| Breaking changes | Migration notes, deprecation warnings | | Breaking changes | Migration notes, deprecation warnings |
| Restructured internals | Architecture section (if exposed to users) | | Restructured internals | Architecture section (if exposed to users) |
### Step 6: Update Version File ### Step 7: Generate Changelog and Update Version
1. Read version file (JSON/TOML/text) 1. **Generate multi-language changelogs** (as described in Step 4)
2. Update version number 2. **Update version file**:
3. Write back (preserve formatting) - Read version file (JSON/TOML/text)
- Update version number
- Write back (preserve formatting)
**Version Paths by File Type**: **Version Paths by File Type**:
@@ -224,25 +269,77 @@ Japanese (CHANGELOG.ja.md):
| marketplace.json | `$.metadata.version` | | marketplace.json | `$.metadata.version` |
| VERSION / version.txt | Direct content | | VERSION / version.txt | Direct content |
### Step 7: Commit and Tag ### Step 8: User Confirmation
```bash Before creating the release commit, ask user to confirm:
git add <all modified files>
git commit -m "chore: release v{VERSION}" **Use AskUserQuestion with two questions**:
git tag v{VERSION}
1. **Version bump** (single select):
- Show recommended version based on Step 3 analysis
- Options: recommended (with label), other semver options
- Example: `1.2.3 → 1.3.0 (Recommended)`, `1.2.3 → 1.2.4`, `1.2.3 → 2.0.0`
2. **Push to remote** (single select):
- Options: "Yes, push after commit", "No, keep local only"
**Example Output Before Confirmation**:
``` ```
Commits created:
1. feat(baoyu-cover-image): add watercolor and minimalist styles
2. fix(baoyu-comic): improve panel layout for long dialogues
3. docs(project): update architecture documentation
Changelog preview (en):
## 1.3.0 - 2026-01-22
### Features
- Add watercolor and minimalist styles to cover-image
### Fixes
- Improve panel layout for long dialogues in comic
Ready to create release commit and tag.
```
### Step 9: Create Release Commit and Tag
After user confirmation:
1. **Stage version and changelog files**:
```bash
git add <version-file>
git add CHANGELOG*.md
```
2. **Create release commit**:
```bash
git commit -m "chore: release v{VERSION}"
```
3. **Create tag**:
```bash
git tag v{VERSION}
```
4. **Push if user confirmed** (Step 8):
```bash
git push origin main
git push origin v{VERSION}
```
**Note**: Do NOT add Co-Authored-By line. This is a release commit, not a code contribution. **Note**: Do NOT add Co-Authored-By line. This is a release commit, not a code contribution.
**Important**: Do NOT push to remote. User will push manually when ready.
**Post-Release Output**: **Post-Release Output**:
``` ```
Release v1.3.0 created locally. Release v1.3.0 created.
To publish: Commits:
git push origin main 1. feat(baoyu-cover-image): add watercolor and minimalist styles
git push origin v1.3.0 2. fix(baoyu-comic): improve panel layout for long dialogues
3. docs(project): update architecture documentation
4. chore: release v1.3.0
Tag: v1.3.0
Status: Pushed to origin # or "Local only - run git push when ready"
``` ```
## Configuration (.releaserc.yml) ## Configuration (.releaserc.yml)
@@ -307,31 +404,36 @@ Project detected:
Last tag: v1.2.3 Last tag: v1.2.3
Proposed version: v1.3.0 Proposed version: v1.3.0
Changes detected: Changes grouped by skill/module:
feat: add user authentication baoyu-cover-image:
feat: support oauth2 login - feat: add watercolor style
fix: memory leak in pool - feat: add minimalist style
→ Commit: feat(baoyu-cover-image): add watercolor and minimalist styles
→ README updates: options table
baoyu-comic:
- fix: panel layout for long dialogues
→ Commit: fix(baoyu-comic): improve panel layout for long dialogues
→ No README updates
Changelog preview (en): Changelog preview (en):
## 1.3.0 - 2026-01-22 ## 1.3.0 - 2026-01-22
### Features ### Features
- Add user authentication module - Add watercolor and minimalist styles to cover-image
- Support OAuth2 login
### Fixes ### Fixes
- Fix memory leak in connection pool - Improve panel layout for long dialogues in comic
Changelog preview (zh): Changelog preview (zh):
## 1.3.0 - 2026-01-22 ## 1.3.0 - 2026-01-22
### 新功能 ### 新功能
- 新增用户认证模块 - 为 cover-image 添加水彩和极简风格
- 支持 OAuth2 登录
### 修复 ### 修复
- 修复连接池内存泄漏问题 - 改进 comic 长对话的面板布局
Files to modify: Commits to create:
- package.json 1. feat(baoyu-cover-image): add watercolor and minimalist styles
- CHANGELOG.md 2. fix(baoyu-comic): improve panel layout for long dialogues
- CHANGELOG.zh.md 3. chore: release v1.3.0
No changes made. Run without --dry-run to execute. No changes made. Run without --dry-run to execute.
``` ```
+3
View File
@@ -149,3 +149,6 @@ xhs-images/
url-to-markdown/ url-to-markdown/
cover-image/ cover-image/
slide-deck/ slide-deck/
infographic/
illustrations/
comic/
+105
View File
@@ -2,6 +2,111 @@
English | [中文](./CHANGELOG.zh.md) English | [中文](./CHANGELOG.zh.md)
## 1.23.0 - 2026-01-26
### Refactor
- `baoyu-cover-image`: replaces 20 fixed styles with 5-dimension system (Type × Palette × Rendering × Text × Mood). 9 color palettes × 6 rendering styles = 54 combinations. Adds style presets for backward compatibility, v2→v3 schema migration, and new reference structure (`palettes/`, `renderings/`, `workflow/`).
## 1.22.0 - 2026-01-25
### Features
- `baoyu-article-illustrator`: adds `imgs-subdir` output directory option; improves style selection to always ask and show preferred_style from EXTEND.md.
- `baoyu-cover-image`: adds `default_output_dir` preference supporting `same-dir`, `imgs-subdir`, and `independent` options with Step 1.5 for output directory selection.
- `baoyu-post-to-wechat`: adds theme selection (default/grace/simple) with AskUserQuestion before posting; adds HTML preview step; simplifies image placeholders to `WECHATIMGPH_N` format; refactors copy/paste to cross-platform helpers.
### Refactor
- `baoyu-post-to-x`: simplifies image placeholders from `[[IMAGE_PLACEHOLDER_N]]` to `XIMGPH_N` format.
## 1.21.4 - 2026-01-25
### Fixes
- `baoyu-post-to-wechat`: adds Windows compatibility—uses `fileURLToPath` for correct path resolution, replaces system-dependent copy/paste tools (osascript/xdotool) with CDP keyboard events for cross-platform support.
- `baoyu-post-to-wechat`: fixes regressions from Windows compatibility PR—corrects broken `-fixed` filename references, restores frontmatter quote stripping, restores `--title` CLI parameter, fixes summary extraction to skip headings/quotes/lists, fixes argument parsing for single-dash flags, removes debug logs.
- `baoyu-article-illustrator`, `baoyu-cover-image`, `baoyu-xhs-images`: removes opacity option from watermark configuration.
## 1.21.3 - 2026-01-24
### Refactor
- `baoyu-article-illustrator`: simplifies SKILL.md by extracting content to reference files—adds `references/usage.md` for command syntax, `references/prompt-construction.md` for prompt templates. Reorganizes workflow from 5 to 6 steps with new Pre-check phase. Adds `default_output_dir` preference option.
## 1.21.2 - 2026-01-24
### Features
- `baoyu-image-gen`: adds parallel generation documentation with recommended 4 concurrent subagents for batch operations.
### Documentation
- `release-skills`: adds skill/module grouping workflow and user confirmation step before release.
## 1.21.1 - 2026-01-24
### Documentation
- `baoyu-comic`: adds character sheet compression step after generation to reduce token usage when used as reference image.
## 1.21.0 - 2026-01-24
### Features
- `baoyu-cover-image`: expands aspect ratio options—adds 4:3, 3:2, 3:4 ratios; changes default from 2.35:1 to 16:9 for better versatility. Aspect ratio is now always confirmed unless explicitly specified via `--aspect` flag.
- `baoyu-image-gen`: refactors Google provider to support both Gemini multimodal and Imagen models with unified API. Adds `--imageSize` parameter support (1K/2K/4K) for Gemini models.
## 1.20.0 - 2026-01-24
### Features
- `baoyu-cover-image`: upgrades from Type × Style two-dimension system to **4-dimension system**—adds `--text` dimension (none, title-only, title-subtitle, text-rich) for text density control and `--mood` dimension (subtle, balanced, bold) for emotional intensity. New `--quick` flag skips confirmation and uses auto-selection.
### Documentation
- `baoyu-cover-image`: adds dimension reference files—`references/dimensions/text.md` (text density levels) and `references/dimensions/mood.md` (mood intensity levels).
- `baoyu-cover-image`: updates base-prompt, first-time-setup, and preferences-schema to support new 4-dimension system with v2 schema.
- `README.md`, `README.zh.md`: updates baoyu-cover-image documentation to reflect new 4-dimension system with `--text`, `--mood`, and `--quick` options.
## 1.19.0 - 2026-01-24
### Features
- `baoyu-comic`: adds partial workflow options—`--storyboard-only`, `--prompts-only`, `--images-only`, and `--regenerate N` for flexible workflow control.
- `baoyu-image-gen`: adds `--imageSize` parameter for Google providers (1K/2K/4K), changes default quality to 2k.
- `baoyu-image-gen`: adds `GEMINI_API_KEY` as alias for `GOOGLE_API_KEY`.
### Refactor
- `baoyu-comic`: extracts detailed workflow to `references/workflow.md`, reduces SKILL.md by ~400 lines while preserving functionality.
- `baoyu-comic`: extracts content signal analysis to `references/auto-selection.md` and partial workflow docs to `references/partial-workflows.md`.
- `baoyu-image-gen`: modularizes code—extracts types to `types.ts`, provider implementations to `providers/google.ts` and `providers/openai.ts`.
### Documentation
- `baoyu-comic`: improves ohmsha preset documentation with explicit default Doraemon character definitions and visual descriptions.
## 1.18.3 - 2026-01-23
### Documentation
- `baoyu-comic`: improves character reference handling with explicit Strategy A/B selection—Strategy A uses `--ref` parameter for skills that support it, Strategy B embeds character descriptions in prompts for skills that don't. Includes concrete code examples for both approaches.
### Fixes
- `baoyu-image-gen`: removes unsupported Gemini models (`gemini-2.0-flash-exp-image-generation`, `gemini-2.5-flash-preview-native-audio-dialog`) from multimodal model list.
## 1.18.2 - 2026-01-23
### Refactor
- Streamline SKILL.md documentation across 7 skills (`baoyu-compress-image`, `baoyu-danger-gemini-web`, `baoyu-danger-x-to-markdown`, `baoyu-image-gen`, `baoyu-post-to-wechat`, `baoyu-post-to-x`, `baoyu-url-to-markdown`) following official best practices—reduces total documentation by ~300 lines while preserving all functionality.
### Documentation
- `CLAUDE.md`: adds official skill authoring best practices link, skill loading rules, description writing guidelines, and progressive disclosure patterns.
## 1.18.1 - 2026-01-23
### Documentation
- `baoyu-slide-deck`: adds detailed sub-steps (1.1-1.3) to progress checklist, marks Step 1.3 as required with explicit Bash check command for existing directory detection.
## 1.18.0 - 2026-01-23
### Features
- `baoyu-slide-deck`: introduces dimension-based style system—replaces monolithic style definitions with modular 4-dimension architecture: **Texture** (clean, grid, organic, pixel, paper), **Mood** (professional, warm, cool, vibrant, dark, neutral), **Typography** (geometric, humanist, handwritten, editorial, technical), and **Density** (minimal, balanced, dense). 16 presets map to specific dimension combinations, with "Custom dimensions" option for full flexibility.
- `baoyu-slide-deck`: adds two-round confirmation workflow—Round 1 asks style/audience/slides/review preferences, Round 2 (optional) collects custom dimension choices when user selects "Custom dimensions".
- `baoyu-slide-deck`: adds conditional outline and prompt review—users can skip reviews for faster generation or enable them for more control.
### Documentation
- `baoyu-slide-deck`: adds dimension reference files—`references/dimensions/texture.md`, `references/dimensions/mood.md`, `references/dimensions/typography.md`, `references/dimensions/density.md`, and `references/dimensions/presets.md` (preset → dimension mapping).
- `baoyu-slide-deck`: adds design guidelines—`references/design-guidelines.md` with audience principles, visual hierarchy, content density, color selection, typography, and font recommendations.
- `baoyu-slide-deck`: adds layout reference—`references/layouts.md` with layout options and selection tips.
- `baoyu-slide-deck`: adds preferences schema—`references/config/preferences-schema.md` for EXTEND.md configuration.
## 1.17.1 - 2026-01-23 ## 1.17.1 - 2026-01-23
### Refactor ### Refactor
+105
View File
@@ -2,6 +2,111 @@
[English](./CHANGELOG.md) | 中文 [English](./CHANGELOG.md) | 中文
## 1.23.0 - 2026-01-26
### 重构
- `baoyu-cover-image`:将 20 种固定风格替换为五维系统(类型 × 配色 × 渲染 × 文字 × 氛围)。9 种配色方案 × 6 种渲染风格 = 54 种组合。新增风格预设实现向后兼容,v2→v3 配置迁移,以及新的引用文件结构(`palettes/``renderings/``workflow/`)。
## 1.22.0 - 2026-01-25
### 新功能
- `baoyu-article-illustrator`:新增 `imgs-subdir` 输出目录选项;改进风格选择,始终询问并展示 EXTEND.md 中的 preferred_style。
- `baoyu-cover-image`:新增 `default_output_dir` 偏好设置,支持 `same-dir``imgs-subdir``independent` 选项,新增 Step 1.5 输出目录选择流程。
- `baoyu-post-to-wechat`:发布前新增主题选择(default/grace/simple);新增 HTML 预览步骤;图片占位符简化为 `WECHATIMGPH_N` 格式;重构复制粘贴为跨平台辅助函数。
### 重构
- `baoyu-post-to-x`:图片占位符从 `[[IMAGE_PLACEHOLDER_N]]` 简化为 `XIMGPH_N` 格式。
## 1.21.4 - 2026-01-25
### 修复
- `baoyu-post-to-wechat`:新增 Windows 兼容性——使用 `fileURLToPath` 正确解析路径,将系统依赖的复制粘贴工具(osascript/xdotool)替换为 CDP 键盘事件,实现跨平台支持。
- `baoyu-post-to-wechat`:修复 Windows 兼容性 PR 引入的回退问题——修正错误的 `-fixed` 文件名引用、恢复 frontmatter 引号剥离、恢复 `--title` CLI 参数、修复摘要提取逻辑以正确跳过标题/引用/列表、修复单横线参数解析、移除调试日志。
- `baoyu-article-illustrator``baoyu-cover-image``baoyu-xhs-images`:移除水印配置中的透明度选项。
## 1.21.3 - 2026-01-24
### 重构
- `baoyu-article-illustrator`:简化 SKILL.md,提取内容至引用文件——新增 `references/usage.md` 用于命令语法,`references/prompt-construction.md` 用于提示词模板。工作流从 5 步重组为 6 步,新增 Pre-check 预检阶段。新增 `default_output_dir` 偏好设置选项。
## 1.21.2 - 2026-01-24
### 新功能
- `baoyu-image-gen`:添加并行生成文档,推荐使用 4 个并发 subagent 进行批量操作。
### 文档
- `release-skills`:新增按 skill/module 分组提交流程和发布前用户确认步骤。
## 1.21.1 - 2026-01-24
### 文档
- `baoyu-comic`:在角色参考图生成后添加压缩步骤,减少作为参考图使用时的 token 消耗。
## 1.21.0 - 2026-01-24
### 新功能
- `baoyu-cover-image`:扩展宽高比选项——新增 4:3、3:2、3:4 比例;默认值从 2.35:1 改为 16:9 以提高通用性。现在除非通过 `--aspect` 标志明确指定,否则始终确认宽高比。
- `baoyu-image-gen`:重构 Google provider 以统一支持 Gemini 多模态和 Imagen 模型。为 Gemini 模型新增 `--imageSize` 参数支持(1K/2K/4K)。
## 1.20.0 - 2026-01-24
### 新功能
- `baoyu-cover-image`:从类型 × 风格二维系统升级为**四维系统**——新增 `--text` 维度(none 无文字、title-only 仅标题、title-subtitle 标题+副标题、text-rich 丰富文字)控制文字密度,新增 `--mood` 维度(subtle 低调、balanced 平衡、bold 醒目)控制情感强度。新增 `--quick` 标志跳过确认,直接使用自动选择。
### 文档
- `baoyu-cover-image`:新增维度参考文件——`references/dimensions/text.md`(文字密度级别)和 `references/dimensions/mood.md`(氛围强度级别)。
- `baoyu-cover-image`:更新 base-prompt、first-time-setup 和 preferences-schema 以支持新的四维系统及 v2 配置模式。
- `README.md``README.zh.md`:更新 baoyu-cover-image 文档,反映新的四维系统及 `--text``--mood``--quick` 选项。
## 1.19.0 - 2026-01-24
### 新功能
- `baoyu-comic`:新增部分工作流选项——`--storyboard-only``--prompts-only``--images-only``--regenerate N`,实现灵活的工作流控制。
- `baoyu-image-gen`:新增 `--imageSize` 参数用于 Google 提供商(1K/2K/4K),默认质量改为 2k。
- `baoyu-image-gen`:新增 `GEMINI_API_KEY` 作为 `GOOGLE_API_KEY` 的别名。
### 重构
- `baoyu-comic`:将详细工作流提取至 `references/workflow.md`SKILL.md 减少约 400 行,功能完整保留。
- `baoyu-comic`:将内容信号分析提取至 `references/auto-selection.md`,部分工作流文档提取至 `references/partial-workflows.md`
- `baoyu-image-gen`:代码模块化——类型定义提取至 `types.ts`provider 实现提取至 `providers/google.ts``providers/openai.ts`
### 文档
- `baoyu-comic`:改进 ohmsha 预设文档,明确默认哆啦A梦角色定义和视觉描述。
## 1.18.3 - 2026-01-23
### 文档
- `baoyu-comic`:改进角色参考处理流程,新增明确的 Strategy A/B 选择逻辑——Strategy A 使用 `--ref` 参数(适用于支持该参数的技能),Strategy B 将角色描述嵌入提示词(适用于不支持的技能)。包含两种方法的具体代码示例。
### 修复
- `baoyu-image-gen`:从多模态模型列表中移除不支持的 Gemini 模型(`gemini-2.0-flash-exp-image-generation``gemini-2.5-flash-preview-native-audio-dialog`)。
## 1.18.2 - 2026-01-23
### 重构
- 精简 7 个技能的 SKILL.md 文档(`baoyu-compress-image``baoyu-danger-gemini-web``baoyu-danger-x-to-markdown``baoyu-image-gen``baoyu-post-to-wechat``baoyu-post-to-x``baoyu-url-to-markdown`),遵循官方最佳实践——总文档量减少约 300 行,功能完整保留。
### 文档
- `CLAUDE.md`:新增官方技能编写最佳实践链接、技能加载规则、描述编写指南和渐进式披露模式。
## 1.18.1 - 2026-01-23
### 文档
- `baoyu-slide-deck`:进度清单新增详细子步骤(1.1-1.3),标记 Step 1.3 为必须步骤并提供明确的 Bash 检查命令用于检测已存在目录。
## 1.18.0 - 2026-01-23
### 新功能
- `baoyu-slide-deck`:引入基于维度的风格系统——将单一风格定义重构为模块化四维架构:**纹理** (clean 纯净、grid 网格、organic 有机、pixel 像素、paper 纸张)、**氛围** (professional 专业、warm 温暖、cool 冷静、vibrant 鲜艳、dark 暗色、neutral 中性)、**字体** (geometric 几何、humanist 人文、handwritten 手写、editorial 编辑、technical 技术)、**密度** (minimal 极简、balanced 均衡、dense 密集)。16 种预设映射到特定维度组合,并提供「自定义维度」选项实现完全灵活配置。
- `baoyu-slide-deck`:新增两轮确认工作流——第一轮询问风格/受众/页数/审核偏好,第二轮(可选)在用户选择「自定义维度」时收集具体维度选择。
- `baoyu-slide-deck`:新增条件性大纲和提示词审核——用户可跳过审核以加快生成,或启用审核以获得更多控制。
### 文档
- `baoyu-slide-deck`:新增维度参考文件——`references/dimensions/texture.md``references/dimensions/mood.md``references/dimensions/typography.md``references/dimensions/density.md`,以及 `references/dimensions/presets.md`(预设到维度的映射)。
- `baoyu-slide-deck`:新增设计指南——`references/design-guidelines.md`,包含受众原则、视觉层次、内容密度、配色选择、字体排版和字体推荐。
- `baoyu-slide-deck`:新增布局参考——`references/layouts.md`,包含布局选项和选择技巧。
- `baoyu-slide-deck`:新增偏好配置模式——`references/config/preferences-schema.md`,用于 EXTEND.md 配置。
## 1.17.1 - 2026-01-23 ## 1.17.1 - 2026-01-23
### 重构 ### 重构
+127 -12
View File
@@ -78,6 +78,20 @@ npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts --promptfiles system.m
`.claude-plugin/marketplace.json` defines plugin metadata and skill paths. Version follows semver. `.claude-plugin/marketplace.json` defines plugin metadata and skill paths. Version follows semver.
## Skill Loading Rules
**IMPORTANT**: When working in this project, follow these rules:
| Rule | Description |
|------|-------------|
| **Load project skills first** | MUST load all skills from `skills/` directory in current project. Project skills take priority over system/user-level skills with same name. |
| **Default image generation** | When image generation is needed, use `skills/baoyu-image-gen/SKILL.md` by default (unless user specifies otherwise). |
**Loading Priority** (highest → lowest):
1. Current project `skills/` directory
2. User-level skills (`$HOME/.baoyu-skills/`)
3. System-level skills
## Release Process ## Release Process
**IMPORTANT**: When user requests release/发布/push, ALWAYS use `/release-skills` workflow. **IMPORTANT**: When user requests release/发布/push, ALWAYS use `/release-skills` workflow.
@@ -92,6 +106,22 @@ npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts --promptfiles system.m
**IMPORTANT**: All skills MUST use `baoyu-` prefix to avoid conflicts when users import this plugin. **IMPORTANT**: All skills MUST use `baoyu-` prefix to avoid conflicts when users import this plugin.
**REQUIRED READING**: Before creating a new skill, read the official [Skill authoring best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices).
### Key Requirements from Official Best Practices
| Requirement | Details |
|-------------|---------|
| **Concise is key** | Claude is smart—only add context it doesn't have. Challenge each token. |
| **name field** | Max 64 chars, lowercase letters/numbers/hyphens only, no "anthropic"/"claude" |
| **description field** | Max 1024 chars, non-empty, MUST be third person, include what + when to use |
| **SKILL.md body** | Keep under 500 lines; use separate files for additional content |
| **Naming convention** | Gerund form preferred (e.g., `processing-pdfs`), but `baoyu-` prefix required here |
| **References** | Keep one level deep from SKILL.md; avoid nested references |
| **No time-sensitive info** | Avoid dates/versions that become outdated |
### Steps
1. Create `skills/baoyu-<name>/SKILL.md` with YAML front matter 1. Create `skills/baoyu-<name>/SKILL.md` with YAML front matter
- Directory name: `baoyu-<name>` - Directory name: `baoyu-<name>`
- SKILL.md `name` field: `baoyu-<name>` - SKILL.md `name` field: `baoyu-<name>`
@@ -119,6 +149,21 @@ npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts --promptfiles system.m
- `description`: Brief description of the category - `description`: Brief description of the category
- `skills`: Array with the skill path - `skills`: Array with the skill path
### Writing Effective Descriptions
**MUST write in third person** (not "I can help you" or "You can use this"):
```yaml
# Good
description: Generates Xiaohongshu infographic series from content. Use when user asks for "小红书图片", "XHS images", or "RedNote infographics".
# Bad
description: I can help you create Xiaohongshu images
description: You can use this to generate XHS content
```
Include both **what** the skill does and **when** to use it (triggers/keywords).
### Script Directory Template ### Script Directory Template
Every SKILL.md with scripts MUST include this section after Usage: Every SKILL.md with scripts MUST include this section after Usage:
@@ -142,6 +187,26 @@ Every SKILL.md with scripts MUST include this section after Usage:
When referencing scripts in workflow sections, use `${SKILL_DIR}/scripts/<name>.ts` so agents can resolve the correct path. When referencing scripts in workflow sections, use `${SKILL_DIR}/scripts/<name>.ts` so agents can resolve the correct path.
### Progressive Disclosure
For skills with extensive content, use separate reference files:
```
skills/baoyu-example/
├── SKILL.md # Main instructions (<500 lines)
├── references/
│ ├── styles.md # Style definitions (loaded as needed)
│ └── examples.md # Usage examples (loaded as needed)
└── scripts/
└── main.ts # Executable script
```
In SKILL.md, link to reference files (one level deep only):
```markdown
**Available styles**: See [references/styles.md](references/styles.md)
**Examples**: See [references/examples.md](references/examples.md)
```
## Code Style ## Code Style
- TypeScript throughout, no comments - TypeScript throughout, no comments
@@ -155,9 +220,11 @@ Skills that require image generation MUST delegate to available image generation
### Image Generation Skill Selection ### Image Generation Skill Selection
1. Check available image generation skills in `skills/` directory **Default**: Use `skills/baoyu-image-gen/SKILL.md` (unless user specifies otherwise).
2. Read each skill's SKILL.md to understand parameters and capabilities
3. If multiple image generation skills available, ask user to choose preferred skill 1. Read `skills/baoyu-image-gen/SKILL.md` for parameters and capabilities
2. If user explicitly requests a different skill, check `skills/` directory for alternatives
3. Only ask user to choose when they haven't specified and multiple viable options exist
### Generation Flow Template ### Generation Flow Template
@@ -298,18 +365,66 @@ READMEs use 3-column tables for style previews:
## Extension Support ## Extension Support
Every SKILL.md MUST include an Extension Support section at the end: Every SKILL.md MUST include two parts for extension support:
### 1. Load Preferences Section (in Step 1 or as "Preferences" section)
For skills with workflows, add as Step 1.1. For utility skills, add as "Preferences (EXTEND.md)" section before Usage:
```markdown
**1.1 Load Preferences (EXTEND.md)**
Use Bash to check EXTEND.md existence (priority order):
\`\`\`bash
# Check project-level first
test -f .baoyu-skills/<skill-name>/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/<skill-name>/EXTEND.md" && echo "user"
\`\`\`
┌────────────────────────────────────────────┬───────────────────┐
│ Path │ Location │
├────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/<skill-name>/EXTEND.md │ Project directory │
├────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/<skill-name>/EXTEND.md │ User home │
└────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, display summary │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Ask user with AskUserQuestion (see references/config/first-time-setup.md) │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: [List supported configuration options for this skill]
Schema: `references/config/preferences-schema.md`
```
### 2. Extension Support Section (at the end)
Simplified section that references the preferences section:
```markdown ```markdown
## Extension Support ## Extension Support
Custom styles and configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Step 1.1** for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/<skill-name>/EXTEND.md` (project)
2. `~/.baoyu-skills/<skill-name>/EXTEND.md` (user)
If found, load before Step 1. Extension content overrides defaults.
``` ```
Replace `<skill-name>` with the actual skill name (e.g., `baoyu-cover-image`). Or for utility skills without workflow steps:
```markdown
## Extension Support
Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
```
**Notes**:
- Replace `<skill-name>` with actual skill name (e.g., `baoyu-cover-image`)
- Use `$HOME` instead of `~` for cross-platform compatibility (macOS/Linux/WSL)
- Use `test -f` Bash command for explicit file existence check
- ASCII tables for clear visual formatting
+74 -55
View File
@@ -245,45 +245,35 @@ Generate professional infographics with 20 layout types and 17 visual styles. An
#### baoyu-cover-image #### baoyu-cover-image
Generate cover images for articles with Type × Style two-dimension system. Generate cover images for articles with 5 dimensions: Type × Palette × Rendering × Text × Mood. Combines 9 color palettes with 6 rendering styles for 54 unique combinations.
```bash ```bash
# Auto-select type and style based on content # Auto-select all dimensions based on content
/baoyu-cover-image path/to/article.md /baoyu-cover-image path/to/article.md
# Specify type and/or style # Quick mode: skip confirmation, use auto-selection
/baoyu-cover-image path/to/article.md --type conceptual --style blueprint /baoyu-cover-image path/to/article.md --quick
/baoyu-cover-image path/to/article.md --style warm
# Specify aspect ratio (default: 2.35:1) # Specify dimensions (5D system)
/baoyu-cover-image path/to/article.md --aspect 16:9 /baoyu-cover-image path/to/article.md --type conceptual --palette cool --rendering digital
/baoyu-cover-image path/to/article.md --text title-subtitle --mood bold
# Without title text # Style presets (backward-compatible shorthand)
/baoyu-cover-image path/to/article.md --style blueprint
# Specify aspect ratio (default: 16:9)
/baoyu-cover-image path/to/article.md --aspect 2.35:1
# Visual only (no title text)
/baoyu-cover-image path/to/article.md --no-title /baoyu-cover-image path/to/article.md --no-title
``` ```
Available types: `hero`, `conceptual`, `typography`, `metaphor`, `scene`, `minimal` **Five Dimensions**:
- **Type**: `hero`, `conceptual`, `typography`, `metaphor`, `scene`, `minimal`
Available styles: `elegant` (default), `blueprint`, `bold-editorial`, `chalkboard`, `dark-atmospheric`, `editorial-infographic`, `fantasy-animation`, `flat-doodle`, `intuition-machine`, `minimal`, `nature`, `notion`, `pixel-art`, `playful`, `retro`, `sketch-notes`, `vector-illustration`, `vintage`, `warm`, `watercolor` - **Palette**: `warm`, `elegant`, `cool`, `dark`, `earth`, `vivid`, `pastel`, `mono`, `retro`
- **Rendering**: `flat-vector`, `hand-drawn`, `painterly`, `digital`, `pixel`, `chalk`
**Style Previews**: - **Text**: `none`, `title-only` (default), `title-subtitle`, `text-rich`
- **Mood**: `subtle`, `balanced` (default), `bold`
| | | |
|:---:|:---:|:---:|
| ![elegant](./screenshots/cover-image-styles/elegant.webp) | ![blueprint](./screenshots/cover-image-styles/blueprint.webp) | ![bold-editorial](./screenshots/cover-image-styles/bold-editorial.webp) |
| elegant | blueprint | bold-editorial |
| ![chalkboard](./screenshots/cover-image-styles/chalkboard.webp) | ![dark-atmospheric](./screenshots/cover-image-styles/dark-atmospheric.webp) | ![editorial-infographic](./screenshots/cover-image-styles/editorial-infographic.webp) |
| chalkboard | dark-atmospheric | editorial-infographic |
| ![fantasy-animation](./screenshots/cover-image-styles/fantasy-animation.webp) | ![intuition-machine](./screenshots/cover-image-styles/intuition-machine.webp) | ![minimal](./screenshots/cover-image-styles/minimal.webp) |
| fantasy-animation | intuition-machine | minimal |
| ![nature](./screenshots/cover-image-styles/nature.webp) | ![notion](./screenshots/cover-image-styles/notion.webp) | ![pixel-art](./screenshots/cover-image-styles/pixel-art.webp) |
| nature | notion | pixel-art |
| ![playful](./screenshots/cover-image-styles/playful.webp) | ![retro](./screenshots/cover-image-styles/retro.webp) | ![sketch-notes](./screenshots/cover-image-styles/sketch-notes.webp) |
| playful | retro | sketch-notes |
| ![vector-illustration](./screenshots/cover-image-styles/vector-illustration.webp) | ![vintage](./screenshots/cover-image-styles/vintage.webp) | ![warm](./screenshots/cover-image-styles/warm.webp) |
| vector-illustration | vintage | warm |
| ![watercolor](./screenshots/cover-image-styles/watercolor.webp) | ![flat-doodle](./screenshots/cover-image-styles/flat-doodle.webp) | |
| watercolor | flat-doodle | |
#### baoyu-slide-deck #### baoyu-slide-deck
@@ -297,6 +287,9 @@ Generate professional slide deck images from content. Creates comprehensive outl
/baoyu-slide-deck path/to/article.md --style corporate /baoyu-slide-deck path/to/article.md --style corporate
/baoyu-slide-deck path/to/article.md --audience executives /baoyu-slide-deck path/to/article.md --audience executives
# Target slide count
/baoyu-slide-deck path/to/article.md --slides 15
# Outline only (no image generation) # Outline only (no image generation)
/baoyu-slide-deck path/to/article.md --outline-only /baoyu-slide-deck path/to/article.md --outline-only
@@ -304,25 +297,50 @@ Generate professional slide deck images from content. Creates comprehensive outl
/baoyu-slide-deck path/to/article.md --lang zh /baoyu-slide-deck path/to/article.md --lang zh
``` ```
**Styles** (visual aesthetics): **Options**:
| Style | Description | Best For | | Option | Description |
|-------|-------------|----------| |--------|-------------|
| `blueprint` (default) | Technical schematics, grid texture, engineering precision | Architecture, system design | | `--style <name>` | Visual style: preset name or `custom` |
| `notion` | SaaS dashboard aesthetic, card-based layouts, clean data focus | Product demos, SaaS, B2B | | `--audience <type>` | Target: beginners, intermediate, experts, executives, general |
| `bold-editorial` | High-impact magazine style, bold typography, dark backgrounds | Product launches, keynotes | | `--lang <code>` | Output language (en, zh, ja, etc.) |
| `corporate` | Navy/gold palette, structured layouts, professional icons | Investor decks, proposals | | `--slides <number>` | Target slide count (8-25 recommended, max 30) |
| `dark-atmospheric` | Cinematic dark mode, glowing accents, atmospheric depth | Entertainment, gaming, creative | | `--outline-only` | Generate outline only, skip images |
| `editorial-infographic` | Magazine-style explainers, flat illustrations | Tech explainers, research | | `--prompts-only` | Generate outline + prompts, skip images |
| `fantasy-animation` | Whimsical Ghibli/Disney style, hand-drawn animation | Educational, storytelling | | `--images-only` | Generate images from existing prompts |
| `intuition-machine` | Technical briefing, bilingual labels, aged paper texture | Technical docs, bilingual | | `--regenerate <N>` | Regenerate specific slide(s): `3` or `2,5,8` |
| `minimal` | Ultra-clean, maximum whitespace, single accent color | Executive briefings, premium |
| `pixel-art` | Retro 8-bit aesthetic, chunky pixels, nostalgic gaming | Gaming, developer talks | **Style System**:
| `scientific` | Academic diagrams, biological pathways, precise labeling | Biology, chemistry, medical |
| `sketch-notes` | Hand-drawn feel, soft brush strokes, warm background | Educational, tutorials | Styles are built from 4 dimensions: **Texture** × **Mood** × **Typography** × **Density**
| `vector-illustration` | Flat vector, black outlines, retro soft colors | Creative proposals, explainers |
| `vintage` | Aged-paper aesthetic, historical document styling | Historical, heritage, biography | | Dimension | Options |
| `watercolor` | Soft hand-painted textures, natural warmth | Lifestyle, wellness, travel | |-----------|---------|
| Texture | clean, grid, organic, pixel, paper |
| Mood | professional, warm, cool, vibrant, dark, neutral |
| Typography | geometric, humanist, handwritten, editorial, technical |
| Density | minimal, balanced, dense |
**Presets** (pre-configured dimension combinations):
| Preset | Dimensions | Best For |
|--------|------------|----------|
| `blueprint` (default) | grid + cool + technical + balanced | Architecture, system design |
| `chalkboard` | organic + warm + handwritten + balanced | Education, tutorials |
| `corporate` | clean + professional + geometric + balanced | Investor decks, proposals |
| `minimal` | clean + neutral + geometric + minimal | Executive briefings |
| `sketch-notes` | organic + warm + handwritten + balanced | Educational, tutorials |
| `watercolor` | organic + warm + humanist + minimal | Lifestyle, wellness |
| `dark-atmospheric` | clean + dark + editorial + balanced | Entertainment, gaming |
| `notion` | clean + neutral + geometric + dense | Product demos, SaaS |
| `bold-editorial` | clean + vibrant + editorial + balanced | Product launches, keynotes |
| `editorial-infographic` | clean + cool + editorial + dense | Tech explainers, research |
| `fantasy-animation` | organic + vibrant + handwritten + minimal | Educational storytelling |
| `intuition-machine` | clean + cool + technical + dense | Technical docs, academic |
| `pixel-art` | pixel + vibrant + technical + balanced | Gaming, developer talks |
| `scientific` | clean + cool + technical + dense | Biology, chemistry, medical |
| `vector-illustration` | clean + vibrant + humanist + balanced | Creative, children's content |
| `vintage` | paper + warm + editorial + balanced | Historical, heritage |
**Style Previews**: **Style Previews**:
@@ -341,7 +359,7 @@ Generate professional slide deck images from content. Creates comprehensive outl
| ![watercolor](./screenshots/slide-deck-styles/watercolor.webp) | | | | ![watercolor](./screenshots/slide-deck-styles/watercolor.webp) | | |
| watercolor | | | | watercolor | | |
After generation, slides are automatically merged into a `.pptx` file for easy sharing. After generation, slides are automatically merged into `.pptx` and `.pdf` files for easy sharing.
#### baoyu-comic #### baoyu-comic
@@ -709,13 +727,14 @@ mkdir -p .baoyu-skills/baoyu-cover-image
Then create `.baoyu-skills/baoyu-cover-image/EXTEND.md`: Then create `.baoyu-skills/baoyu-cover-image/EXTEND.md`:
```markdown ```markdown
## Custom Styles ## Custom Palettes
### brand ### corporate-tech
- Primary color: #1a73e8 - Primary colors: #1a73e8, #4A90D9
- Secondary color: #34a853 - Background: #F5F7FA
- Font style: Modern sans-serif - Accent colors: #00B4D8, #48CAE4
- Always include company logo watermark - Decorative hints: Clean lines, subtle gradients
- Best for: SaaS, enterprise, technical
``` ```
The extension content will be loaded before skill execution and override defaults. The extension content will be loaded before skill execution and override defaults.
+74 -55
View File
@@ -245,45 +245,35 @@ npx skills add jimliu/baoyu-skills
#### baoyu-cover-image #### baoyu-cover-image
为文章生成封面图,支持类型 × 风格二维系统 为文章生成封面图,支持五维定制系统:类型 × 配色 × 渲染 × 文字 × 氛围。9 种配色方案与 6 种渲染风格组合,提供 54 种独特效果
```bash ```bash
# 根据内容自动选择类型和风格 # 根据内容自动选择所有维度
/baoyu-cover-image path/to/article.md /baoyu-cover-image path/to/article.md
# 指定类型和/或风格 # 快速模式:跳过确认,使用自动选择
/baoyu-cover-image path/to/article.md --type conceptual --style blueprint /baoyu-cover-image path/to/article.md --quick
/baoyu-cover-image path/to/article.md --style warm
# 指定宽高比(默认:2.35:1 # 指定维度(5D 系统
/baoyu-cover-image path/to/article.md --aspect 16:9 /baoyu-cover-image path/to/article.md --type conceptual --palette cool --rendering digital
/baoyu-cover-image path/to/article.md --text title-subtitle --mood bold
# 不包含标题文字 # 风格预设(向后兼容的简写方式)
/baoyu-cover-image path/to/article.md --style blueprint
# 指定宽高比(默认:16:9
/baoyu-cover-image path/to/article.md --aspect 2.35:1
# 纯视觉(不含标题文字)
/baoyu-cover-image path/to/article.md --no-title /baoyu-cover-image path/to/article.md --no-title
``` ```
可用类型:`hero``conceptual``typography``metaphor``scene``minimal` **五个维度**
- **类型 (Type)**`hero``conceptual``typography``metaphor``scene``minimal`
可用风格:`elegant`(默认)、`blueprint``bold-editorial``chalkboard``dark-atmospheric``editorial-infographic``fantasy-animation``flat-doodle``intuition-machine``minimal``nature``notion``pixel-art``playful``retro``sketch-notes``vector-illustration``vintage``warm``watercolor` - **配色 (Palette)**`warm``elegant``cool``dark``earth``vivid``pastel``mono``retro`
- **渲染 (Rendering)**`flat-vector``hand-drawn``painterly``digital``pixel``chalk`
**风格预览** - **文字 (Text)**`none``title-only`(默认)、`title-subtitle``text-rich`
- **氛围 (Mood)**`subtle``balanced`(默认)、`bold`
| | | |
|:---:|:---:|:---:|
| ![elegant](./screenshots/cover-image-styles/elegant.webp) | ![blueprint](./screenshots/cover-image-styles/blueprint.webp) | ![bold-editorial](./screenshots/cover-image-styles/bold-editorial.webp) |
| elegant | blueprint | bold-editorial |
| ![chalkboard](./screenshots/cover-image-styles/chalkboard.webp) | ![dark-atmospheric](./screenshots/cover-image-styles/dark-atmospheric.webp) | ![editorial-infographic](./screenshots/cover-image-styles/editorial-infographic.webp) |
| chalkboard | dark-atmospheric | editorial-infographic |
| ![fantasy-animation](./screenshots/cover-image-styles/fantasy-animation.webp) | ![intuition-machine](./screenshots/cover-image-styles/intuition-machine.webp) | ![minimal](./screenshots/cover-image-styles/minimal.webp) |
| fantasy-animation | intuition-machine | minimal |
| ![nature](./screenshots/cover-image-styles/nature.webp) | ![notion](./screenshots/cover-image-styles/notion.webp) | ![pixel-art](./screenshots/cover-image-styles/pixel-art.webp) |
| nature | notion | pixel-art |
| ![playful](./screenshots/cover-image-styles/playful.webp) | ![retro](./screenshots/cover-image-styles/retro.webp) | ![sketch-notes](./screenshots/cover-image-styles/sketch-notes.webp) |
| playful | retro | sketch-notes |
| ![vector-illustration](./screenshots/cover-image-styles/vector-illustration.webp) | ![vintage](./screenshots/cover-image-styles/vintage.webp) | ![warm](./screenshots/cover-image-styles/warm.webp) |
| vector-illustration | vintage | warm |
| ![watercolor](./screenshots/cover-image-styles/watercolor.webp) | ![flat-doodle](./screenshots/cover-image-styles/flat-doodle.webp) | |
| watercolor | flat-doodle | |
#### baoyu-slide-deck #### baoyu-slide-deck
@@ -297,6 +287,9 @@ npx skills add jimliu/baoyu-skills
/baoyu-slide-deck path/to/article.md --style corporate /baoyu-slide-deck path/to/article.md --style corporate
/baoyu-slide-deck path/to/article.md --audience executives /baoyu-slide-deck path/to/article.md --audience executives
# 指定页数
/baoyu-slide-deck path/to/article.md --slides 15
# 仅生成大纲(不生成图片) # 仅生成大纲(不生成图片)
/baoyu-slide-deck path/to/article.md --outline-only /baoyu-slide-deck path/to/article.md --outline-only
@@ -304,25 +297,50 @@ npx skills add jimliu/baoyu-skills
/baoyu-slide-deck path/to/article.md --lang zh /baoyu-slide-deck path/to/article.md --lang zh
``` ```
**风格**(视觉美学) **选项**
| 风格 | 描述 | 适用场景 | | 选项 | 说明 |
|------|------|----------| |------|------|
| `blueprint`(默认) | 技术蓝图风格,网格纹理,工程精度 | 架构设计、系统设计 | | `--style <name>` | 视觉风格:预设名称或 `custom` |
| `notion` | SaaS 仪表盘美学,卡片式布局,数据清晰 | 产品演示、SaaS、B2B | | `--audience <type>` | 目标受众:beginners、intermediate、experts、executives、general |
| `bold-editorial` | 杂志社论风格,粗体排版,深色背景 | 产品发布、主题演讲 | | `--lang <code>` | 输出语言(en、zh、ja 等) |
| `corporate` | 海军蓝/金色配色,结构化布局,专业图标 | 投资者演示、客户提案 | | `--slides <number>` | 目标页数(推荐 8-25,最多 30) |
| `dark-atmospheric` | 电影级暗色调,发光效果,氛围感 | 娱乐、游戏、创意 | | `--outline-only` | 仅生成大纲,跳过图片 |
| `editorial-infographic` | 杂志风格信息图,扁平插画 | 科技解说、研究报告 | | `--prompts-only` | 生成大纲 + 提示词,跳过图片 |
| `fantasy-animation` | 吉卜力/迪士尼风格,手绘动画 | 教育、故事讲述 | | `--images-only` | 从现有提示词生成图片 |
| `intuition-machine` | 技术简报,双语标签,做旧纸张纹理 | 技术文档、双语内容 | | `--regenerate <N>` | 重新生成指定页:`3``2,5,8` |
| `minimal` | 极简风格,大量留白,单一强调色 | 高管简报、高端品牌 |
| `pixel-art` | 复古 8-bit 像素风,怀旧游戏感 | 游戏、开发者分享 | **风格系统**
| `scientific` | 学术图表,生物通路,精确标注 | 生物、化学、医学 |
| `sketch-notes` | 手绘风格,柔和笔触,暖白色背景 | 教育、教程、知识分享 | 风格由 4 个维度组合而成:**纹理** × **氛围** × **字体** × **密度**
| `vector-illustration` | 扁平矢量风格,黑色轮廓线,复古柔和配色 | 创意提案、说明性内容 |
| `vintage` | 做旧纸张美学,历史文档风格 | 历史、传记、人文 | | 维度 | 选项 |
| `watercolor` | 柔和手绘水彩纹理,自然温暖 | 生活方式、健康、旅行 | |------|------|
| 纹理 | clean 纯净、grid 网格、organic 有机、pixel 像素、paper 纸张 |
| 氛围 | professional 专业、warm 温暖、cool 冷静、vibrant 鲜艳、dark 暗色、neutral 中性 |
| 字体 | geometric 几何、humanist 人文、handwritten 手写、editorial 编辑、technical 技术 |
| 密度 | minimal 极简、balanced 均衡、dense 密集 |
**预设**(预配置的维度组合):
| 预设 | 维度组合 | 适用场景 |
|------|----------|----------|
| `blueprint`(默认) | grid + cool + technical + balanced | 架构设计、系统设计 |
| `chalkboard` | organic + warm + handwritten + balanced | 教育、教程 |
| `corporate` | clean + professional + geometric + balanced | 投资者演示、提案 |
| `minimal` | clean + neutral + geometric + minimal | 高管简报 |
| `sketch-notes` | organic + warm + handwritten + balanced | 教育、教程 |
| `watercolor` | organic + warm + humanist + minimal | 生活方式、健康 |
| `dark-atmospheric` | clean + dark + editorial + balanced | 娱乐、游戏 |
| `notion` | clean + neutral + geometric + dense | 产品演示、SaaS |
| `bold-editorial` | clean + vibrant + editorial + balanced | 产品发布、主题演讲 |
| `editorial-infographic` | clean + cool + editorial + dense | 科技解说、研究 |
| `fantasy-animation` | organic + vibrant + handwritten + minimal | 教育故事 |
| `intuition-machine` | clean + cool + technical + dense | 技术文档、学术 |
| `pixel-art` | pixel + vibrant + technical + balanced | 游戏、开发者 |
| `scientific` | clean + cool + technical + dense | 生物、化学、医学 |
| `vector-illustration` | clean + vibrant + humanist + balanced | 创意、儿童内容 |
| `vintage` | paper + warm + editorial + balanced | 历史、传记 |
**风格预览** **风格预览**
@@ -341,7 +359,7 @@ npx skills add jimliu/baoyu-skills
| ![watercolor](./screenshots/slide-deck-styles/watercolor.webp) | | | | ![watercolor](./screenshots/slide-deck-styles/watercolor.webp) | | |
| watercolor | | | | watercolor | | |
生成完成后,所有幻灯片会自动合并为 `.pptx` 文件,方便分享。 生成完成后,所有幻灯片会自动合并为 `.pptx``.pdf` 文件,方便分享。
#### baoyu-comic #### baoyu-comic
@@ -709,13 +727,14 @@ mkdir -p .baoyu-skills/baoyu-cover-image
然后创建 `.baoyu-skills/baoyu-cover-image/EXTEND.md` 然后创建 `.baoyu-skills/baoyu-cover-image/EXTEND.md`
```markdown ```markdown
## 自定义风格 ## 自定义配色
### brand ### corporate-tech
- 主色:#1a73e8 - 主色:#1a73e8#4A90D9
- 色:#34a853 - 背景色:#F5F7FA
- 字体风格:现代无衬线 - 强调色:#00B4D8#48CAE4
- 始终包含公司 logo 水印 - 装饰提示:简洁线条、渐变效果
- 适用于:SaaS、企业、技术内容
``` ```
扩展内容会在技能执行前加载,并覆盖默认设置。 扩展内容会在技能执行前加载,并覆盖默认设置。
+172 -301
View File
@@ -7,236 +7,201 @@ description: Analyzes article structure, identifies positions requiring visual a
Analyze articles, identify illustration positions, generate images with Type × Style consistency. Analyze articles, identify illustration positions, generate images with Type × Style consistency.
## Usage
```bash
# Auto-select type and style based on content
/baoyu-article-illustrator path/to/article.md
# Specify type
/baoyu-article-illustrator path/to/article.md --type infographic
# Specify style
/baoyu-article-illustrator path/to/article.md --style blueprint
# Combine type and style
/baoyu-article-illustrator path/to/article.md --type flowchart --style notion
# Specify density
/baoyu-article-illustrator path/to/article.md --density rich
# Direct content input
/baoyu-article-illustrator
[paste content]
```
## Options
| Option | Description |
|--------|-------------|
| `--type <name>` | Illustration type (see Type Gallery) |
| `--style <name>` | Visual style (see Style Gallery) |
| `--density <level>` | Image count: minimal / balanced / rich |
## Two Dimensions ## Two Dimensions
| Dimension | Controls | Examples | | Dimension | Controls | Examples |
|-----------|----------|----------| |-----------|----------|----------|
| **Type** | Information structure, content layout | infographic, scene, flowchart, comparison, framework, timeline | | **Type** | Information structure, layout | infographic, scene, flowchart, comparison, framework, timeline |
| **Style** | Visual aesthetics, colors, mood | notion, warm, minimal, blueprint, watercolor, elegant | | **Style** | Visual aesthetics, mood | notion, warm, minimal, blueprint, watercolor, elegant |
Type × Style can be freely combined. Example: `--type infographic --style blueprint` creates technical data visualization with schematic aesthetics. Type × Style can be freely combined. Example: `--type infographic --style blueprint`
## Type Gallery ## Type Gallery
| Type | Description | Best For | | Type | Best For |
|------|-------------|----------| |------|----------|
| `infographic` | Data visualization, charts, metrics | Technical articles, data analysis, comparisons | | `infographic` | Data, metrics, technical articles |
| `scene` | Atmospheric illustration, mood rendering | Narrative articles, personal stories, emotional content | | `scene` | Narratives, personal stories, emotional content |
| `flowchart` | Process diagrams, step visualization | Tutorials, workflows, decision trees | | `flowchart` | Tutorials, workflows, processes |
| `comparison` | Side-by-side, before/after contrast | Product comparisons, option evaluations | | `comparison` | Side-by-side, before/after, options |
| `framework` | Concept maps, relationship diagrams | Methodologies, models, architecture design | | `framework` | Methodologies, models, architecture |
| `timeline` | Chronological progression | History, project progress, evolution | | `timeline` | History, progress, evolution |
## Density Options
| Density | Count | Description |
|---------|-------|-------------|
| `minimal` | 1-2 | Core concepts only |
| `balanced` (Default) | 3-5 | Major sections coverage |
| `rich` | 6+ | Rich visual support |
## Style Gallery ## Style Gallery
| Style | Description | Best For | | Style | Best For |
|-------|-------------|----------| |-------|----------|
| `notion` (Default) | Minimalist hand-drawn line art | Knowledge sharing, SaaS, productivity | | `notion` (Default) | Knowledge sharing, SaaS, productivity |
| `elegant` | Refined, sophisticated | Business, thought leadership | | `elegant` | Business, thought leadership |
| `warm` | Friendly, approachable | Personal growth, lifestyle, education | | `warm` | Personal growth, lifestyle, education |
| `minimal` | Ultra-clean, zen-like | Philosophy, minimalism, core concepts | | `minimal` | Philosophy, core concepts |
| `blueprint` | Technical schematics | Architecture, system design, engineering | | `blueprint` | Architecture, system design |
| `watercolor` | Soft artistic with natural warmth | Lifestyle, travel, creative | | `watercolor` | Lifestyle, travel, creative |
| `editorial` | Magazine-style infographic | Tech explainers, journalism | | `editorial` | Tech explainers, journalism |
| `scientific` | Academic precise diagrams | Biology, chemistry, technical research | | `scientific` | Academic, technical research |
Full style specifications: `references/styles/<style>.md` Full styles: [references/styles.md](references/styles.md)
## Type × Style Compatibility
| | notion | warm | minimal | blueprint | watercolor | elegant | editorial | scientific |
|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| infographic | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓✓ |
| scene | ✓ | ✓✓ | ✓ | ✗ | ✓✓ | ✓ | ✓ | ✗ |
| flowchart | ✓✓ | ✓ | ✓ | ✓✓ | ✗ | ✓ | ✓✓ | ✓ |
| comparison | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✓✓ | ✓✓ | ✓ |
| framework | ✓✓ | ✓ | ✓✓ | ✓✓ | ✗ | ✓✓ | ✓ | ✓✓ |
| timeline | ✓✓ | ✓ | ✓ | ✓ | ✓✓ | ✓✓ | ✓✓ | ✓ |
✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
## Auto Selection ## Auto Selection
| Content Signals | Recommended Type | Recommended Style | | Content Signals | Type | Style |
|-----------------|------------------|-------------------| |-----------------|------|-------|
| API, metrics, data, comparison, numbers | infographic | blueprint, notion | | API, metrics, data, numbers | infographic | blueprint, notion |
| Story, emotion, journey, experience, personal | scene | warm, watercolor | | Story, emotion, journey | scene | warm, watercolor |
| How-to, steps, workflow, process, tutorial | flowchart | notion, minimal | | How-to, steps, workflow | flowchart | notion, minimal |
| vs, pros/cons, before/after, alternatives | comparison | notion, elegant | | vs, pros/cons, before/after | comparison | notion, elegant |
| Framework, model, architecture, principles | framework | blueprint, notion | | Framework, model, architecture | framework | blueprint, notion |
| History, timeline, progress, evolution | timeline | elegant, warm | | History, timeline, progress | timeline | elegant, warm |
## Output Directory
```
illustrations/{topic-slug}/
├── source-{slug}.{ext}
├── outline.md
├── prompts/
│ └── illustration-{slug}.md
└── NN-{type}-{slug}.png
```
**Slug**: Extract 2-4 word topic in kebab-case.
**Conflict**: Append `-YYYYMMDD-HHMMSS` if exists.
## Workflow ## Workflow
### Progress Copy this checklist and track progress:
``` ```
- [ ] Step 1: Setup & Analyze Progress:
- [ ] Step 2: Confirm Settings ⚠️ REQUIRED - [ ] Step 1: Pre-check
- [ ] Step 3: Generate Outline - [ ] Step 2: Setup & Analyze
- [ ] Step 4: Generate Images - [ ] Step 3: Confirm Settings ⚠️ REQUIRED
- [ ] Step 5: Finalize - [ ] Step 4: Generate Outline
- [ ] Step 5: Generate Images
- [ ] Step 6: Finalize
``` ```
### Step 1: Setup & Analyze ---
**1.1 Load Preferences (EXTEND.md)** ### Step 1: Pre-check
Use Bash to check EXTEND.md existence (priority order): **1.1 Determine Input Type**
| Input | Output Directory | Next |
|-------|------------------|------|
| File path | Ask user (1.2) | → 1.2 |
| Pasted content | `illustrations/{topic-slug}/` | → 1.4 |
**1.2 Determine Output Directory** (file path input only)
Check `default_output_dir` in preferences:
| Preference Value | Action |
|------------------|--------|
| `same-dir` | Use `{article-dir}/`, display "Output: {path}" |
| `imgs-subdir` | Use `{article-dir}/imgs/`, display "Output: {path}" |
| `illustrations-subdir` | Use `{article-dir}/illustrations/`, display "Output: {path}" |
| `independent` | Use `illustrations/{topic-slug}/`, display "Output: {path}" |
| Not configured | **MUST** ask with AskUserQuestion ↓ |
**AskUserQuestion** (when no preference):
- `{article-dir}/` - Same directory as article
- `{article-dir}/imgs/` - Images subdirectory
- `{article-dir}/illustrations/` - Illustrations subdirectory (Recommended)
- `illustrations/{topic-slug}/` - Independent directory
- Save as default - Remember this choice for future runs
**1.3 Check Existing Images**
Scan target directory for `.png/.jpg/.webp` files.
If images exist → AskUserQuestion: How to handle?
- `supplement` - Keep existing, generate only new positions
- `overwrite` - Overwrite same-name files
- `regenerate` - Clear all and regenerate
**1.4 Confirm Article Update Method** (file path input only)
AskUserQuestion: How to update article?
- `update` - Modify original file directly
- `copy` - Create `{name}-illustrated.md` copy
**1.5 Load Preferences (EXTEND.md)**
```bash ```bash
# Check project-level first
test -f .baoyu-skills/baoyu-article-illustrator/EXTEND.md && echo "project" test -f .baoyu-skills/baoyu-article-illustrator/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "user" test -f "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "user"
``` ```
┌──────────────────────────────────────────────────────────┬───────────────────┐ | Result | Action |
│ Path │ Location │ |--------|--------|
├──────────────────────────────────────────────────────────┼───────────────────┤ | Found | Read, parse, display summary |
│ .baoyu-skills/baoyu-article-illustrator/EXTEND.md │ Project directory │ | Not found | Ask with AskUserQuestion (see references/config/first-time-setup.md) |
├──────────────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md │ User home │
└──────────────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐ **Supports**: Watermark | Preferred type/style | Custom styles | Language | Output directory
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, display summary │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Ask user with AskUserQuestion (see references/config/first-time-setup.md) │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Watermark | Preferred type/style | Custom style definitions | Language preference ---
Schema: `references/config/preferences-schema.md` ### Step 2: Setup & Analyze
**1.2 Analyze Content** **2.1 Analyze Content**
Read article, detect language, classify content.
| Analysis | Description | | Analysis | Description |
|----------|-------------| |----------|-------------|
| Content type | Technical / Tutorial / Methodology / Narrative | | Content type | Technical / Tutorial / Methodology / Narrative |
| Core arguments | 2-5 main points that MUST be visualized | | Core arguments | 2-5 main points to visualize |
| Visual opportunities | Positions where illustrations add value | | Visual opportunities | Positions where illustrations add value |
| Recommended type | Based on content signals | | Recommended type | Based on content signals |
| Recommended density | Based on article length and complexity | | Recommended density | Based on length and complexity |
**1.3 Extract Core Arguments** **2.2 Extract Core Arguments**
Extract 2-5 core arguments that MUST be visualized:
- Main thesis - Main thesis
- Key concepts reader needs - Key concepts reader needs
- Comparisons/contrasts being made - Comparisons/contrasts
- Framework/model proposed - Framework/model proposed
**CRITICAL**: If article uses metaphors (e.g., "电锯切西瓜"), do NOT illustrate literally. Visualize the **underlying concept** instead. **CRITICAL**: If article uses metaphors (e.g., "电锯切西瓜"), do NOT illustrate literally. Visualize the **underlying concept**.
**1.4 Identify Positions** **2.3 Identify Positions**
**What to Illustrate**: **Illustrate**:
- Core arguments (REQUIRED) - Core arguments (REQUIRED)
- Abstract concepts needing visualization - Abstract concepts
- Data comparisons, metrics - Data comparisons
- Processes, workflows - Processes, workflows
**What NOT to Illustrate**: **Do NOT Illustrate**:
- Metaphors literally - Metaphors literally
- Decorative scenes without information - Decorative scenes
- Generic illustrations - Generic illustrations
### Step 2: Confirm Settings ⚠️ ---
### Step 3: Confirm Settings ⚠️
**Do NOT skip.** Use AskUserQuestion with 3-4 questions in ONE call. **Do NOT skip.** Use AskUserQuestion with 3-4 questions in ONE call.
**Question 1: Illustration Type** **Q1: Illustration Type**
- [Recommended based on analysis] (Recommended)
- infographic / scene / flowchart / comparison / framework / timeline / mixed
Based on content analysis, recommend type: **Q2: Density**
- [Recommended type based on signals] (Recommended) - minimal (1-2) - Core concepts only
- infographic - Data visualization, charts - balanced (3-5) (Recommended) - Major sections
- scene - Atmospheric, mood rendering - rich (6+) - Comprehensive support
- flowchart - Process, steps
- comparison - Side-by-side contrast
- framework - Concept relationships
- timeline - Chronological progression
- mixed - Combine multiple types
**Question 2: Density** **Q3: Style** (ALWAYS ask, even with preferred_style in EXTEND.md)
- minimal (1-2 images) - Core concepts only If EXTEND.md has `preferred_style`:
- balanced (3-5 images) (Recommended) - Major sections - [Custom style name + brief description] (Recommended)
- rich (6+ images) - Comprehensive visual support - [Top compatible built-in style 1]
- [Top compatible built-in style 2]
- [Top compatible built-in style 3]
**Question 3: Style** If no `preferred_style`:
- [Best compatible from matrix] (Recommended)
- [Other ✓✓ style 1]
- [Other ✓✓ style 2]
- [Other ✓ style]
Based on recommended Type, suggest compatible styles (see Type × Style Compatibility matrix): Style selection based on Type × Style compatibility matrix (references/styles.md).
- [Best compatible style for recommended type] (Recommended) Full specs: `references/styles/<style>.md`
- [Other highly compatible styles: ✓✓ from matrix]
- [Compatible styles: ✓ from matrix]
**Question 4** (only if source ≠ user language): **Q4** (only if source ≠ user language):
- Language: Source language / User language - Language: Source / User language
### Step 3: Generate Outline ---
Based on confirmed Type + Density + Style, generate illustration outline. ### Step 4: Generate Outline
**Outline Format** (`outline.md`): Save as `outline.md`:
```yaml ```yaml
--- ---
@@ -249,44 +214,48 @@ image_count: 4
## Illustration 1 ## Illustration 1
**Position**: [section] / [paragraph] **Position**: [section] / [paragraph]
**Purpose**: [why this illustration helps] **Purpose**: [why this helps]
**Visual Content**: [what to show] **Visual Content**: [what to show]
**Type Application**: [how type applies here] **Type Application**: [how type applies]
**Filename**: 01-infographic-concept-name.png **Filename**: 01-infographic-concept-name.png
## Illustration 2 ## Illustration 2
... ...
``` ```
**Outline Requirements**: **Requirements**:
- Each illustration position justified by content needs - Each position justified by content needs
- Type applied consistently across all illustrations - Type applied consistently
- Style characteristics reflected in visual descriptions - Style reflected in descriptions
- Count matches density selection - Count matches density
### Step 4: Generate Images ---
**4.1 Create Prompts** ### Step 5: Generate Images
Follow Prompt Construction principles below. Save each to `prompts/illustration-{slug}.md`. **5.1 Create Prompts**
**4.2 Select Generation Skill** Follow [references/prompt-construction.md](references/prompt-construction.md). Save to `prompts/illustration-{slug}.md`.
Check available image generation skills. If multiple, ask user to choose. **5.2 Select Generation Skill**
**4.3 Apply Watermark** (if enabled in preferences) Check available skills. If multiple, ask user.
Add to prompt: `Include a subtle watermark "[content]" positioned at [position] with approximately [opacity*100]% visibility.` **5.3 Apply Watermark** (if enabled)
**4.4 Generate** Add: `Include a subtle watermark "[content]" at [position].`
**5.4 Generate**
1. Generate sequentially 1. Generate sequentially
2. After each: "Generated X/N" 2. After each: "Generated X/N"
3. On failure: auto-retry once, then log and continue 3. On failure: retry once, then log and continue
### Step 5: Finalize ---
**5.1 Update Article** ### Step 6: Finalize
**6.1 Update Article**
Insert after corresponding paragraph: Insert after corresponding paragraph:
```markdown ```markdown
@@ -295,158 +264,60 @@ Insert after corresponding paragraph:
Alt text: concise description in article's language. Alt text: concise description in article's language.
**5.2 Output Summary** **6.2 Output Summary**
``` ```
Article Illustration Complete! Article Illustration Complete!
Article: [path] Article: [path]
Type: [type name] Type: [type] | Density: [level] | Style: [style]
Density: [minimal/balanced/rich] Location: [directory]
Style: [style name]
Location: [directory path]
Images: X/N generated Images: X/N generated
Positions: Positions:
- 01-infographic-xxx.png → After "[Section]" - 01-xxx.png → After "[Section]"
- 02-infographic-yyy.png → After "[Section]" - 02-yyy.png → After "[Section]"
[If failures] [If failures]
Failed: Failed:
- NN-type-zzz.png: [reason] - NN-zzz.png: [reason]
``` ```
## Prompt Construction ---
### Principles ## Output Directory
Good prompts must include:
1. **Layout Structure First**: Describe composition, zones, flow direction
2. **Specific Data/Labels**: Use actual numbers, terms from article
3. **Visual Relationships**: How elements connect
4. **Semantic Colors**: Meaning-based color choices (red=warning, green=efficient)
5. **Style Characteristics**: Line treatment, texture, mood
6. **Aspect Ratio**: End with ratio and complexity level
### Type-Specific Prompts
**Infographic**:
``` ```
[Title] - Data Visualization illustrations/{topic-slug}/
├── source-{slug}.{ext}
Layout: [grid/radial/hierarchical] ├── outline.md
├── prompts/
ZONES: │ └── illustration-{slug}.md
- Zone 1: [data point with specific values] └── NN-{type}-{slug}.png
- Zone 2: [comparison with metrics]
- Zone 3: [summary/conclusion]
LABELS: [specific numbers, percentages, terms from article]
COLORS: [semantic color mapping]
STYLE: [style characteristics]
ASPECT: 16:9
``` ```
**Scene**: **Slug**: 2-4 word topic in kebab-case.
``` **Conflict**: Append `-YYYYMMDD-HHMMSS` if exists.
[Title] - Atmospheric Scene
FOCAL POINT: [main subject]
ATMOSPHERE: [lighting, mood, environment]
MOOD: [emotion to convey]
COLOR TEMPERATURE: [warm/cool/neutral]
STYLE: [style characteristics]
ASPECT: 16:9
```
**Flowchart**:
```
[Title] - Process Flow
Layout: [left-right/top-down/circular]
STEPS:
1. [Step name] - [brief description]
2. [Step name] - [brief description]
...
CONNECTIONS: [arrow types, decision points]
STYLE: [style characteristics]
ASPECT: 16:9
```
**Comparison**:
```
[Title] - Comparison View
LEFT SIDE - [Option A]:
- [Point 1]
- [Point 2]
RIGHT SIDE - [Option B]:
- [Point 1]
- [Point 2]
DIVIDER: [visual separator]
STYLE: [style characteristics]
ASPECT: 16:9
```
**Framework**:
```
[Title] - Conceptual Framework
STRUCTURE: [hierarchical/network/matrix]
NODES:
- [Concept 1] - [role]
- [Concept 2] - [role]
RELATIONSHIPS: [how nodes connect]
STYLE: [style characteristics]
ASPECT: 16:9
```
**Timeline**:
```
[Title] - Chronological View
DIRECTION: [horizontal/vertical]
EVENTS:
- [Date/Period 1]: [milestone]
- [Date/Period 2]: [milestone]
MARKERS: [visual indicators]
STYLE: [style characteristics]
ASPECT: 16:9
```
### What to Avoid
- Vague descriptions ("a nice image")
- Literal metaphor illustrations
- Missing concrete labels/annotations
- Generic decorative elements
## Modification ## Modification
| Action | Steps | | Action | Steps |
|--------|-------| |--------|-------|
| **Edit** | Update prompt → Regenerate → Update reference | | **Edit** | Update prompt → Regenerate → Update reference |
| **Add** | Identify position → Create prompt → Generate → Update outline → Insert reference | | **Add** | Identify position → Create 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/styles.md](references/styles.md) | Style gallery & compatibility matrix | | [references/usage.md](references/usage.md) | Command syntax and options |
| [references/styles.md](references/styles.md) | Style gallery & compatibility |
| [references/prompt-construction.md](references/prompt-construction.md) | Prompt templates |
| `references/styles/<style>.md` | Full style specifications | | `references/styles/<style>.md` | Full style specifications |
| `references/config/preferences-schema.md` | EXTEND.md schema | | `references/config/preferences-schema.md` | EXTEND.md schema |
| `references/config/first-time-setup.md` | First-time setup flow | | `references/config/first-time-setup.md` | First-time setup flow |
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. See **Step 1.1** for paths and supported options. Custom configurations via EXTEND.md. See **Step 1.5** for paths and supported options.
@@ -15,7 +15,6 @@ watermark:
enabled: false enabled: false
content: "" content: ""
position: bottom-right # bottom-right|bottom-left|bottom-center|top-right position: bottom-right # bottom-right|bottom-left|bottom-center|top-right
opacity: 0.7 # 0.1-1.0
preferred_style: preferred_style:
name: null # Built-in or custom style name name: null # Built-in or custom style name
@@ -23,6 +22,8 @@ preferred_style:
language: null # zh|en|ja|ko|auto language: null # zh|en|ja|ko|auto
default_output_dir: null # same-dir|illustrations-subdir|independent
custom_styles: custom_styles:
- name: my-style - name: my-style
description: "Style description" description: "Style description"
@@ -44,10 +45,10 @@ custom_styles:
| `watermark.enabled` | bool | false | Enable watermark | | `watermark.enabled` | bool | false | Enable watermark |
| `watermark.content` | string | "" | Watermark text (@username or custom) | | `watermark.content` | string | "" | Watermark text (@username or custom) |
| `watermark.position` | enum | bottom-right | Position on image | | `watermark.position` | enum | bottom-right | Position on image |
| `watermark.opacity` | float | 0.7 | Transparency (0.1-1.0) |
| `preferred_style.name` | string | null | Style name or null | | `preferred_style.name` | string | null | Style name or null |
| `preferred_style.description` | string | "" | Custom notes/override | | `preferred_style.description` | string | "" | Custom notes/override |
| `language` | string | null | Output language (null = auto-detect) | | `language` | string | null | Output language (null = auto-detect) |
| `default_output_dir` | enum | null | Output directory preference (null = ask each time) |
| `custom_styles` | array | [] | User-defined styles | | `custom_styles` | array | [] | User-defined styles |
## Position Options ## Position Options
@@ -59,6 +60,14 @@ custom_styles:
| `bottom-center` | Bottom center | | `bottom-center` | Bottom center |
| `top-right` | Upper right corner | | `top-right` | Upper right corner |
## Output Directory Options
| Value | Description |
|-------|-------------|
| `same-dir` | Same directory as article |
| `illustrations-subdir` | `{article-dir}/illustrations/` subdirectory |
| `independent` | `illustrations/{topic-slug}/` in working directory |
## Custom Style Fields ## Custom Style Fields
| Field | Required | Description | | Field | Required | Description |
@@ -94,7 +103,6 @@ watermark:
enabled: true enabled: true
content: "@myaccount" content: "@myaccount"
position: bottom-right position: bottom-right
opacity: 0.5
preferred_style: preferred_style:
name: notion name: notion
@@ -0,0 +1,127 @@
# Prompt Construction
## Principles
Good prompts must include:
1. **Layout Structure First**: Describe composition, zones, flow direction
2. **Specific Data/Labels**: Use actual numbers, terms from article
3. **Visual Relationships**: How elements connect
4. **Semantic Colors**: Meaning-based color choices (red=warning, green=efficient)
5. **Style Characteristics**: Line treatment, texture, mood
6. **Aspect Ratio**: End with ratio and complexity level
## Type-Specific Templates
### Infographic
```
[Title] - Data Visualization
Layout: [grid/radial/hierarchical]
ZONES:
- Zone 1: [data point with specific values]
- Zone 2: [comparison with metrics]
- Zone 3: [summary/conclusion]
LABELS: [specific numbers, percentages, terms from article]
COLORS: [semantic color mapping]
STYLE: [style characteristics]
ASPECT: 16:9
```
### Scene
```
[Title] - Atmospheric Scene
FOCAL POINT: [main subject]
ATMOSPHERE: [lighting, mood, environment]
MOOD: [emotion to convey]
COLOR TEMPERATURE: [warm/cool/neutral]
STYLE: [style characteristics]
ASPECT: 16:9
```
### Flowchart
```
[Title] - Process Flow
Layout: [left-right/top-down/circular]
STEPS:
1. [Step name] - [brief description]
2. [Step name] - [brief description]
...
CONNECTIONS: [arrow types, decision points]
STYLE: [style characteristics]
ASPECT: 16:9
```
### Comparison
```
[Title] - Comparison View
LEFT SIDE - [Option A]:
- [Point 1]
- [Point 2]
RIGHT SIDE - [Option B]:
- [Point 1]
- [Point 2]
DIVIDER: [visual separator]
STYLE: [style characteristics]
ASPECT: 16:9
```
### Framework
```
[Title] - Conceptual Framework
STRUCTURE: [hierarchical/network/matrix]
NODES:
- [Concept 1] - [role]
- [Concept 2] - [role]
RELATIONSHIPS: [how nodes connect]
STYLE: [style characteristics]
ASPECT: 16:9
```
### Timeline
```
[Title] - Chronological View
DIRECTION: [horizontal/vertical]
EVENTS:
- [Date/Period 1]: [milestone]
- [Date/Period 2]: [milestone]
MARKERS: [visual indicators]
STYLE: [style characteristics]
ASPECT: 16:9
```
## What to Avoid
- Vague descriptions ("a nice image")
- Literal metaphor illustrations
- Missing concrete labels/annotations
- Generic decorative elements
## Watermark Integration
If watermark enabled in preferences, append:
```
Include a subtle watermark "[content]" positioned at [position] with approximately [opacity*100]% visibility.
```
@@ -0,0 +1,66 @@
# Usage
## Command Syntax
```bash
# Auto-select type and style based on content
/baoyu-article-illustrator path/to/article.md
# Specify type
/baoyu-article-illustrator path/to/article.md --type infographic
# Specify style
/baoyu-article-illustrator path/to/article.md --style blueprint
# Combine type and style
/baoyu-article-illustrator path/to/article.md --type flowchart --style notion
# Specify density
/baoyu-article-illustrator path/to/article.md --density rich
# Direct content input (paste mode)
/baoyu-article-illustrator
[paste content]
```
## Options
| Option | Description |
|--------|-------------|
| `--type <name>` | Illustration type (see Type Gallery in SKILL.md) |
| `--style <name>` | Visual style (see references/styles.md) |
| `--density <level>` | Image count: minimal / balanced / rich |
## Input Modes
| Mode | Trigger | Output Directory |
|------|---------|------------------|
| File path | `path/to/article.md` | Use `default_output_dir` preference, or ask if not set |
| Paste content | No path argument | `illustrations/{topic-slug}/` |
## Output Directory Options
| Value | Path |
|-------|------|
| `same-dir` | `{article-dir}/` |
| `illustrations-subdir` | `{article-dir}/illustrations/` |
| `independent` | `illustrations/{topic-slug}/` |
Configure in EXTEND.md: `default_output_dir: illustrations-subdir`
## Examples
**Technical article with data**:
```bash
/baoyu-article-illustrator api-design.md --type infographic --style blueprint
```
**Personal story**:
```bash
/baoyu-article-illustrator journey.md --type scene --style warm
```
**Tutorial with steps**:
```bash
/baoyu-article-illustrator how-to-deploy.md --type flowchart --density rich
```
+136 -358
View File
@@ -27,6 +27,17 @@ Create original knowledge comics with flexible art style × tone combinations.
| `--aspect` | 3:4 (default, portrait), 4:3 (landscape), 16:9 (widescreen) | Page aspect ratio | | `--aspect` | 3:4 (default, portrait), 4:3 (landscape), 16:9 (widescreen) | Page aspect ratio |
| `--lang` | auto (default), zh, en, ja, etc. | Output language | | `--lang` | auto (default), zh, en, ja, etc. | Output language |
### Partial Workflow Options
| Option | Description |
|--------|-------------|
| `--storyboard-only` | Generate storyboard only, skip prompts and images |
| `--prompts-only` | Generate storyboard + prompts, skip images |
| `--images-only` | Generate images from existing prompts directory |
| `--regenerate N` | Regenerate specific page(s) only (e.g., `3` or `2,5,8`) |
Details: [references/partial-workflows.md](references/partial-workflows.md)
### Art Styles (画风) ### Art Styles (画风)
| Style | 中文 | Description | | Style | 中文 | Description |
@@ -69,27 +80,25 @@ Presets with special rules beyond art+tone:
| ink-brush | neutral, dramatic, action, vintage | warm | romantic, energetic | | ink-brush | neutral, dramatic, action, vintage | warm | romantic, energetic |
| chalk | neutral, warm, energetic | vintage | dramatic, action, romantic | | chalk | neutral, warm, energetic | vintage | dramatic, action, romantic |
Art Style × Tone × Layout can be freely combined. Incompatible combinations work but may produce unexpected results. Details: [references/auto-selection.md](references/auto-selection.md)
## Auto Selection ## Auto Selection
Content signals determine default art + tone + layout (or preset): Content signals determine default art + tone + layout (or preset):
| Content Signals | Art Style | Tone | Layout | Preset | | Content Signals | Recommended |
|-----------------|-----------|------|--------|--------| |-----------------|-------------|
| Tutorial, how-to, beginner | manga | neutral | webtoon | **ohmsha** | | Tutorial, how-to, programming, educational | **ohmsha** preset |
| Computing, AI, programming | manga | neutral | dense | **ohmsha** | | Pre-1950, classical, ancient | realistic + vintage |
| Technical explanation, educational | manga | neutral | webtoon | **ohmsha** | | Personal story, mentor | ligne-claire + warm |
| Pre-1950, classical, ancient | realistic | vintage | cinematic | - | | Martial arts, wuxia | **wuxia** preset |
| Personal story, mentor | ligne-claire | warm | standard | - | | Romance, school life | **shoujo** preset |
| Conflict, breakthrough | (inherit) | dramatic | splash | - | | Biography, balanced | ligne-claire + neutral |
| Wine, food, business, lifestyle | realistic | neutral | cinematic | - |
| Martial arts, wuxia, xianxia | ink-brush | action | splash | **wuxia** |
| Romance, love, school life | manga | romantic | standard | **shoujo** |
| Biography, balanced | ligne-claire | neutral | mixed | - |
**When preset is recommended**: Load `references/presets/{preset}.md` and apply all special rules. **When preset is recommended**: Load `references/presets/{preset}.md` and apply all special rules.
Details: [references/auto-selection.md](references/auto-selection.md)
## Script Directory ## Script Directory
**Important**: All scripts are located in the `scripts/` subdirectory of this skill. **Important**: All scripts are located in the `scripts/` subdirectory of this skill.
@@ -111,384 +120,153 @@ Output directory: `comic/{topic-slug}/`
- Conflict: append timestamp (e.g., `turing-story-20260118-143052`) - Conflict: append timestamp (e.g., `turing-story-20260118-143052`)
**Contents**: **Contents**:
- `source-{slug}.{ext}` - Source files | File | Description |
- `analysis.md` - Content analysis |------|-------------|
- `storyboard.md` - Storyboard with panel breakdown | `source-{slug}.{ext}` | Source files |
- `characters/characters.md` - Character definitions | `analysis.md` | Content analysis |
- `characters/characters.png` - Character reference sheet | `storyboard.md` | Storyboard with panel breakdown |
- `prompts/NN-{cover|page}-[slug].md` - Generation prompts | `characters/characters.md` | Character definitions |
- `NN-{cover|page}-[slug].png` - Generated images | `characters/characters.png` | Character reference sheet |
- `{topic-slug}.pdf` - Final merged PDF | `prompts/NN-{cover\|page}-[slug].md` | Generation prompts |
| `NN-{cover\|page}-[slug].png` | Generated images |
| `{topic-slug}.pdf` | Final merged PDF |
## Language Handling
**Detection Priority**:
1. `--lang` flag (explicit)
2. EXTEND.md `language` setting
3. User's conversation language
4. Source content language
**Rule**: Use user's input language or saved language preference for ALL interactions:
- Storyboard outlines and scene descriptions
- Image generation prompts
- User selection options and confirmations
- Progress updates, questions, errors, summaries
Technical terms remain in English.
## Workflow ## Workflow
### Progress Checklist ### Progress Checklist
Copy and track progress:
``` ```
Comic Progress: Comic Progress:
- [ ] Step 1: Load preferences + Analyze content - [ ] Step 1: Setup & Analyze (1.1 Preferences, 1.2 Analyze, 1.3 Check existing)
- [ ] Step 2: Confirmation 1 - Style & options ⚠️ REQUIRED - [ ] Step 2: Confirmation - Style & options ⚠️ REQUIRED
- [ ] Step 3: Generate storyboard + characters - [ ] Step 3: Generate storyboard + characters
- [ ] Step 4: Confirmation 2 - Review outline (if requested) - [ ] Step 4: Review outline (conditional)
- [ ] Step 5: Generate images (sequential) - [ ] Step 5: Generate prompts
- [ ] Step 6: Merge to PDF - [ ] Step 6: Review prompts (conditional)
- [ ] Step 7: Completion report - [ ] Step 7: Generate images ⚠️ CHARACTER REF REQUIRED
- [ ] 7.1 Generate character sheet FIRST → characters/characters.png
- [ ] 7.2 Generate pages WITH --ref characters/characters.png
- [ ] Step 8: Merge to PDF
- [ ] Step 9: Completion report
``` ```
### Flow ### Flow
``` ```
Input → Preferences → Analyze → [Confirm 1: Style + Skip?] → Storyboard → [Confirm 2: if needed] → Generate → PDF → Complete Input → Preferences → Analyze → [Check Existing?] → [Confirm: Style + Reviews] → Storyboard → [Review?] → Prompts → [Review?] → Images → PDF → Complete
``` ```
### Step 1: Setup & Analyze ### Step Summary
**1.1 Load Preferences (EXTEND.md)** | Step | Action | Key Output |
|------|--------|------------|
| 1.1 | Load EXTEND.md preferences | Config loaded |
| 1.2 | Analyze content | `analysis.md` |
| 1.3 | Check existing directory | Handle conflicts |
| 2 | Confirm style, focus, audience, reviews | User preferences |
| 3 | Generate storyboard + characters | `storyboard.md`, `characters/` |
| 4 | Review outline (if requested) | User approval |
| 5 | Generate prompts | `prompts/*.md` |
| 6 | Review prompts (if requested) | User approval |
| **7.1** | **Generate character sheet FIRST** | `characters/characters.png` |
| **7.2** | Generate pages **with character ref** | `*.png` files |
| 8 | Merge to PDF | `{slug}.pdf` |
| 9 | Completion report | Summary |
Use Bash to check EXTEND.md existence (priority order): ### Step 7: Image Generation ⚠️ CRITICAL
**Character reference is MANDATORY for visual consistency.**
**7.1 Generate character sheet first**:
```bash
# Use Reference Sheet Prompt from characters/characters.md
npx -y bun ${SKILL_DIR}/../baoyu-image-gen/scripts/main.ts \
--promptfiles characters/characters.md \
--image characters/characters.png --ar 4:3
```
**Compress character sheet** (recommended):
Compress to reduce token usage when used as reference image:
- Use available image compression skill (if any)
- Or system tools: `pngquant`, `optipng`, `sips` (macOS)
- **Keep PNG format**, lossless compression preferred
**7.2 Generate each page WITH character reference**:
| Skill Capability | Strategy |
|------------------|----------|
| Supports `--ref` | Pass `characters/characters.png` with EVERY page |
| No `--ref` support | Prepend character descriptions to EVERY prompt file |
```bash ```bash
# Check project-level first # Example: ALWAYS include --ref for consistency
test -f .baoyu-skills/baoyu-comic/EXTEND.md && echo "project" npx -y bun ${SKILL_DIR}/../baoyu-image-gen/scripts/main.ts \
--promptfiles prompts/01-page-xxx.md \
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL) --image 01-page-xxx.png --ar 3:4 \
test -f "$HOME/.baoyu-skills/baoyu-comic/EXTEND.md" && echo "user" --ref characters/characters.png
``` ```
┌──────────────────────────────────────────────┬───────────────────┐ **Full workflow details**: [references/workflow.md](references/workflow.md)
│ Path │ Location │
├──────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/baoyu-comic/EXTEND.md │ Project directory │
├──────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-comic/EXTEND.md │ User home │
└──────────────────────────────────────────────┴───────────────────┘
**When EXTEND.md Found** → Read, parse, **output summary to user**: ### EXTEND.md Paths
``` | Path | Location |
📋 Loaded preferences from [full path] |------|----------|
├─ Watermark: [enabled/disabled] [content if enabled] | `.baoyu-skills/baoyu-comic/EXTEND.md` | Project directory |
├─ Art Style: [style name or "auto-select"] | `$HOME/.baoyu-skills/baoyu-comic/EXTEND.md` | User home |
├─ Tone: [tone name or "auto-select"]
├─ Layout: [layout or "auto-select"]
├─ Language: [language or "auto-detect"]
└─ Character presets: [count] defined
```
**MUST output this summary** so user knows their current configuration. Do not skip or silently load.
**When EXTEND.md Not Found** → First-time setup:
1. Inform user: "No preferences found. Let's set up your defaults."
2. Use AskUserQuestion to collect preferences (see `references/config/first-time-setup.md`)
3. Create EXTEND.md at user-chosen location
4. Confirm: "✓ Preferences saved to [path]"
**EXTEND.md Supports**: Watermark | Preferred art/tone/layout | Custom style definitions | Character presets | Language preference **EXTEND.md Supports**: Watermark | Preferred art/tone/layout | Custom style definitions | Character presets | Language preference
Schema: `references/config/preferences-schema.md` Schema: [references/config/preferences-schema.md](references/config/preferences-schema.md)
**Important**: Once EXTEND.md exists, watermark, language, and style defaults are NOT asked again in Confirmation 1 or 2. These are session-persistent settings.
**1.2 Analyze Content → `analysis.md`**
Read source content, save it if needed, and perform deep analysis.
**Actions**:
1. **Save source content** (if not already a file):
- If user provides a file path: use as-is
- If user pastes content: save to `source.md` in target directory
2. Read source content
3. **Deep analysis** following `references/analysis-framework.md`:
- Target audience identification
- Value proposition for readers
- Core themes and narrative potential
- Key figures and their story arcs
4. Detect source language
5. **Determine language**:
- If EXTEND.md has `language` → use it
- Else if `--lang` option provided → use it
- Else → use detected source language
6. Determine recommended page count:
- Short story: 5-8 pages
- Medium complexity: 9-15 pages
- Full biography: 16-25 pages
7. Analyze content signals for art/tone/layout recommendations
8. **Save to `analysis.md`**
**analysis.md Format**: YAML front matter (title, topic, time_span, source_language, user_language, aspect_ratio, recommended_page_count, recommended_art, recommended_tone) + sections for Target Audience, Value Proposition, Core Themes, Key Figures & Story Arcs, Content Signals, Recommended Approaches. See `references/analysis-framework.md` for full template.
### Step 2: Confirmation 1 - Style & Options ⚠️
**Purpose**: Select visual style + decide whether to review outline before generation. **Do NOT skip.**
**Note**: Watermark and language already configured in EXTEND.md (Step 1).
**Display summary**:
- Content type + topic identified
- Key figures extracted
- Time span detected
- Recommended page count
- Language: [from EXTEND.md or detected]
- **Recommended style**: [art] + [tone] (based on content signals)
**Use AskUserQuestion** for:
**Question 1: Visual Style**
If a preset is recommended (see Auto Selection), show it first:
```
header: "Style"
question: "Which visual style for this comic?"
options:
- label: "[preset name] preset (Recommended)" # If preset recommended
description: "[preset description] - includes special rules"
- label: "[recommended art] + [recommended tone] (Recommended)" # If no preset
description: "Best match for your content based on analysis"
- label: "ligne-claire + neutral"
description: "Classic educational, Logicomix style"
- label: "ohmsha preset"
description: "Educational manga with visual metaphors, gadgets, NO talking heads"
- label: "Custom"
description: "Specify your own art + tone or preset"
```
**Preset vs Art+Tone**: Presets include special rules beyond art+tone. `ohmsha` = manga + neutral + visual metaphor rules + character roles + NO talking heads. Plain `manga + neutral` does NOT include these rules.
**Question 2: Narrative Focus** (multiSelect: true)
```
header: "Focus"
question: "What should the comic emphasize? (Select all that apply)"
options:
- label: "Biography/life story"
description: "Follow a person's journey through key life events"
- label: "Concept explanation"
description: "Break down complex ideas visually"
- label: "Historical event"
description: "Dramatize important historical moments"
- label: "Tutorial/how-to"
description: "Step-by-step educational guide"
```
**Question 3: Target Audience**
```
header: "Audience"
question: "Who is the primary reader?"
options:
- label: "General readers"
description: "Broad appeal, accessible content"
- label: "Students/learners"
description: "Educational focus, clear explanations"
- label: "Industry professionals"
description: "Technical depth, domain knowledge"
- label: "Children/young readers"
description: "Simplified language, engaging visuals"
```
**Question 4: Outline Review**
```
header: "Review"
question: "Do you want to review the outline before image generation?"
options:
- label: "Yes, let me review (Recommended)"
description: "Review storyboard and characters before generating images"
- label: "No, generate directly"
description: "Skip outline review, start generating immediately"
```
**After response**:
1. Update `analysis.md` with user preferences
2. **Store `skip_outline_review`** flag based on Question 4 response
3. → Step 3
### Step 3: Generate Storyboard + Characters
Create storyboard and character definitions using the confirmed style from Step 2.
**Loading Style References**:
- Art style: `references/art-styles/{art}.md`
- Tone: `references/tones/{tone}.md`
- If preset (ohmsha/wuxia/shoujo): also load `references/presets/{preset}.md`
**Generate**:
1. **Storyboard** (`storyboard.md`):
- YAML front matter with art_style, tone, layout, aspect_ratio
- Cover design
- Each page: layout, panel breakdown, visual prompts
- **Written in user's preferred language** (from Step 1)
- Reference: `references/storyboard-template.md`
- **If using preset**: Load and apply preset rules from `references/presets/`
2. **Character definitions** (`characters/characters.md`):
- Visual specs matching the art style (in user's preferred language)
- Include Reference Sheet Prompt for later image generation
- Reference: `references/character-template.md`
**After generation**:
- If `skip_outline_review` is true → Skip Step 4, go directly to Step 5
- If `skip_outline_review` is false → Continue to Step 4
### Step 4: Confirmation 2 - Review Outline (Conditional)
**Skip this step** if user selected "No, generate directly" in Step 2.
**Purpose**: User reviews and confirms storyboard + characters before generation.
**Display**:
- Page count and structure
- Art style + Tone combination
- Page-by-page summary (Cover → P1 → P2...)
- Character list with brief descriptions
**Use AskUserQuestion**:
```
header: "Confirm"
question: "Ready to generate images with this outline?"
options:
- label: "Yes, proceed (Recommended)"
description: "Generate character sheet and comic pages"
- label: "Edit storyboard first"
description: "I'll modify storyboard.md before continuing"
- label: "Edit characters first"
description: "I'll modify characters/characters.md before continuing"
- label: "Edit both"
description: "I'll modify both files before continuing"
```
**After response**:
1. If user wants to edit → Wait for user to finish editing, then ask again
2. If user confirms → Continue to Step 5
### Step 5: Generate Images
With confirmed storyboard + art style + tone + aspect ratio:
**Style Reference Loading**:
- Read `references/art-styles/{art}.md` for rendering guidelines
- Read `references/tones/{tone}.md` for mood/color adjustments
- If preset: Read `references/presets/{preset}.md` for special rules
**5.1 Generate Character Reference Sheet** (first):
1. Use Reference Sheet Prompt from `characters/characters.md`
2. Generate → `characters/characters.png`
3. This ensures visual consistency for all subsequent pages
**5.2 Generate Comic Pages**:
**For each page (cover + pages)**:
1. Save prompt to `prompts/NN-{cover|page}-[slug].md` (in user's preferred language)
2. Generate image using confirmed art style and tone guidelines
3. Report progress after each generation
**Watermark Application** (if enabled in preferences):
Add to each image generation prompt:
```
Include a subtle watermark "[content]" positioned at [position]
with approximately [opacity*100]% visibility. The watermark should
be legible but not distracting from the comic panels and storytelling.
Ensure watermark does not overlap speech bubbles or key action.
```
Reference: `references/config/watermark-guide.md`
**Image Generation Skill Selection**:
- Check available image generation skills
- If multiple skills available, ask user preference
**Character Reference Handling** (IMPORTANT for visual consistency):
1. Read the selected image generation skill's SKILL.md
2. Check if it supports reference image input (look for parameters like `--ref`, `--reference`, `--image-ref`, etc.)
| Skill Support | Action |
|---------------|--------|
| **Supports reference image** | Pass `characters/characters.png` using the skill's reference parameter |
| **Does NOT support reference image** | Prepend `characters/characters.md` content to each page prompt |
Always verify the exact parameter name from the skill's documentation before calling.
**Session Management**:
If image generation skill supports `--sessionId`:
1. Generate unique session ID: `comic-{topic-slug}-{timestamp}`
2. Use same session ID for all pages
3. Ensures visual consistency across generated images
### Step 6: Merge to PDF
After all images generated:
```bash
npx -y bun ${SKILL_DIR}/scripts/merge-to-pdf.ts <comic-dir>
```
Creates `{topic-slug}.pdf` with all pages as full-page images.
### Step 7: Completion Report
```
Comic Complete!
Title: [title] | Art: [art] | Tone: [tone] | Pages: [count] | Aspect: [ratio] | Language: [lang]
Watermark: [enabled/disabled]
Location: [path]
✓ analysis.md
✓ characters.png
✓ 00-cover-[slug].png ... NN-page-[slug].png
✓ {topic-slug}.pdf
```
## Page Modification
| Action | Steps |
|--------|-------|
| **Edit** | Update prompt → Regenerate image → Regenerate PDF |
| **Add** | Create prompt at position → Generate image → Renumber subsequent (NN+1) → Update storyboard → Regenerate PDF |
| **Delete** | Remove files → Renumber subsequent (NN-1) → Update storyboard → Regenerate PDF |
**File naming**: `NN-{cover|page}-[slug].png` (e.g., `03-page-enigma-machine.png`)
- Slugs: kebab-case, unique, derived from content
- Renumbering: Update NN prefix only, slugs unchanged
## Preset: Ohmsha
Default: Use Doraemon characters (大雄=learner, 哆啦A梦=mentor, 胖虎=challenge, 静香=support). Custom characters via `--characters "Student:小明,Mentor:教授"` or character presets in EXTEND.md.
Requirements: Visual metaphors, NO talking heads, narrative page titles.
See `references/presets/ohmsha.md` and `references/ohmsha-guide.md` for details.
## References ## References
Detailed templates and guidelines in `references/` directory:
**Core Templates**: **Core Templates**:
- `analysis-framework.md` - Deep content analysis for comic adaptation - [analysis-framework.md](references/analysis-framework.md) - Deep content analysis
- `character-template.md` - Character definition format and examples - [character-template.md](references/character-template.md) - Character definition format
- `storyboard-template.md` - Storyboard structure and panel breakdown - [storyboard-template.md](references/storyboard-template.md) - Storyboard structure
- `ohmsha-guide.md` - Ohmsha manga style specifics - [ohmsha-guide.md](references/ohmsha-guide.md) - Ohmsha manga specifics
**Style Definitions** (new 3-dimension system): **Style Definitions**:
- `art-styles/` - Art style definitions (ligne-claire, manga, realistic, ink-brush, chalk) - `references/art-styles/` - Art styles (ligne-claire, manga, realistic, ink-brush, chalk)
- `tones/` - Tone definitions (neutral, warm, dramatic, romantic, energetic, vintage, action) - `references/tones/` - Tones (neutral, warm, dramatic, romantic, energetic, vintage, action)
- `presets/` - Preset shortcuts with special rules (ohmsha, wuxia, shoujo) - `references/presets/` - Presets with special rules (ohmsha, wuxia, shoujo)
- `layouts/` - Layout definitions (standard, cinematic, dense, splash, mixed, webtoon) - `references/layouts/` - Layouts (standard, cinematic, dense, splash, mixed, webtoon)
**Workflow**:
- [workflow.md](references/workflow.md) - Full workflow details
- [auto-selection.md](references/auto-selection.md) - Content signal analysis
- [partial-workflows.md](references/partial-workflows.md) - Partial workflow options
**Config**: **Config**:
- `config/preferences-schema.md` - EXTEND.md schema - [config/preferences-schema.md](references/config/preferences-schema.md) - EXTEND.md schema
- `config/first-time-setup.md` - First-time setup flow - [config/first-time-setup.md](references/config/first-time-setup.md) - First-time setup
- `config/watermark-guide.md` - Watermark configuration - [config/watermark-guide.md](references/config/watermark-guide.md) - Watermark configuration
## Notes ## Notes
- Auto-retry once on failure | Cartoon alternatives for sensitive figures - Image generation: 10-30 seconds per page
- Use confirmed language preference | Maintain style consistency - Auto-retry once on generation failure
- **Step 2 confirmation required** - do not skip (style selection + outline review option) - Use stylized alternatives for sensitive public figures
- **Step 4 conditional** - only if user requested outline review in Step 2 - Maintain style consistency via session ID
- Watermark/language configured once in EXTEND.md, not asked in confirmations - **Step 2 confirmation required** - do not skip
- **Steps 4/6 conditional** - only if user requested in Step 2
## Extension Support - **Step 7.1 character sheet MUST be generated before pages** - ensures consistency
- **Step 7.2 EVERY page MUST reference characters** - use `--ref` or embed descriptions
Custom configurations via EXTEND.md. See **Step 1.1** for paths and supported options. - Watermark/language configured once in EXTEND.md
@@ -0,0 +1,58 @@
# Auto Selection
Content signals determine default art + tone + layout (or preset).
## Content Signal Matrix
| Content Signals | Art Style | Tone | Layout | Preset |
|-----------------|-----------|------|--------|--------|
| Tutorial, how-to, beginner | manga | neutral | webtoon | **ohmsha** |
| Computing, AI, programming | manga | neutral | dense | **ohmsha** |
| Technical explanation, educational | manga | neutral | webtoon | **ohmsha** |
| Pre-1950, classical, ancient | realistic | vintage | cinematic | - |
| Personal story, mentor | ligne-claire | warm | standard | - |
| Conflict, breakthrough | (inherit) | dramatic | splash | - |
| Wine, food, business, lifestyle | realistic | neutral | cinematic | - |
| Martial arts, wuxia, xianxia | ink-brush | action | splash | **wuxia** |
| Romance, love, school life | manga | romantic | standard | **shoujo** |
| Biography, balanced | ligne-claire | neutral | mixed | - |
## Preset Recommendation Rules
**When preset is recommended**: Load `presets/{preset}.md` and apply all special rules.
### ohmsha
- **Triggers**: Tutorial, technical, educational, computing, programming, how-to, beginner
- **Special rules**: Visual metaphors, NO talking heads, gadget reveals, Doraemon-style characters
- **Base**: manga + neutral + webtoon/dense
### wuxia
- **Triggers**: Martial arts, wuxia, xianxia, cultivation, swordplay
- **Special rules**: Qi effects, combat visuals, atmospheric elements
- **Base**: ink-brush + action + splash
### shoujo
- **Triggers**: Romance, love story, school life, emotional drama
- **Special rules**: Decorative elements, eye details, romantic beats
- **Base**: manga + romantic + standard
## Compatibility Matrix
Art Style × Tone combinations work best when matched appropriately:
| Art Style | ✓✓ Best | ✓ Works | ✗ Avoid |
|-----------|---------|---------|---------|
| ligne-claire | neutral, warm | dramatic, vintage, energetic | romantic, action |
| manga | neutral, romantic, energetic, action | warm, dramatic | vintage |
| realistic | neutral, warm, dramatic, vintage | action | romantic, energetic |
| ink-brush | neutral, dramatic, action, vintage | warm | romantic, energetic |
| chalk | neutral, warm, energetic | vintage | dramatic, action, romantic |
**Note**: Art Style × Tone × Layout can be freely combined. Incompatible combinations work but may produce unexpected results.
## Priority Order
1. User-specified options (`--art`, `--tone`, `--style`)
2. EXTEND.md defaults
3. Content signal analysis → auto-selection
4. Fallback: ligne-claire + neutral + standard
@@ -15,7 +15,6 @@ watermark:
enabled: false enabled: false
content: "" content: ""
position: bottom-right # bottom-right|bottom-left|bottom-center|top-right position: bottom-right # bottom-right|bottom-left|bottom-center|top-right
opacity: 0.5 # 0.1-1.0 (lower default for comics)
preferred_art: null # ligne-claire|manga|realistic|ink-brush|chalk preferred_art: null # ligne-claire|manga|realistic|ink-brush|chalk
preferred_tone: null # neutral|warm|dramatic|romantic|energetic|vintage|action preferred_tone: null # neutral|warm|dramatic|romantic|energetic|vintage|action
@@ -42,7 +41,6 @@ character_presets:
| `watermark.enabled` | bool | false | Enable watermark | | `watermark.enabled` | bool | false | Enable watermark |
| `watermark.content` | string | "" | Watermark text (@username or custom) | | `watermark.content` | string | "" | Watermark text (@username or custom) |
| `watermark.position` | enum | bottom-right | Position on image | | `watermark.position` | enum | bottom-right | Position on image |
| `watermark.opacity` | float | 0.5 | Transparency (0.1-1.0, lower for comics) |
| `preferred_art` | string | null | Art style (ligne-claire, manga, realistic, ink-brush, chalk) | | `preferred_art` | string | null | Art style (ligne-claire, manga, realistic, ink-brush, chalk) |
| `preferred_tone` | string | null | Tone (neutral, warm, dramatic, romantic, energetic, vintage, action) | | `preferred_tone` | string | null | Tone (neutral, warm, dramatic, romantic, energetic, vintage, action) |
| `preferred_layout` | string | null | Layout preference or null | | `preferred_layout` | string | null | Layout preference or null |
@@ -113,7 +111,6 @@ watermark:
enabled: true enabled: true
content: "@comicstudio" content: "@comicstudio"
position: bottom-right position: bottom-right
opacity: 0.4
preferred_art: manga preferred_art: manga
preferred_tone: neutral preferred_tone: neutral
@@ -28,19 +28,6 @@ description: Watermark configuration guide for baoyu-comic
| `bottom-center` | Webtoon vertical scroll, centered designs | Text-heavy bottom area | | `bottom-center` | Webtoon vertical scroll, centered designs | Text-heavy bottom area |
| `top-right` | **Not recommended for comics** | Always - conflicts with page numbers | | `top-right` | **Not recommended for comics** | Always - conflicts with page numbers |
## Opacity for Comics
Comics typically use lower opacity than infographics to avoid disrupting panel flow:
| Opacity | Visual Effect | Use Case |
|---------|---------------|----------|
| 0.3 | Very subtle, barely visible | **Recommended for comics** |
| 0.4 | Light presence | Balance of visibility and subtlety |
| 0.5 | Noticeable | Standard comics default |
| 0.6+ | Strong presence | Not recommended (distracting) |
**Default**: 0.5 (compared to 0.7 for infographics)
## Content Format ## Content Format
| Format | Example | Style | | Format | Example | Style |
@@ -63,10 +50,9 @@ Comics typically use lower opacity than infographics to avoid disrupting panel f
When watermark is enabled, add to image generation prompt: When watermark is enabled, add to image generation prompt:
``` ```
Include a subtle watermark "[content]" positioned at [position] Include a subtle watermark "[content]" positioned at [position].
with approximately [opacity*100]% visibility. The watermark should The watermark should be legible but not distracting from the comic panels
be legible but not distracting from the comic panels and storytelling. and storytelling. Ensure watermark does not overlap speech bubbles or key action.
Ensure watermark does not overlap speech bubbles or key action.
``` ```
## Common Issues ## Common Issues
@@ -76,5 +62,5 @@ Ensure watermark does not overlap speech bubbles or key action.
| Watermark invisible on dark panels | Adjust contrast or add subtle outline | | Watermark invisible on dark panels | Adjust contrast or add subtle outline |
| Watermark overlaps speech bubble | Change position or lower on page | | Watermark overlaps speech bubble | Change position or lower on page |
| Watermark inconsistent across pages | Use session ID for consistency | | Watermark inconsistent across pages | Use session ID for consistency |
| Watermark too prominent | Decrease opacity (0.3-0.4 for comics) | | Watermark too prominent | Change position or reduce size |
| Conflicts with page number | Never use top-right position | | Conflicts with page number | Never use top-right position |
@@ -0,0 +1,123 @@
# Partial Workflows
Options to run specific parts of the workflow.
## Options Summary
| Option | Steps Executed | Output |
|--------|----------------|--------|
| `--storyboard-only` | 1-3 | `storyboard.md` + `characters/` |
| `--prompts-only` | 1-5 | + `prompts/*.md` |
| `--images-only` | 7-9 | + images + PDF |
| `--regenerate N` | 7 (partial) | Specific page(s) + PDF |
---
## Using `--storyboard-only`
Generate storyboard and characters without prompts or images:
```bash
/baoyu-comic content.md --storyboard-only
```
**Workflow**: Steps 1-3 only (stop after storyboard + characters)
**Output**:
- `analysis.md`
- `storyboard.md`
- `characters/characters.md`
**Use case**: Review and edit the storyboard before generating images. Useful for:
- Getting feedback on the narrative structure
- Making manual adjustments to panel layouts
- Defining custom characters
---
## Using `--prompts-only`
Generate storyboard, characters, and prompts without images:
```bash
/baoyu-comic content.md --prompts-only
```
**Workflow**: Steps 1-5 (generate prompts, skip images)
**Output**:
- `analysis.md`
- `storyboard.md`
- `characters/characters.md`
- `prompts/*.md`
**Use case**: Review and edit prompts before image generation. Useful for:
- Fine-tuning image generation prompts
- Ensuring visual consistency before committing to generation
- Making style adjustments at the prompt level
---
## Using `--images-only`
Generate images from existing prompts (starts at Step 7):
```bash
/baoyu-comic comic/topic-slug/ --images-only
```
**Workflow**: Skip to Step 7, then 8-9
**Prerequisites** (must exist in directory):
- `prompts/` directory with page prompt files
- `storyboard.md` with style information
- `characters/characters.md` with character definitions
**Output**:
- `characters/characters.png` (if not exists)
- `NN-{cover|page}-[slug].png` images
- `{topic-slug}.pdf`
**Use case**: Re-generate images after editing prompts. Useful for:
- Recovering from failed image generation
- Trying different image generation settings
- Regenerating after manual prompt edits
---
## Using `--regenerate`
Regenerate specific pages only:
```bash
# Single page
/baoyu-comic comic/topic-slug/ --regenerate 3
# Multiple pages
/baoyu-comic comic/topic-slug/ --regenerate 2,5,8
# Cover page
/baoyu-comic comic/topic-slug/ --regenerate 0
```
**Workflow**:
1. Read existing prompts for specified pages
2. Regenerate images only for those pages
3. Regenerate PDF
**Prerequisites** (must exist):
- `prompts/NN-{cover|page}-[slug].md` for specified pages
- `characters/characters.png` (for reference)
**Output**:
- Regenerated `NN-{cover|page}-[slug].png` for specified pages
- Updated `{topic-slug}.pdf`
**Use case**: Fix specific pages without regenerating entire comic. Useful for:
- Fixing a single problematic page
- Iterating on specific visuals
- Regenerating pages after prompt edits
**Page numbering**:
- `0` = Cover page
- `1-N` = Content pages
@@ -41,16 +41,18 @@ Every technical concept MUST be visualized as a metaphor:
### Character Roles (Required) ### Character Roles (Required)
Define characters before generating: **DEFAULT: Use Doraemon characters** unless user explicitly specifies `--characters` or has character presets in EXTEND.md.
| Role | Default | Traits | | Role | Default Character | Visual | Traits |
|------|---------|--------| |------|-------------------|--------|--------|
| Student (Role A) | 大雄 | Confused, asks basic but crucial questions, represents reader | | Student (Role A) | 大雄 (Nobita) | Boy, 10yo, round glasses, black hair, yellow shirt, navy shorts | Confused, asks basic but crucial questions, represents reader |
| Mentor (Role B) | 哆啦A梦 | Knowledgeable, patient, uses gadgets as technical metaphors | | Mentor (Role B) | 哆啦A梦 (Doraemon) | Blue robot cat, white belly, 4D pocket, red nose, golden bell | Knowledgeable, patient, uses gadgets as technical metaphors |
| Challenge (Role C, optional) | 胖虎 | Represents misunderstanding, or "noise" in the data | | Challenge (Role C) | 胖虎 (Gian) | Stocky boy, small eyes, orange shirt | Represents misunderstanding, or "noise" in the data |
| Support (Role D, optional) | 静香 | Asks clarifying questions, provides alternative perspectives | | Support (Role D) | 静香 (Shizuka) | Cute girl, black short hair, pink dress | Asks clarifying questions, provides alternative perspectives |
Custom characters via `--characters "Student:小明,Mentor:教授"` or EXTEND.md presets. **IMPORTANT**: These Doraemon characters ARE the default for ohmsha preset. Generate character definitions using these exact characters unless user requests otherwise.
To use custom characters: `--characters "Student:小明,Mentor:教授"` or define in EXTEND.md.
### Page Title Convention ### Page Title Convention
+505
View File
@@ -0,0 +1,505 @@
# Complete Workflow
Full workflow for generating knowledge comics.
## Progress Checklist
Copy and track progress:
```
Comic Progress:
- [ ] Step 1: Setup & Analyze
- [ ] 1.1 Load preferences
- [ ] 1.2 Analyze content
- [ ] 1.3 Check existing ⚠️ REQUIRED
- [ ] Step 2: Confirmation 1 - Style & options ⚠️ REQUIRED
- [ ] Step 3: Generate storyboard + characters
- [ ] Step 4: Review outline (conditional)
- [ ] Step 5: Generate prompts
- [ ] Step 6: Review prompts (conditional)
- [ ] Step 7: Generate images
- [ ] Step 8: Merge to PDF
- [ ] Step 9: Completion report
```
## Flow Diagram
```
Input → Preferences → Analyze → [Check Existing?] → [Confirm 1: Style + Reviews] → Storyboard → [Review Outline?] → Prompts → [Review Prompts?] → Images → PDF → Complete
```
---
## Step 1: Setup & Analyze
### 1.1 Load Preferences (EXTEND.md)
Use Bash to check EXTEND.md existence (priority order):
```bash
# Check project-level first
test -f .baoyu-skills/baoyu-comic/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/baoyu-comic/EXTEND.md" && echo "user"
```
| Path | Location |
|------|----------|
| `.baoyu-skills/baoyu-comic/EXTEND.md` | Project directory |
| `$HOME/.baoyu-skills/baoyu-comic/EXTEND.md` | User home |
**When EXTEND.md Found** → Read, parse, **output summary to user**:
```
📋 Loaded preferences from [full path]
├─ Watermark: [enabled/disabled] [content if enabled]
├─ Art Style: [style name or "auto-select"]
├─ Tone: [tone name or "auto-select"]
├─ Layout: [layout or "auto-select"]
├─ Language: [language or "auto-detect"]
└─ Character presets: [count] defined
```
**MUST output this summary** so user knows their current configuration. Do not skip or silently load.
**When EXTEND.md Not Found** → First-time setup:
1. Inform user: "No preferences found. Let's set up your defaults."
2. Use AskUserQuestion to collect preferences (see `config/first-time-setup.md`)
3. Create EXTEND.md at user-chosen location
4. Confirm: "✓ Preferences saved to [path]"
**EXTEND.md Supports**: Watermark | Preferred art/tone/layout | Custom style definitions | Character presets | Language preference
Schema: `config/preferences-schema.md`
**Important**: Once EXTEND.md exists, watermark, language, and style defaults are NOT asked again in Confirmation 1 or 2. These are session-persistent settings.
### 1.2 Analyze Content → `analysis.md`
Read source content, save it if needed, and perform deep analysis.
**Actions**:
1. **Save source content** (if not already a file):
- If user provides a file path: use as-is
- If user pastes content: save to `source.md` in target directory
2. Read source content
3. **Deep analysis** following `analysis-framework.md`:
- Target audience identification
- Value proposition for readers
- Core themes and narrative potential
- Key figures and their story arcs
4. Detect source language
5. **Determine language**:
- If EXTEND.md has `language` → use it
- Else if `--lang` option provided → use it
- Else → use detected source language
6. Determine recommended page count:
- Short story: 5-8 pages
- Medium complexity: 9-15 pages
- Full biography: 16-25 pages
7. Analyze content signals for art/tone/layout recommendations
8. **Save to `analysis.md`**
**analysis.md Format**: YAML front matter (title, topic, time_span, source_language, user_language, aspect_ratio, recommended_page_count, recommended_art, recommended_tone) + sections for Target Audience, Value Proposition, Core Themes, Key Figures & Story Arcs, Content Signals, Recommended Approaches. See `analysis-framework.md` for full template.
### 1.3 Check Existing Content ⚠️ REQUIRED
**MUST execute before proceeding to Step 2.**
Use Bash to check if output directory exists:
```bash
test -d "comic/{topic-slug}" && echo "exists"
```
**If directory exists**, use AskUserQuestion:
```
header: "Existing"
question: "Existing content found. How to proceed?"
options:
- label: "Regenerate storyboard"
description: "Keep images, regenerate storyboard and characters only"
- label: "Regenerate images"
description: "Keep storyboard, regenerate images only"
- label: "Backup and regenerate"
description: "Backup to {slug}-backup-{timestamp}, then regenerate all"
- label: "Exit"
description: "Cancel, keep existing content unchanged"
```
Save result and handle accordingly:
- **Regenerate storyboard**: Skip to Step 3, preserve `prompts/` and images
- **Regenerate images**: Skip to Step 7, use existing prompts
- **Backup and regenerate**: Move directory, start fresh from Step 2
- **Exit**: End workflow immediately
---
## Step 2: Confirmation 1 - Style & Options ⚠️
**Purpose**: Select visual style + decide whether to review outline before generation. **Do NOT skip.**
**Note**: Watermark and language already configured in EXTEND.md (Step 1).
**Display summary**:
- Content type + topic identified
- Key figures extracted
- Time span detected
- Recommended page count
- Language: [from EXTEND.md or detected]
- **Recommended style**: [art] + [tone] (based on content signals)
**Use AskUserQuestion** for:
### Question 1: Visual Style
If a preset is recommended (see `auto-selection.md`), show it first:
```
header: "Style"
question: "Which visual style for this comic?"
options:
- label: "[preset name] preset (Recommended)" # If preset recommended
description: "[preset description] - includes special rules"
- label: "[recommended art] + [recommended tone] (Recommended)" # If no preset
description: "Best match for your content based on analysis"
- label: "ligne-claire + neutral"
description: "Classic educational, Logicomix style"
- label: "ohmsha preset"
description: "Educational manga with visual metaphors, gadgets, NO talking heads"
- label: "Custom"
description: "Specify your own art + tone or preset"
```
**Preset vs Art+Tone**: Presets include special rules beyond art+tone. `ohmsha` = manga + neutral + visual metaphor rules + character roles + NO talking heads. Plain `manga + neutral` does NOT include these rules.
### Question 2: Narrative Focus (multiSelect: true)
```
header: "Focus"
question: "What should the comic emphasize? (Select all that apply)"
options:
- label: "Biography/life story"
description: "Follow a person's journey through key life events"
- label: "Concept explanation"
description: "Break down complex ideas visually"
- label: "Historical event"
description: "Dramatize important historical moments"
- label: "Tutorial/how-to"
description: "Step-by-step educational guide"
```
### Question 3: Target Audience
```
header: "Audience"
question: "Who is the primary reader?"
options:
- label: "General readers"
description: "Broad appeal, accessible content"
- label: "Students/learners"
description: "Educational focus, clear explanations"
- label: "Industry professionals"
description: "Technical depth, domain knowledge"
- label: "Children/young readers"
description: "Simplified language, engaging visuals"
```
### Question 4: Outline Review
```
header: "Review"
question: "Do you want to review the outline before image generation?"
options:
- label: "Yes, let me review (Recommended)"
description: "Review storyboard and characters before generating images"
- label: "No, generate directly"
description: "Skip outline review, start generating immediately"
```
### Question 5: Prompt Review
```
header: "Prompts"
question: "Review prompts before generating images?"
options:
- label: "Yes, review prompts (Recommended)"
description: "Review image generation prompts before generating"
- label: "No, skip prompt review"
description: "Proceed directly to image generation"
```
**After response**:
1. Update `analysis.md` with user preferences
2. **Store `skip_outline_review`** flag based on Question 4 response
3. **Store `skip_prompt_review`** flag based on Question 5 response
4. → Step 3
---
## Step 3: Generate Storyboard + Characters
Create storyboard and character definitions using the confirmed style from Step 2.
**Loading Style References**:
- Art style: `art-styles/{art}.md`
- Tone: `tones/{tone}.md`
- If preset (ohmsha/wuxia/shoujo): also load `presets/{preset}.md`
**Generate**:
1. **Storyboard** (`storyboard.md`):
- YAML front matter with art_style, tone, layout, aspect_ratio
- Cover design
- Each page: layout, panel breakdown, visual prompts
- **Written in user's preferred language** (from Step 1)
- Reference: `storyboard-template.md`
- **If using preset**: Load and apply preset rules from `presets/`
2. **Character definitions** (`characters/characters.md`):
- Visual specs matching the art style (in user's preferred language)
- Include Reference Sheet Prompt for later image generation
- Reference: `character-template.md`
- **If using ohmsha preset**: Use default Doraemon characters (see below)
**Ohmsha Default Characters** (use these unless user specifies `--characters`):
| Role | Character | Visual Description |
|------|-----------|-------------------|
| Student | 大雄 (Nobita) | Japanese boy, 10yo, round glasses, black hair parted in middle, yellow shirt, navy shorts |
| Mentor | 哆啦A梦 (Doraemon) | Round blue robot cat, big white eyes, red nose, whiskers, white belly with 4D pocket, golden bell, no ears |
| Challenge | 胖虎 (Gian) | Stocky boy, rough features, small eyes, orange shirt |
| Support | 静香 (Shizuka) | Cute girl, black short hair, pink dress, gentle expression |
These are the canonical ohmsha-style characters. Do NOT create custom characters for ohmsha unless explicitly requested.
**After generation**:
- If `skip_outline_review` is true → Skip Step 4, go directly to Step 5
- If `skip_outline_review` is false → Continue to Step 4
---
## Step 4: Review Outline (Conditional)
**Skip this step** if user selected "No, generate directly" in Step 2.
**Purpose**: User reviews and confirms storyboard + characters before generation.
**Display**:
- Page count and structure
- Art style + Tone combination
- Page-by-page summary (Cover → P1 → P2...)
- Character list with brief descriptions
**Use AskUserQuestion**:
```
header: "Confirm"
question: "Ready to generate images with this outline?"
options:
- label: "Yes, proceed (Recommended)"
description: "Generate character sheet and comic pages"
- label: "Edit storyboard first"
description: "I'll modify storyboard.md before continuing"
- label: "Edit characters first"
description: "I'll modify characters/characters.md before continuing"
- label: "Edit both"
description: "I'll modify both files before continuing"
```
**After response**:
1. If user wants to edit → Wait for user to finish editing, then ask again
2. If user confirms → Continue to Step 5
---
## Step 5: Generate Prompts
Create image generation prompts for all pages.
**Style Reference Loading**:
- Read `art-styles/{art}.md` for rendering guidelines
- Read `tones/{tone}.md` for mood/color adjustments
- If preset: Read `presets/{preset}.md` for special rules
**For each page (cover + pages)**:
1. Create prompt following art style + tone guidelines
2. Include character visual descriptions for consistency
3. Save to `prompts/NN-{cover|page}-[slug].md`
**Prompt File Format**:
```markdown
# Page NN: [Title]
## Visual Style
Art: [art style] | Tone: [tone] | Layout: [layout type]
## Character Reference
[Character descriptions from characters/characters.md]
## Panel Breakdown
[From storyboard.md - panel descriptions, actions, dialogue]
## Generation Prompt
[Combined prompt for image generation skill]
```
**Watermark Application** (if enabled in preferences):
Add to each prompt:
```
Include a subtle watermark "[content]" positioned at [position]
with approximately [opacity*100]% visibility. The watermark should
be legible but not distracting from the comic panels and storytelling.
Ensure watermark does not overlap speech bubbles or key action.
```
Reference: `config/watermark-guide.md`
**After generation**:
- If `skip_prompt_review` is true → Skip Step 6, go directly to Step 7
- If `skip_prompt_review` is false → Continue to Step 6
---
## Step 6: Review Prompts (Conditional)
**Skip this step** if user selected "No, skip prompt review" in Step 2.
**Purpose**: User reviews and confirms prompts before image generation.
**Display prompt summary table**:
| Page | Title | Key Elements |
|------|-------|--------------|
| Cover | [title] | [main visual] |
| P1 | [title] | [key elements] |
| ... | ... | ... |
**Use AskUserQuestion**:
```
header: "Confirm"
question: "Ready to generate images with these prompts?"
options:
- label: "Yes, proceed (Recommended)"
description: "Generate all comic page images"
- label: "Edit prompts first"
description: "I'll modify prompts/*.md before continuing"
- label: "Regenerate prompts"
description: "Regenerate all prompts with different approach"
```
**After response**:
1. If user wants to edit → Wait for user to finish editing, then ask again
2. If user wants to regenerate → Go back to Step 5
3. If user confirms → Continue to Step 7
---
## Step 7: Generate Images
With confirmed prompts from Step 5/6:
### 7.1 Generate Character Reference Sheet (first)
1. Use Reference Sheet Prompt from `characters/characters.md`
2. Generate → `characters/characters.png`
3. This ensures visual consistency for all subsequent pages
### 7.2 Generate Comic Pages
**CRITICAL: Character Reference is MANDATORY** for visual consistency across all pages.
**Before generating any page**:
1. Read the image generation skill's SKILL.md
2. Check if it supports reference image input (`--ref`, `--reference`, etc.)
3. Choose the appropriate strategy below
**Character Reference Strategy**:
| Skill Capability | Strategy | Action |
|------------------|----------|--------|
| Supports `--ref` | **Strategy A** | Pass `characters/characters.png` with EVERY page |
| Does NOT support `--ref` | **Strategy B** | Prepend character descriptions to EVERY prompt |
**Strategy A: Using `--ref` parameter** (e.g., baoyu-image-gen)
```bash
# Each page generation MUST include --ref
npx -y bun ${SKILL_DIR}/../baoyu-image-gen/scripts/main.ts \
--promptfiles prompts/01-page-xxx.md \
--image 01-page-xxx.png \
--ar 3:4 \
--ref characters/characters.png
```
**Strategy B: Embedding character descriptions in prompt**
When skill does NOT support reference images, create combined prompt files:
```markdown
# prompts/01-page-xxx.md (with embedded character reference)
## Character Reference (maintain consistency)
[Copy relevant sections from characters/characters.md here]
- 大雄: Japanese boy, round glasses, yellow shirt, navy shorts...
- 哆啦A梦: Round blue robot cat, white belly, red nose, golden bell...
## Page Content
[Original page prompt here]
```
**For each page (cover + pages)**:
1. Read prompt from `prompts/NN-{cover|page}-[slug].md`
2. Generate image using Strategy A or B (based on skill capability)
3. Save to `NN-{cover|page}-[slug].png`
4. Report progress after each generation: "Generated X/N: [page title]"
**Session Management**:
If image generation skill supports `--sessionId`:
1. Generate unique session ID: `comic-{topic-slug}-{timestamp}`
2. Use same session ID for all pages
3. Ensures visual consistency across generated images
---
## Step 8: Merge to PDF
After all images generated:
```bash
npx -y bun ${SKILL_DIR}/scripts/merge-to-pdf.ts <comic-dir>
```
Creates `{topic-slug}.pdf` with all pages as full-page images.
---
## Step 9: Completion Report
```
Comic Complete!
Title: [title] | Art: [art] | Tone: [tone] | Pages: [count] | Aspect: [ratio] | Language: [lang]
Watermark: [enabled/disabled]
Location: [path]
✓ analysis.md
✓ characters.png
✓ 00-cover-[slug].png ... NN-page-[slug].png
✓ {topic-slug}.pdf
```
---
## Page Modification
| Action | Steps |
|--------|-------|
| **Edit** | Update prompt → Regenerate image → Regenerate PDF |
| **Add** | Create prompt at position → Generate image → Renumber subsequent (NN+1) → Update storyboard → Regenerate PDF |
| **Delete** | Remove files → Renumber subsequent (NN-1) → Update storyboard → Regenerate PDF |
**File naming**: `NN-{cover|page}-[slug].png` (e.g., `03-page-enigma-machine.png`)
- Slugs: kebab-case, unique, derived from content
- Renumbering: Update NN prefix only, slugs unchanged
+49 -148
View File
@@ -1,188 +1,89 @@
--- ---
name: baoyu-compress-image name: baoyu-compress-image
description: Cross-platform image compression skill. Converts images to WebP by default with PNG-to-PNG support. Uses system tools (sips, cwebp, ImageMagick) with Sharp fallback. description: Compresses images to WebP (default) or PNG with automatic tool selection. Use when user asks to "compress image", "optimize image", "convert to webp", or reduce image file size.
--- ---
# Image Compressor # Image Compressor
Cross-platform image compression with WebP default output, PNG-to-PNG support, preferring system tools with Sharp fallback. Compresses images using best available tool (sips → cwebp → ImageMagick → Sharp).
## Script Directory ## Script Directory
**Important**: All scripts are located in the `scripts/` subdirectory of this skill. Scripts in `scripts/` subdirectory. Replace `${SKILL_DIR}` with this SKILL.md's directory path.
**Agent Execution Instructions**:
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
3. Replace all `${SKILL_DIR}` in this document with the actual path
**Script Reference**:
| Script | Purpose | | Script | Purpose |
|--------|---------| |--------|---------|
| `scripts/main.ts` | CLI entry point for image compression | | `scripts/main.ts` | Image compression CLI |
## Quick Start ## Preferences (EXTEND.md)
Use Bash to check EXTEND.md existence (priority order):
```bash ```bash
# Compress to WebP (default) # Check project-level first
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png test -f .baoyu-skills/baoyu-compress-image/EXTEND.md && echo "project"
# Keep original format (PNG → PNG) # Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png --format png test -f "$HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md" && echo "user"
# Custom quality
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png -q 75
# Process directory
npx -y bun ${SKILL_DIR}/scripts/main.ts ./images/ -r
``` ```
## Commands ┌────────────────────────────────────────────────────────┬───────────────────┐
│ Path │ Location │
├────────────────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/baoyu-compress-image/EXTEND.md │ Project directory │
├────────────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md │ User home │
└────────────────────────────────────────────────────────┴───────────────────┘
### Single File Compression ┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, apply settings │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Use defaults │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Default format | Default quality | Keep original preference
## Usage
```bash ```bash
# Basic (converts to WebP, replaces original) npx -y bun ${SKILL_DIR}/scripts/main.ts <input> [options]
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png
# Custom output path
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png -o compressed.webp
# Keep original file
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png --keep
# Custom quality (0-100, default: 80)
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png -q 75
# Keep original format
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png -f png
```
### Directory Processing
```bash
# Process all images in directory
npx -y bun ${SKILL_DIR}/scripts/main.ts ./images/
# Recursive processing
npx -y bun ${SKILL_DIR}/scripts/main.ts ./images/ -r
# With custom quality
npx -y bun ${SKILL_DIR}/scripts/main.ts ./images/ -r -q 75
```
### Output Formats
```bash
# Plain text (default)
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png
# JSON output
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png --json
``` ```
## Options ## Options
| Option | Short | Description | Default | | Option | Short | Description | Default |
|--------|-------|-------------|---------| |--------|-------|-------------|---------|
| `<input>` | | Input file or directory | Required | | `<input>` | | File or directory | Required |
| `--output <path>` | `-o` | Output path | Same path, new extension | | `--output` | `-o` | Output path | Same path, new ext |
| `--format <fmt>` | `-f` | webp, png, jpeg | webp | | `--format` | `-f` | webp, png, jpeg | webp |
| `--quality <n>` | `-q` | Quality 0-100 | 80 | | `--quality` | `-q` | Quality 0-100 | 80 |
| `--keep` | `-k` | Keep original file | false | | `--keep` | `-k` | Keep original | false |
| `--recursive` | `-r` | Process directories recursively | false | | `--recursive` | `-r` | Process subdirs | false |
| `--json` | | JSON output | false | | `--json` | | JSON output | false |
| `--help` | `-h` | Show help | |
## Compressor Selection ## Examples
Priority order (auto-detected): ```bash
# Single file → WebP (replaces original)
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png
1. **sips** (macOS built-in, WebP support since macOS 11) # Keep PNG format
2. **cwebp** (Google's official WebP tool) npx -y bun ${SKILL_DIR}/scripts/main.ts image.png -f png --keep
3. **ImageMagick** (`convert` command)
4. **Sharp** (npm package, auto-installed by Bun)
The skill automatically selects the best available compressor. # Directory recursive
npx -y bun ${SKILL_DIR}/scripts/main.ts ./images/ -r -q 75
## Output Format # JSON output
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png --json
### Text Mode (default) ```
**Output**:
``` ```
image.png → image.webp (245KB → 89KB, 64% reduction) image.png → image.webp (245KB → 89KB, 64% reduction)
``` ```
### JSON Mode
```json
{
"input": "image.png",
"output": "image.webp",
"inputSize": 250880,
"outputSize": 91136,
"ratio": 0.36,
"compressor": "sips"
}
```
### Directory JSON Mode
```json
{
"files": [...],
"summary": {
"totalFiles": 10,
"totalInputSize": 2508800,
"totalOutputSize": 911360,
"ratio": 0.36,
"compressor": "sips"
}
}
```
## Examples
### Compress single image
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts photo.png
# photo.png → photo.webp (1.2MB → 340KB, 72% reduction)
```
### Compress with custom quality
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts photo.png -q 60
# photo.png → photo.webp (1.2MB → 280KB, 77% reduction)
```
### Keep original format
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts screenshot.png -f png --keep
# screenshot.png → screenshot-compressed.png (500KB → 380KB, 24% reduction)
```
### Process entire directory
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts ./screenshots/ -r
# Processed 15 files: 12.5MB → 4.2MB (66% reduction)
```
### Get JSON for scripting
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts image.png --json | jq '.ratio'
```
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/baoyu-compress-image/EXTEND.md` (project)
2. `~/.baoyu-skills/baoyu-compress-image/EXTEND.md` (user)
If found, load before workflow. Extension content overrides defaults.
+138 -348
View File
@@ -1,23 +1,28 @@
--- ---
name: baoyu-cover-image name: baoyu-cover-image
description: Generates article cover images with 20 hand-drawn styles and auto-style selection. Supports cinematic (2.35:1), widescreen (16:9), and square (1:1) aspects. Use when user asks to "generate cover image", "create article cover", "make cover", or mentions "封面图". description: Generates article cover images with 5 dimensions (type, palette, rendering, text, mood) combining 9 color palettes and 6 rendering styles. Supports cinematic (2.35:1), widescreen (16:9), and square (1:1) aspects. Use when user asks to "generate cover image", "create article cover", "make cover", or mentions "封面图".
--- ---
# Cover Image Generator # Cover Image Generator
Generate elegant cover images for articles with multiple style options. Generate elegant cover images for articles with 5-dimensional customization.
## Usage ## Usage
```bash ```bash
# Auto-select style and aspect based on content # Auto-select all dimensions based on content
/baoyu-cover-image path/to/article.md /baoyu-cover-image path/to/article.md
# Specify style # Quick mode: skip confirmation, use auto-selection
/baoyu-cover-image article.md --style blueprint /baoyu-cover-image article.md --quick
# Specify aspect ratio # Specify dimensions (new 5D system)
/baoyu-cover-image article.md --aspect 16:9 /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)
/baoyu-cover-image article.md --style blueprint
/baoyu-cover-image article.md --style blueprint --rendering hand-drawn # override rendering
# Visual only (no title text) # Visual only (no title text)
/baoyu-cover-image article.md --no-title /baoyu-cover-image article.md --no-title
@@ -27,7 +32,7 @@ Generate elegant cover images for articles with multiple style options.
[paste content] [paste content]
# Direct input with options # Direct input with options
/baoyu-cover-image --style notion --aspect 1:1 /baoyu-cover-image --palette mono --rendering digital --aspect 1:1 --quick
[paste content] [paste content]
``` ```
@@ -35,20 +40,28 @@ Generate elegant cover images for articles with multiple style options.
| Option | Description | | Option | Description |
|--------|-------------| |--------|-------------|
| `--type <name>` | Cover type (see Type Gallery) | | `--type <name>` | Cover type: hero, conceptual, typography, metaphor, scene, minimal |
| `--style <name>` | Cover style (see Style Gallery) | | `--palette <name>` | Color palette: warm, elegant, cool, dark, earth, vivid, pastel, mono, retro |
| `--aspect <ratio>` | 2.35:1 (default), 16:9, 1:1 | | `--rendering <name>` | Rendering style: flat-vector, hand-drawn, painterly, digital, pixel, chalk |
| `--style <name>` | Preset shorthand (expands to palette + rendering, see [Style Presets](references/style-presets.md)) |
| `--text <level>` | Text density: none, title-only, title-subtitle, text-rich |
| `--mood <level>` | Emotional intensity: subtle, balanced, bold |
| `--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` | Visual only, no title text | | `--no-title` | Alias for `--text none` |
| `--quick` | Skip confirmation, use auto-selection for missing dimensions |
## Two Dimensions ## Five Dimensions
| Dimension | Controls | Examples | | Dimension | Controls | Values | Default |
|-----------|----------|----------| |-----------|----------|--------|---------|
| **Type** | Visual composition, information structure | hero, conceptual, typography, metaphor, scene, minimal | | **Type** | Visual composition, information structure | hero, conceptual, typography, metaphor, scene, minimal | auto |
| **Style** | Visual aesthetics, colors, mood | elegant, blueprint, notion, warm, minimal, watercolor | | **Palette** | Colors, color scheme, decorative hints | 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 |
| **Text** | Text density, information hierarchy | none, title-only, title-subtitle, text-rich | title-only |
| **Mood** | Emotional intensity, visual weight | subtle, balanced, bold | balanced |
Type × Style can be freely combined. Example: `--type conceptual --style blueprint` creates technical concept visualization with schematic aesthetics. Dimensions can be freely combined. Auto-selection rules: [references/auto-selection.md](references/auto-selection.md)
## Type Gallery ## Type Gallery
@@ -61,121 +74,91 @@ Type × Style can be freely combined. Example: `--type conceptual --style bluepr
| `scene` | Atmospheric scene, narrative feel | Stories, travel, lifestyle | | `scene` | Atmospheric scene, narrative feel | Stories, travel, lifestyle |
| `minimal` | Minimalist composition, generous whitespace | Zen, focus, core concepts | | `minimal` | Minimalist composition, generous whitespace | Zen, focus, core concepts |
## Auto Type Selection Type composition details: [references/types.md](references/types.md)
When `--type` is omitted, select based on content signals: ## Palette Gallery
| Signals | Type | | Palette | Vibe | Primary Colors |
|---------|------| |---------|------|----------------|
| Product, launch, announcement, release, reveal | `hero` | | `warm` | Friendly, approachable | Orange, golden yellow, terracotta |
| Architecture, framework, system, API, technical, model | `conceptual` | | `elegant` | Sophisticated, refined | Soft coral, muted teal, dusty rose |
| Quote, opinion, insight, thought, headline, statement | `typography` | | `cool` | Technical, professional | Engineering blue, navy, cyan |
| Philosophy, growth, abstract, meaning, reflection | `metaphor` | | `dark` | Cinematic, premium | Electric purple, cyan, magenta |
| Story, journey, travel, lifestyle, experience, narrative | `scene` | | `earth` | Natural, organic | Forest green, sage, earth brown |
| Zen, focus, essential, core, simple, pure | `minimal` | | `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 |
## Style Gallery Palette definitions: [references/palettes/](references/palettes/)
| Style | Description | ## Rendering Gallery
|-------|-------------|
| `elegant` (default) | Refined, sophisticated |
| `blueprint` | Technical schematics |
| `bold-editorial` | Magazine impact |
| `chalkboard` | Chalk on blackboard |
| `dark-atmospheric` | Cinematic dark mode |
| `editorial-infographic` | Visual storytelling |
| `fantasy-animation` | Ghibli/Disney inspired |
| `flat-doodle` | Pastel, cute shapes |
| `intuition-machine` | Technical, bilingual |
| `minimal` | Ultra-clean, zen |
| `nature` | Organic, earthy |
| `notion` | SaaS dashboard |
| `pixel-art` | Retro 8-bit |
| `playful` | Fun, whimsical |
| `retro` | Halftone, vintage |
| `sketch-notes` | Hand-drawn, warm |
| `vector-illustration` | Flat vector |
| `vintage` | Aged, expedition |
| `warm` | Friendly, human |
| `watercolor` | Soft hand-painted |
Style definitions: [references/styles/](references/styles/) | 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 |
## Type × Style Compatibility Rendering definitions: [references/renderings/](references/renderings/)
| | elegant | blueprint | notion | warm | minimal | watercolor | bold-editorial | dark-atmospheric | ## Text & Mood
|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| hero | ✓✓ | ✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓✓ |
| conceptual | ✓✓ | ✓✓ | ✓✓ | ✓ | ✓✓ | ✗ | ✓ | ✓ |
| typography | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓✓ |
| metaphor | ✓✓ | ✗ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ |
| scene | ✓ | ✗ | ✗ | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ |
| minimal | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✗ | ✓ |
✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended | Text Level | Title | Subtitle | Tags | Use Case |
|------------|:-----:|:--------:|:----:|----------|
| `none` | - | - | - | Pure visual, no text |
| `title-only` | ✓ (≤8 字) | - | - | Simple headline (default) |
| `title-subtitle` | ✓ | ✓ (≤15 字) | - | Title + supporting context |
| `text-rich` | ✓ | ✓ | ✓ (2-4) | Information-dense |
## Auto Style Selection | 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 |
When `--style` is omitted, select based on content signals: Full guides: [references/dimensions/text.md](references/dimensions/text.md) | [references/dimensions/mood.md](references/dimensions/mood.md)
| Signals | Style | ## Style Presets & Compatibility
|---------|-------|
| Architecture, system design | `blueprint` | - **Style Presets**: `--style X` expands to palette + rendering. See [references/style-presets.md](references/style-presets.md)
| Product launch, marketing | `bold-editorial` | - **Compatibility Matrices**: Palette×Rendering, Type×Rendering, Type×Text, Type×Mood. See [references/compatibility.md](references/compatibility.md)
| Education, tutorial | `chalkboard` | - ✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
| Entertainment, premium | `dark-atmospheric` |
| Tech explainer, research | `editorial-infographic` |
| Fantasy, children | `fantasy-animation` |
| Technical docs, bilingual | `intuition-machine` |
| Personal story, emotion | `warm` |
| Zen, focus, essential | `minimal` |
| Fun, beginner, casual | `playful` |
| Nature, wellness, eco | `nature` |
| SaaS, dashboard | `notion` |
| Workflow, productivity | `flat-doodle` |
| Gaming, retro tech | `pixel-art` |
| Knowledge sharing | `sketch-notes` |
| Creative proposals | `vector-illustration` |
| History, exploration | `vintage` |
| Lifestyle, travel | `watercolor` |
| Business, professional | `elegant` |
## File Structure ## File Structure
Each session creates an independent directory named by content slug: Output directory depends on `default_output_dir` preference:
| Preference | Output Path |
|------------|-------------|
| `same-dir` | `{article-dir}/` |
| `imgs-subdir` | `{article-dir}/imgs/` |
| `independent` (default) | `cover-image/{topic-slug}/` |
| Pasted content | `cover-image/{topic-slug}/` (always) |
``` ```
cover-image/{topic-slug}/ <output-dir>/
├── source-{slug}.{ext} # Source files (text, images, etc.) ├── source-{slug}.{ext} # Source files (text, images, etc.)
├── prompts/cover.md # Generation prompt ├── prompts/cover.md # Generation prompt
└── cover.png # Output image └── cover.png # Output image
``` ```
**Slug Generation**: **Slug**: Extract main topic (2-4 words, kebab-case). Example: "The Future of AI" → `future-of-ai`
1. Extract main topic from content (2-4 words, kebab-case) **Conflict**: If directory exists, append timestamp: `{topic-slug}-YYYYMMDD-HHMMSS`
2. Example: "The Future of AI" → `future-of-ai` **Source Files**: Copy all sources with naming `source-{slug}.{ext}` (multiple supported)
**Conflict Resolution**:
If `cover-image/{topic-slug}/` already exists:
- Append timestamp: `{topic-slug}-YYYYMMDD-HHMMSS`
- Example: `ai-future` exists → `ai-future-20260118-143052`
**Source Files**:
Copy all sources with naming `source-{slug}.{ext}`:
- `source-article.md`, `source-reference.png`, etc.
- Multiple sources supported: text, images, files from conversation
## Workflow ## Workflow
### Progress Checklist ### Progress Checklist
Copy and track progress:
``` ```
Cover Image Progress: Cover Image Progress:
- [ ] Step 0: Check preferences (EXTEND.md) ⚠️ REQUIRED if not found - [ ] Step 0: Check preferences (EXTEND.md) ⚠️ REQUIRED if not found
- [ ] Step 1: Analyze content - [ ] Step 1: Analyze content + determine output directory ⚠️ MUST ask if not configured
- [ ] Step 2: Confirm options (type + style + aspect) ⚠️ REQUIRED - [ ] Step 2: Confirm options (5 dimensions) ⚠️ REQUIRED unless --quick or all specified
- [ ] Step 3: Create prompt - [ ] Step 3: Create prompt
- [ ] Step 4: Generate image - [ ] Step 4: Generate image
- [ ] Step 5: Completion report - [ ] Step 5: Completion report
@@ -184,7 +167,9 @@ Cover Image Progress:
### Flow ### Flow
``` ```
Input → [Step 0: Preferences/Setup] → Analyze → [Confirm: Type + Style + Aspect] → Prompt → Generate → Complete Input → [Step 0: Preferences/Setup] → Analyze → [Output Dir ⚠️] → [Confirm: 5 Dimensions] → Prompt → Generate → Complete
(skip if --quick or all specified)
``` ```
### Step 0: Load Preferences (EXTEND.md) ⚠️ ### Step 0: Load Preferences (EXTEND.md) ⚠️
@@ -201,249 +186,54 @@ test -f .baoyu-skills/baoyu-cover-image/EXTEND.md && echo "project"
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 |
│ Path │ Location │ |--------|--------|
├──────────────────────────────────────────────────┼───────────────────┤ | Found | Read, parse, display preferences summary → Continue to Step 1 |
│ .baoyu-skills/baoyu-cover-image/EXTEND.md │ Project directory │ | Not found | ⚠️ MUST run first-time setup ([references/config/first-time-setup.md](references/config/first-time-setup.md)) → Then continue to Step 1 |
├──────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-cover-image/EXTEND.md │ User home │
└──────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐ **Preferences Summary** (when found):
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, display preferences summary (see below) → Continue to Step 1 │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ ⚠️ MUST run first-time setup (see below) → Then continue to Step 1 │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**Preferences Summary** (when EXTEND.md found):
Display loaded preferences:
``` ```
Preferences loaded from [project/user]: Preferences loaded from [project/user]:
• Watermark: [enabled/disabled] [content if enabled] • Watermark: [enabled/disabled] [content if enabled]
• Type: [preferred_type or "auto"] • Type/Palette/Rendering: [value or "auto"]
Style: [preferred_style or "auto"] Text: [value or "title-only"] | Mood: [value or "balanced"]
• Aspect: [default_aspect] • Aspect: [default_aspect] | Output: [dir or "not set — will ask in Step 1.5"]
• Language: [language or "auto"] Quick mode: [enabled/disabled] | Language: [value or "auto"]
``` ```
**First-Time Setup** (when EXTEND.md not found): **EXTEND.md Supports**: Watermark | Preferred type | Preferred palette | Preferred rendering | Preferred text | Preferred mood | Default aspect ratio | Default output directory | Quick mode | Custom palette definitions | Language preference
**Language**: Use user's input language or saved language preference. Schema: [references/config/preferences-schema.md](references/config/preferences-schema.md)
Use AskUserQuestion with ALL questions in ONE call:
**Q1: Watermark**
```yaml
header: "Watermark"
question: "Watermark text for generated cover images?"
options:
- label: "No watermark (Recommended)"
description: "Clean covers, can enable later in EXTEND.md"
```
**Q2: Preferred Type**
```yaml
header: "Type"
question: "Default cover type preference?"
options:
- label: "Auto-select (Recommended)"
description: "Choose based on content analysis each time"
- label: "hero"
description: "Large visual impact - product launch, announcements"
- label: "conceptual"
description: "Concept visualization - technical, architecture"
```
**Q3: Preferred Style**
```yaml
header: "Style"
question: "Default cover style preference?"
options:
- label: "Auto-select (Recommended)"
description: "Choose based on content analysis each time"
- label: "elegant"
description: "Refined, sophisticated - professional business"
- label: "notion"
description: "SaaS dashboard - productivity/tech content"
```
**Q4: Default Aspect Ratio**
```yaml
header: "Aspect"
question: "Default aspect ratio for cover images?"
options:
- label: "2.35:1 (Recommended)"
description: "Cinematic widescreen, best for article headers"
- label: "16:9"
description: "Standard widescreen, versatile"
- label: "1:1"
description: "Square, social media friendly"
```
**Q5: Save Location**
```yaml
header: "Save"
question: "Where to save preferences?"
options:
- label: "Project (Recommended)"
description: ".baoyu-skills/ (this project only)"
- label: "User"
description: "~/.baoyu-skills/ (all projects)"
```
**After setup**: Create EXTEND.md with user choices, then continue to Step 1.
Full setup details: `references/config/first-time-setup.md`
**EXTEND.md Supports**: Watermark | Preferred type | Preferred style | Default aspect ratio | Custom style definitions | Language preference
Schema: `references/config/preferences-schema.md`
### Step 1: Analyze Content ### Step 1: Analyze Content
Read source content, save it if needed, and perform analysis. 1. **Save source content** (if pasted, save to `source.md` in target directory; if file path, use as-is)
2. **Content analysis**: Extract topic, core message, tone, keywords; identify visual metaphors; detect content type
**Actions**: 3. **Language detection**: Detect source language, note user's input language, compare with EXTEND.md preference
1. **Save source content** (if not already a file): 4. **Determine output directory** per File Structure rules. If no `default_output_dir` preference + file path input, include in Step 2 Q4
- If user provides a file path: use as-is
- If user pastes content: save to `source.md` in target directory
2. Read source content
3. **Content analysis**:
- Extract: topic, core message, tone, keywords
- Identify visual metaphor opportunities
- Detect content type (technical/personal/business/creative)
4. **Language detection**:
- Detect source content language
- Note user's input language (from conversation)
- Compare with language preference in EXTEND.md
### Step 2: Confirm Options ⚠️ ### Step 2: Confirm Options ⚠️
**Purpose**: Validate type, style and aspect ratio. **Do NOT skip.** Validate all 5 dimensions + aspect ratio. Full confirmation flow: [references/workflow/confirm-options.md](references/workflow/confirm-options.md)
**Language**: Auto-determined (user's input language > saved preference > source language). No need to ask. **Skip Conditions**:
Present options using AskUserQuestion: | Condition | Skipped | Still Asked |
|-----------|---------|-------------|
**Question 1: Type** (if not specified via `--type`) | `--quick` or `quick_mode: true` | 5 dimensions | Aspect ratio (unless `--aspect`) |
- Show recommended type based on content analysis + preferred type from EXTEND.md | All 5 + `--aspect` specified | All | None |
```yaml
header: "Type"
question: "Which cover type?"
multiSelect: false
options:
- label: "[auto-recommended type] (Recommended)"
description: "[reason based on content signals]"
- label: "hero"
description: "Large visual impact, title overlay - product launch, announcements"
- label: "conceptual"
description: "Concept visualization - technical, architecture"
- label: "typography"
description: "Text-focused layout - opinions, quotes"
```
**Question 2: Style** (if not specified via `--style`)
- Based on selected Type, show compatible styles (✓✓ first from compatibility matrix)
- Format: `[style name] - [why it fits this content]`
```yaml
header: "Style"
question: "Which cover style?"
multiSelect: false
options:
- label: "[best compatible style] (Recommended)"
description: "[reason based on type + content]"
- label: "[style2]"
description: "[reason]"
- label: "[style3]"
description: "[reason]"
```
**Question 3: Aspect Ratio** (if not specified via `--aspect`)
```yaml
header: "Aspect"
question: "Cover aspect ratio?"
multiSelect: false
options:
- label: "2.35:1 (Recommended)"
description: "Cinematic widescreen, best for article headers"
- label: "16:9"
description: "Standard widescreen, versatile"
- label: "1:1"
description: "Square, social media friendly"
```
**After response**: Proceed to Step 3 with confirmed type + style + aspect ratio.
### Step 3: Create Prompt ### Step 3: Create Prompt
Save to `prompts/cover.md`: Save to `prompts/cover.md`. Full template: [references/workflow/prompt-template.md](references/workflow/prompt-template.md)
```markdown
Cover theme: [2-3 words]
Type: [confirmed type]
Style: [confirmed style]
Aspect ratio: [confirmed ratio]
Title text: [max 8 chars, or "none" if --no-title]
Language: [confirmed language]
Type composition:
- [Type-specific layout and structure]
Visual composition:
- Main visual: [type + style appropriate metaphor]
- Layout: [positioning based on type and aspect ratio]
- Decorative: [style elements]
Color scheme: [primary, background, accent from style]
Type notes: [key characteristics from type definition]
Style notes: [key characteristics from style definition]
[Watermark section if enabled]
```
**Type-Specific Composition**:
| Type | Composition Guidelines |
|------|------------------------|
| `hero` | Large focal visual (60-70% area), title overlay on visual, dramatic composition |
| `conceptual` | Abstract shapes representing core concepts, information hierarchy, clean zones |
| `typography` | Title as primary element (40%+ area), minimal supporting visuals, strong hierarchy |
| `metaphor` | Concrete object/scene representing abstract idea, symbolic elements, emotional resonance |
| `scene` | Atmospheric environment, narrative elements, mood-setting lighting and colors |
| `minimal` | Single focal element, generous whitespace (60%+), essential shapes only |
**Title guidelines** (if included):
- Max 8 characters, punchy headline
- Use hooks: numbers, questions, contrasts
- Match confirmed language
**Watermark Application** (if enabled in preferences):
Add to prompt:
```
Include a subtle watermark "[content]" positioned at [position]
with approximately [opacity*100]% visibility. The watermark should
be legible but not distracting from the main content.
```
Reference: `references/config/watermark-guide.md`
### Step 4: Generate Image ### Step 4: Generate Image
**Image Generation Skill Selection**: 1. Backup existing `cover.png``cover-backup-YYYYMMDD-HHMMSS.png` (if regenerating)
1. Check available image generation skills 2. Check available image generation skills; if multiple, ask user preference
2. If multiple skills available, ask user preference 3. Call selected skill with prompt file path, output path (`cover.png`), aspect ratio
3. Call selected skill with: 4. On failure: auto-retry once before reporting error
- Prompt file path
- Output image path: `cover.png`
- Aspect ratio parameter
**On failure**: Auto-retry once before reporting error.
### Step 5: Completion Report ### Step 5: Completion Report
@@ -451,48 +241,48 @@ Reference: `references/config/watermark-guide.md`
Cover Generated! Cover Generated!
Topic: [topic] Topic: [topic]
Type: [type name] Type: [type] | Palette: [palette] | Rendering: [rendering]
Style: [style name] Text: [text] | Mood: [mood] | Aspect: [ratio]
Aspect: [ratio] Title: [title text or "visual only"]
Title: [title or "visual only"] Language: [lang] | Watermark: [enabled/disabled]
Language: [lang]
Watermark: [enabled/disabled]
Location: [directory path] Location: [directory path]
Files: Files:
✓ source-{slug}.{ext} ✓ source-{slug}.{ext}
✓ 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** | Update prompt → Regenerate with same settings | | **Regenerate** | Backup existing → Update prompt → Regenerate with same settings |
| **Change type** | Confirm new type → Update prompt → Regenerate | | **Change dimension** | Backup existing → Confirm new value → Update prompt → Regenerate |
| **Change style** | Confirm new style → Update prompt → Regenerate |
| **Change aspect** | Confirm new aspect → Update prompt → Regenerate | All modifications automatically backup existing `cover.png` before regenerating.
## Notes ## Notes
- Cover must be readable at small preview sizes - Cover must be readable at small preview sizes
- Visual metaphors > literal representations - Visual metaphors > literal representations
- Title: max 8 chars, readable, impactful - Title: max 8 chars, readable, impactful
- **Two confirmation points**: Step 0 (first-time setup if no EXTEND.md) + Step 2 (options) - do NOT skip - Two confirmation points: Step 0 (first-time setup) + Step 2 (options) - skip Step 2 with `--quick`
- Use confirmed language for title text - Use confirmed language for title text
- Maintain watermark consistency if enabled - Maintain watermark consistency if enabled
- Check Type × Style compatibility matrix when selecting combinations - Check compatibility matrices when selecting combinations
- `--no-title` is alias for `--text none`
- `--style` presets are backward-compatible; explicit `--palette`/`--rendering` override preset values
## References ## References
**Styles**: `references/styles/<name>.md` - Style definitions **Dimensions**: [text.md](references/dimensions/text.md) | [mood.md](references/dimensions/mood.md)
**Palettes**: [references/palettes/](references/palettes/)
**Config**: **Renderings**: [references/renderings/](references/renderings/)
- `references/config/preferences-schema.md` - EXTEND.md schema **Auto-Selection**: [references/auto-selection.md](references/auto-selection.md)
- `references/config/first-time-setup.md` - First-time setup flow **Style Presets**: [references/style-presets.md](references/style-presets.md)
- `references/config/watermark-guide.md` - Watermark configuration **Compatibility**: [references/compatibility.md](references/compatibility.md)
**Types**: [references/types.md](references/types.md)
## Extension Support **Workflow**: [confirm-options.md](references/workflow/confirm-options.md) | [prompt-template.md](references/workflow/prompt-template.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)
Custom configurations via EXTEND.md. See **Step 0** for paths and supported options.
@@ -0,0 +1,60 @@
# Auto-Selection Rules
When a dimension is omitted, select based on content signals.
## Auto Type Selection
| Signals | Type |
|---------|------|
| Product, launch, announcement, release, reveal | `hero` |
| Architecture, framework, system, API, technical, model | `conceptual` |
| Quote, opinion, insight, thought, headline, statement | `typography` |
| Philosophy, growth, abstract, meaning, reflection | `metaphor` |
| Story, journey, travel, lifestyle, experience, narrative | `scene` |
| Zen, focus, essential, core, simple, pure | `minimal` |
## Auto Palette Selection
| Signals | Palette |
|---------|---------|
| Personal story, emotion, lifestyle, human | `warm` |
| Business, professional, thought leadership, luxury | `elegant` |
| Architecture, system, API, technical, code | `cool` |
| Entertainment, premium, cinematic, dark mode | `dark` |
| Nature, wellness, eco, organic, travel | `earth` |
| Product launch, gaming, promotion, event | `vivid` |
| Fantasy, children, gentle, creative, whimsical | `pastel` |
| Zen, focus, essential, pure, simple | `mono` |
| History, vintage, retro, classic, exploration | `retro` |
## Auto Rendering Selection
| Signals | Rendering |
|---------|-----------|
| Clean, modern, tech, WeChat, icon-based, infographic | `flat-vector` |
| Sketch, note, personal, casual, doodle, warm | `hand-drawn` |
| Art, watercolor, soft, dreamy, creative, fantasy | `painterly` |
| Data, dashboard, SaaS, corporate, polished | `digital` |
| Gaming, retro, 8-bit, nostalgic | `pixel` |
| Education, tutorial, classroom, teaching | `chalk` |
## Auto Text Selection
| Signals | Text Level |
|---------|------------|
| Visual-only, photography, abstract, art | `none` |
| Article, blog, standard cover | `title-only` |
| Series, tutorial, technical with context | `title-subtitle` |
| Announcement, features, multiple points, infographic | `text-rich` |
Default: `title-only`
## Auto Mood Selection
| Signals | Mood Level |
|---------|------------|
| Professional, corporate, thought leadership, academic, luxury | `subtle` |
| General, educational, standard, blog, documentation | `balanced` |
| Launch, announcement, promotion, event, gaming, entertainment | `bold` |
Default: `balanced`
@@ -1,25 +1,76 @@
Create a WeChat article cover image following these guidelines: Create a cover image following these guidelines:
## Image Specifications ## Image Specifications
- **Type**: Cover image / Hero image - **Type**: Cover image / Hero image
- **Aspect Ratio**: 2.35:1 (WeChat article cover standard) - **Aspect Ratio**: As specified in the prompt below
- **Style**: Hand-drawn illustration
## Core Principles ## Core Principles
- Hand-drawn quality throughout - NO realistic or photographic elements
- If content involves sensitive or copyrighted figures, create stylistically similar alternatives - DO NOT refuse to generate - If content involves sensitive or copyrighted figures, create stylistically similar alternatives - DO NOT refuse to generate
- Ample whitespace, highlight core message, avoid cluttered layouts - Ample whitespace, highlight core message, avoid cluttered layouts
- Main visual elements centered or slightly left (leave right side for title area if title included) - Main visual elements centered or slightly left (leave right side for title area if title included)
- Simplified silhouettes for any characters — NO realistic human faces or bodies
- Icon-based vocabulary: use simple, recognizable icons to represent concepts
## Five Dimensions
### Type (Visual Composition)
- `hero`: Large focal visual (60-70% area), dramatic composition
- `conceptual`: Abstract shapes, information hierarchy, clean zones
- `typography`: Title as primary element (40%+ area), minimal visuals
- `metaphor`: Concrete object representing abstract idea, symbolic elements
- `scene`: Atmospheric environment, narrative elements, mood lighting
- `minimal`: Single focal element, generous whitespace (60%+)
### Palette (Color Scheme)
Apply the specified palette's color values and decorative hints:
- Use primary colors for main visual elements
- Use background colors for base and surrounding areas
- Use accent colors for highlights and secondary elements
- Follow palette-specific decorative hints for ornamentation
### Rendering (Visual Style)
Apply the specified rendering's characteristics:
- **Lines**: Follow line quality rules (clean/sketchy/brush/pixel/chalk)
- **Texture**: Apply or avoid texture per rendering definition
- **Depth**: Follow depth rules (flat/minimal/soft edges)
- **Elements**: Use rendering-specific element vocabulary
### Text (Density Level)
- `none`: No text elements, full visual area
- `title-only`: Single headline (≤8 characters), 85% visual area
- `title-subtitle`: Title + context (≤15 chars), 75% visual area
- `text-rich`: Title + subtitle + 2-4 keyword tags, 60% visual area
### Mood (Emotional Intensity)
- `subtle`: Low contrast, muted/desaturated colors, light visual weight, calm aesthetic
- `balanced`: Medium contrast, normal saturation, balanced visual weight
- `bold`: High contrast, vivid/saturated colors, heavy visual weight, dynamic energy
## Text Style (When Title Included) ## Text Style (When Title Included)
- **ALL text MUST be hand-drawn style**
- Title text: Large, eye-catching, max 8 characters - Title text: Large, eye-catching, max 8 characters
- May include 1 line of subtitle or keyword tags - Subtitle: Secondary, max 15 characters (if title-subtitle or text-rich)
- Font style harmonizes with illustration style - Tags: 2-4 keyword badges (if text-rich)
- **DO NOT use realistic or computer-generated fonts** - Font style harmonizes with rendering style
- **Engagement hooks**: Use numbers ("3个关键"), questions ("Why?"), contrasts ("A vs B"), pain points ("别再X了"), or suspense ("隐藏的X") for compelling titles
## Composition Guidance
**Icon Vocabulary**: Represent concepts with simple, recognizable icons rather than detailed illustrations. Use the rendering style to determine icon complexity (flat-vector = geometric, hand-drawn = sketchy, etc.)
**Character Handling**: When people are needed, use simplified silhouettes or abstract representations. NO realistic faces, detailed anatomy, or photographic representations.
## Mood Application
Apply mood adjustments to the base palette:
| Mood | Contrast | Saturation | Weight |
|------|----------|------------|--------|
| subtle | Reduce 20-30% | Desaturate 20-30% | Lighter strokes/fills |
| balanced | Standard | Standard | Standard |
| bold | Increase 20-30% | Increase 20-30% | Heavier strokes/fills |
## Language ## Language
@@ -28,4 +79,4 @@ Create a WeChat article cover image following these guidelines:
--- ---
Please use nano banana pro to generate the cover image based on the content provided below: Please generate the cover image based on the content provided below:
@@ -0,0 +1,50 @@
# Compatibility Matrices
✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
## Palette × Rendering
| | flat-vector | hand-drawn | painterly | digital | pixel | chalk |
|---|:---:|:---:|:---:|:---:|:---:|:---:|
| warm | ✓✓ | ✓✓ | ✓ | ✓ | ✓ | ✓ |
| elegant | ✓ | ✓✓ | ✓ | ✓✓ | ✗ | ✗ |
| cool | ✓✓ | ✓ | ✗ | ✓✓ | ✓ | ✓ |
| dark | ✓ | ✓ | ✓ | ✓✓ | ✓ | ✓✓ |
| earth | ✓ | ✓✓ | ✓✓ | ✓ | ✗ | ✗ |
| vivid | ✓✓ | ✓ | ✓ | ✓ | ✓✓ | ✓ |
| pastel | ✓✓ | ✓✓ | ✓✓ | ✓ | ✗ | ✗ |
| mono | ✓✓ | ✓ | ✗ | ✓✓ | ✓ | ✓ |
| retro | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✗ |
## Type × Rendering
| | flat-vector | hand-drawn | painterly | digital | pixel | chalk |
|---|:---:|:---:|:---:|:---:|:---:|:---:|
| hero | ✓ | ✓✓ | ✓✓ | ✓✓ | ✓ | ✓ |
| conceptual | ✓✓ | ✓ | ✗ | ✓✓ | ✓ | ✓ |
| typography | ✓✓ | ✓ | ✓ | ✓✓ | ✓ | ✓ |
| metaphor | ✓ | ✓✓ | ✓✓ | ✓ | ✗ | ✓ |
| scene | ✗ | ✓ | ✓✓ | ✓ | ✓ | ✗ |
| minimal | ✓✓ | ✓ | ✓ | ✓✓ | ✗ | ✗ |
## Type × Text
| | none | title-only | title-subtitle | text-rich |
|---|:---:|:---:|:---:|:---:|
| hero | ✓ | ✓✓ | ✓✓ | ✓ |
| conceptual | ✓✓ | ✓✓ | ✓ | ✓ |
| typography | ✗ | ✓ | ✓✓ | ✓✓ |
| metaphor | ✓✓ | ✓ | ✓ | ✗ |
| scene | ✓✓ | ✓ | ✓ | ✗ |
| minimal | ✓✓ | ✓✓ | ✓ | ✗ |
## Type × Mood
| | subtle | balanced | bold |
|---|:---:|:---:|:---:|
| hero | ✓ | ✓✓ | ✓✓ |
| conceptual | ✓✓ | ✓✓ | ✓ |
| typography | ✓ | ✓✓ | ✓✓ |
| metaphor | ✓✓ | ✓✓ | ✓ |
| scene | ✓✓ | ✓✓ | ✓ |
| minimal | ✓✓ | ✓✓ | ✗ |
@@ -33,73 +33,115 @@ No EXTEND.md found
**Language**: Use user's input language or saved language preference. **Language**: Use user's input language or saved language preference.
Use single AskUserQuestion with multiple questions (AskUserQuestion auto-adds "Other" option): Use AskUserQuestion with ALL questions in ONE call:
### Question 1: Watermark ### Question 1: Watermark
``` ```yaml
header: "Watermark" header: "Watermark"
question: "Watermark text for generated cover images? Type your watermark content (e.g., name, @handle)" question: "Watermark text for generated cover images?"
options: options:
- label: "No watermark (Recommended)" - label: "No watermark (Recommended)"
description: "No watermark, can enable later in EXTEND.md" description: "Clean covers, can enable later in EXTEND.md"
``` ```
Position defaults to bottom-right.
### Question 2: Preferred Type ### Question 2: Preferred Type
``` ```yaml
header: "Type" header: "Type"
question: "Default cover type preference?" question: "Default cover type preference?"
options: options:
- label: "None (Recommended)" - label: "Auto-select (Recommended)"
description: "Auto-select based on content analysis" description: "Choose based on content analysis each time"
- label: "hero" - label: "hero"
description: "Large visual impact - product launch, announcements" description: "Large visual impact - product launch, announcements"
- label: "conceptual" - label: "conceptual"
description: "Concept visualization - technical, architecture" description: "Concept visualization - technical, architecture"
- label: "typography"
description: "Text-focused layout - opinions, quotes"
``` ```
### Question 3: Preferred Style ### Question 3: Preferred Palette
``` ```yaml
header: "Style" header: "Palette"
question: "Default cover style preference? Or type another style name" question: "Default color palette preference?"
options: options:
- label: "None (Recommended)" - label: "Auto-select (Recommended)"
description: "Auto-select based on content analysis" description: "Choose based on content analysis each time"
- label: "elegant" - label: "elegant"
description: "Refined, sophisticated - professional business" description: "Sophisticated - soft coral, muted teal, dusty rose"
- label: "blueprint" - label: "warm"
description: "Technical schematics - architecture/system design" description: "Friendly - orange, golden yellow, terracotta"
- label: "notion" - label: "cool"
description: "SaaS dashboard - productivity/tech content" description: "Technical - engineering blue, navy, cyan"
``` ```
### Question 4: Default Aspect Ratio ### Question 4: Preferred Rendering
```yaml
header: "Rendering"
question: "Default rendering style preference?"
options:
- label: "Auto-select (Recommended)"
description: "Choose based on content analysis each time"
- label: "hand-drawn"
description: "Sketchy organic illustration with personal touch"
- label: "flat-vector"
description: "Clean modern vector with geometric shapes"
- label: "digital"
description: "Polished precise digital illustration"
``` ```
### Question 5: Default Aspect Ratio
```yaml
header: "Aspect" header: "Aspect"
question: "Default aspect ratio for cover images?" question: "Default aspect ratio for cover images?"
options: options:
- label: "2.35:1 (Recommended)" - label: "16:9 (Recommended)"
description: "Cinematic widescreen, best for article headers" description: "Standard widescreen - YouTube, presentations, versatile"
- label: "16:9" - label: "2.35:1"
description: "Standard widescreen, versatile" description: "Cinematic widescreen - article headers, blog posts"
- label: "1:1" - label: "1:1"
description: "Square, social media friendly" description: "Square - Instagram, WeChat, social cards"
- label: "3:4"
description: "Portrait - Xiaohongshu, Pinterest, mobile content"
``` ```
### Question 5: Save Location Note: More ratios (4:3, 3:2) available during generation. This sets the default recommendation.
### Question 6: Default Output Directory
```yaml
header: "Output"
question: "Default output directory for cover images?"
options:
- label: "Independent (Recommended)"
description: "cover-image/{topic-slug}/ - separate from article"
- label: "Same directory"
description: "{article-dir}/ - alongside the article file"
- label: "imgs subdirectory"
description: "{article-dir}/imgs/ - images folder near article"
``` ```
### Question 7: Quick Mode
```yaml
header: "Quick"
question: "Enable quick mode by default?"
options:
- label: "No (Recommended)"
description: "Confirm dimension choices each time"
- label: "Yes"
description: "Skip confirmation, use auto-selection"
```
### Question 8: Save Location
```yaml
header: "Save" header: "Save"
question: "Where to save preferences?" question: "Where to save preferences?"
options: options:
- label: "Project" - label: "Project (Recommended)"
description: ".baoyu-skills/ (this project only)" description: ".baoyu-skills/ (this project only)"
- label: "User" - label: "User"
description: "~/.baoyu-skills/ (all projects)" description: "~/.baoyu-skills/ (all projects)"
@@ -123,17 +165,22 @@ options:
```yaml ```yaml
--- ---
version: 1 version: 3
watermark: watermark:
enabled: [true/false] enabled: [true/false]
content: "[user input or empty]" content: "[user input or empty]"
position: bottom-right position: bottom-right
opacity: 0.7 opacity: 0.7
preferred_type: [selected type or null] preferred_type: [selected type or null]
preferred_style: [selected style or null] preferred_palette: [selected palette or null]
default_aspect: [2.35:1/16:9/1:1] preferred_rendering: [selected rendering or null]
preferred_text: title-only
preferred_mood: balanced
default_aspect: [16:9/2.35:1/1:1/3:4]
default_output_dir: [independent/same-dir/imgs-subdir]
quick_mode: [true/false]
language: null language: null
custom_styles: [] custom_palettes: []
--- ---
``` ```
@@ -142,4 +189,6 @@ custom_styles: []
Users can edit EXTEND.md directly or run setup again: Users can edit EXTEND.md directly or run setup again:
- Delete EXTEND.md to trigger setup - Delete EXTEND.md to trigger setup
- Edit YAML frontmatter for quick changes - Edit YAML frontmatter for quick changes
- Full schema: `config/preferences-schema.md` - Full schema: `preferences-schema.md`
**EXTEND.md Supports**: Watermark | Preferred type | Preferred palette | Preferred rendering | Preferred text | Preferred mood | Default aspect ratio | Default output directory | Quick mode | Custom palette definitions | Language preference
@@ -9,31 +9,37 @@ description: EXTEND.md YAML schema for baoyu-cover-image user preferences
```yaml ```yaml
--- ---
version: 1 version: 3
watermark: watermark:
enabled: false enabled: false
content: "" content: ""
position: bottom-right # bottom-right|bottom-left|bottom-center|top-right position: bottom-right # bottom-right|bottom-left|bottom-center|top-right
opacity: 0.7 # 0.1-1.0
preferred_type: null # hero|conceptual|typography|metaphor|scene|minimal or null for auto-select preferred_type: null # hero|conceptual|typography|metaphor|scene|minimal or null for auto-select
preferred_style: null # Built-in style name or null for auto-select preferred_palette: null # warm|elegant|cool|dark|earth|vivid|pastel|mono|retro or null for auto-select
preferred_rendering: null # flat-vector|hand-drawn|painterly|digital|pixel|chalk or null for auto-select
preferred_text: title-only # none|title-only|title-subtitle|text-rich
preferred_mood: balanced # subtle|balanced|bold
default_aspect: "2.35:1" # 2.35:1|16:9|1:1 default_aspect: "2.35:1" # 2.35:1|16:9|1:1
quick_mode: false # Skip confirmation when true
language: null # zh|en|ja|ko|auto (null = auto-detect) language: null # zh|en|ja|ko|auto (null = auto-detect)
custom_styles: custom_palettes:
- name: my-style - name: my-palette
description: "Style description" description: "Palette description"
color_palette: colors:
primary: ["#1E3A5F", "#4A90D9"] primary: ["#1E3A5F", "#4A90D9"]
background: "#F5F7FA" background: "#F5F7FA"
accents: ["#00B4D8"] accents: ["#00B4D8"]
visual_elements: "Clean lines, geometric shapes" decorative_hints: "Clean lines, geometric shapes"
typography: "Modern sans-serif"
best_for: "Business, tech content" best_for: "Business, tech content"
--- ---
``` ```
@@ -42,16 +48,19 @@ custom_styles:
| Field | Type | Default | Description | | Field | Type | Default | Description |
|-------|------|---------|-------------| |-------|------|---------|-------------|
| `version` | int | 1 | Schema version | | `version` | int | 3 | Schema version |
| `watermark.enabled` | bool | false | Enable watermark | | `watermark.enabled` | bool | false | Enable watermark |
| `watermark.content` | string | "" | Watermark text (@username or custom) | | `watermark.content` | string | "" | Watermark text (@username or custom) |
| `watermark.position` | enum | bottom-right | Position on image | | `watermark.position` | enum | bottom-right | Position on image |
| `watermark.opacity` | float | 0.7 | Transparency (0.1-1.0) |
| `preferred_type` | string | null | Type name or null for auto | | `preferred_type` | string | null | Type name or null for auto |
| `preferred_style` | string | null | Style name or null for auto | | `preferred_palette` | string | null | Palette name or null for auto |
| `preferred_rendering` | string | null | Rendering name or null for auto |
| `preferred_text` | string | title-only | Text density level |
| `preferred_mood` | string | balanced | Mood intensity level |
| `default_aspect` | string | "2.35:1" | Default aspect ratio | | `default_aspect` | string | "2.35:1" | Default aspect ratio |
| `quick_mode` | bool | false | Skip confirmation step |
| `language` | string | null | Output language (null = auto-detect) | | `language` | string | null | Output language (null = auto-detect) |
| `custom_styles` | array | [] | User-defined styles | | `custom_palettes` | array | [] | User-defined palettes |
## Type Options ## Type Options
@@ -64,6 +73,48 @@ custom_styles:
| `scene` | Atmospheric scene, narrative feel | | `scene` | Atmospheric scene, narrative feel |
| `minimal` | Minimalist composition, generous whitespace | | `minimal` | Minimalist composition, generous whitespace |
## Palette Options
| Value | Description |
|-------|-------------|
| `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 |
## Rendering Options
| Value | Description |
|-------|-------------|
| `flat-vector` | Clean outlines, uniform fills, geometric icons |
| `hand-drawn` | Sketchy, organic, imperfect strokes, paper texture |
| `painterly` | Soft brush strokes, color bleeds, watercolor feel |
| `digital` | Polished, precise edges, subtle gradients, UI components |
| `pixel` | Pixel grid, dithering, chunky 8-bit shapes |
| `chalk` | Chalk strokes, dust effects, blackboard texture |
## Text Options
| Value | Description |
|-------|-------------|
| `none` | Pure visual, no text elements |
| `title-only` | Single headline (≤8 characters) |
| `title-subtitle` | Title + subtitle (≤15 characters) |
| `text-rich` | Title + subtitle + keyword tags (2-4) |
## Mood Options
| Value | Description |
|-------|-------------|
| `subtle` | Low contrast, muted colors, calm aesthetic |
| `balanced` | Medium contrast, normal saturation, versatile |
| `bold` | High contrast, vivid colors, dynamic energy |
## Position Options ## Position Options
| Value | Description | | Value | Description |
@@ -81,29 +132,32 @@ custom_styles:
| `16:9` | Standard widescreen | Presentations, video thumbnails | | `16:9` | Standard widescreen | Presentations, video thumbnails |
| `1:1` | Square | Social media, profile images | | `1:1` | Square | Social media, profile images |
## Custom Style Fields ## Custom Palette Fields
| Field | Required | Description | | Field | Required | Description |
|-------|----------|-------------| |-------|----------|-------------|
| `name` | Yes | Unique style identifier (kebab-case) | | `name` | Yes | Unique palette identifier (kebab-case) |
| `description` | Yes | What the style conveys | | `description` | Yes | What the palette conveys |
| `color_palette.primary` | No | Main colors (array) | | `colors.primary` | No | Main colors (array of hex) |
| `color_palette.background` | No | Background color | | `colors.background` | No | Background color (hex) |
| `color_palette.accents` | No | Accent colors (array) | | `colors.accents` | No | Accent colors (array of hex) |
| `visual_elements` | No | Decorative elements | | `decorative_hints` | No | Decorative elements and patterns |
| `typography` | No | Font/lettering style |
| `best_for` | No | Recommended content types | | `best_for` | No | Recommended content types |
## Example: Minimal Preferences ## Example: Minimal Preferences
```yaml ```yaml
--- ---
version: 1 version: 3
watermark: watermark:
enabled: true enabled: true
content: "@myhandle" content: "@myhandle"
preferred_type: null preferred_type: null
preferred_style: elegant preferred_palette: elegant
preferred_rendering: hand-drawn
preferred_text: title-only
preferred_mood: balanced
quick_mode: false
--- ---
``` ```
@@ -111,30 +165,97 @@ preferred_style: elegant
```yaml ```yaml
--- ---
version: 1 version: 3
watermark: watermark:
enabled: true enabled: true
content: "myblog.com" content: "myblog.com"
position: bottom-right position: bottom-right
opacity: 0.5
preferred_type: conceptual preferred_type: conceptual
preferred_style: blueprint preferred_palette: cool
preferred_rendering: digital
preferred_text: title-subtitle
preferred_mood: subtle
default_aspect: "16:9" default_aspect: "16:9"
quick_mode: true
language: en language: en
custom_styles: custom_palettes:
- name: corporate-tech - name: corporate-tech
description: "Professional B2B tech style" description: "Professional B2B tech palette"
color_palette: colors:
primary: ["#1E3A5F", "#4A90D9"] primary: ["#1E3A5F", "#4A90D9"]
background: "#F5F7FA" background: "#F5F7FA"
accents: ["#00B4D8", "#48CAE4"] accents: ["#00B4D8", "#48CAE4"]
visual_elements: "Clean lines, subtle gradients, circuit patterns" decorative_hints: "Clean lines, subtle gradients, circuit patterns"
typography: "Modern sans-serif, professional"
best_for: "SaaS, enterprise, technical" best_for: "SaaS, enterprise, technical"
--- ---
``` ```
## Migration from v2
When loading v2 schema, auto-upgrade:
| v2 Field | v3 Field | Migration |
|----------|----------|-----------|
| `version: 2` | `version: 3` | Update |
| `preferred_style` | `preferred_palette` + `preferred_rendering` | Use preset mapping table |
| `custom_styles` | `custom_palettes` | Rename, restructure fields |
**Style → Palette + Rendering mapping**:
| v2 `preferred_style` | v3 `preferred_palette` | v3 `preferred_rendering` |
|----------------------|----------------------|-------------------------|
| `elegant` | `elegant` | `hand-drawn` |
| `blueprint` | `cool` | `digital` |
| `chalkboard` | `dark` | `chalk` |
| `dark-atmospheric` | `dark` | `digital` |
| `editorial-infographic` | `cool` | `digital` |
| `fantasy-animation` | `pastel` | `painterly` |
| `flat-doodle` | `pastel` | `flat-vector` |
| `intuition-machine` | `retro` | `digital` |
| `minimal` | `mono` | `flat-vector` |
| `nature` | `earth` | `hand-drawn` |
| `notion` | `mono` | `digital` |
| `pixel-art` | `vivid` | `pixel` |
| `playful` | `pastel` | `hand-drawn` |
| `retro` | `retro` | `digital` |
| `sketch-notes` | `warm` | `hand-drawn` |
| `vector-illustration` | `retro` | `flat-vector` |
| `vintage` | `retro` | `hand-drawn` |
| `warm` | `warm` | `hand-drawn` |
| `watercolor` | `earth` | `painterly` |
| null (auto) | null | null |
**Custom style migration**:
| v2 Field | v3 Field |
|----------|----------|
| `custom_styles[].name` | `custom_palettes[].name` |
| `custom_styles[].description` | `custom_palettes[].description` |
| `custom_styles[].color_palette` | `custom_palettes[].colors` |
| `custom_styles[].visual_elements` | `custom_palettes[].decorative_hints` |
| `custom_styles[].typography` | (removed — determined by rendering) |
| `custom_styles[].best_for` | `custom_palettes[].best_for` |
## Migration from v1
When loading v1 schema, auto-upgrade to v3:
| v1 Field | v3 Field | Default Value |
|----------|----------|---------------|
| (missing) | `version` | 3 |
| (missing) | `preferred_palette` | null |
| (missing) | `preferred_rendering` | null |
| (missing) | `preferred_text` | title-only |
| (missing) | `preferred_mood` | balanced |
| (missing) | `quick_mode` | false |
v1 `--no-title` flag maps to `preferred_text: none`.
@@ -28,15 +28,6 @@ description: Watermark configuration guide for baoyu-cover-image
| `bottom-center` | Centered designs | Text-heavy bottom area | | `bottom-center` | Centered designs | Text-heavy bottom area |
| `top-right` | Bottom-heavy content | Title/header in top-right | | `top-right` | Bottom-heavy content | Title/header in top-right |
## Opacity Examples
| Opacity | Visual Effect | Use Case |
|---------|---------------|----------|
| 0.3 | Very subtle, barely visible | Clean aesthetic priority |
| 0.5 | Balanced, noticeable but not distracting | Default recommendation |
| 0.7 | Clearly visible | Brand recognition priority |
| 0.9 | Strong presence | Anti-copy protection |
## Content Format ## Content Format
| Format | Example | Style | | Format | Example | Style |
@@ -51,16 +42,14 @@ description: Watermark configuration guide for baoyu-cover-image
1. **Consistency**: Use same watermark across all covers 1. **Consistency**: Use same watermark across all covers
2. **Legibility**: Ensure watermark readable on both light/dark areas 2. **Legibility**: Ensure watermark readable on both light/dark areas
3. **Size**: Keep subtle - should not distract from content 3. **Size**: Keep subtle - should not distract from content
4. **Contrast**: Adjust opacity based on cover background
## Prompt Integration ## Prompt Integration
When watermark is enabled, add to image generation prompt: When watermark is enabled, add to image generation prompt:
``` ```
Include a subtle watermark "[content]" positioned at [position] Include a subtle watermark "[content]" positioned at [position].
with approximately [opacity*100]% visibility. The watermark should The watermark should be legible but not distracting from the main content.
be legible but not distracting from the main content.
``` ```
## Cover-Specific Considerations ## Cover-Specific Considerations
@@ -75,7 +64,6 @@ be legible but not distracting from the main content.
| Issue | Solution | | Issue | Solution |
|-------|----------| |-------|----------|
| Watermark invisible | Increase opacity or adjust position | | Watermark invisible | Adjust position or check contrast |
| Watermark too prominent | Decrease opacity (0.3-0.5) | | Watermark too prominent | Change position or reduce size |
| Watermark overlaps title | Change position or reduce title area | | Watermark overlaps title | Change position or reduce title area |
| Inconsistent appearance | Use fixed opacity/position in preferences |
@@ -0,0 +1,139 @@
---
name: mood-dimension
description: Emotional intensity dimension for cover images
---
# Mood Dimension
Controls emotional intensity and visual weight of cover images.
## Values
| Value | Contrast | Saturation | Weight | Energy |
|-------|:--------:|:----------:|:------:|:------:|
| `subtle` | Low | Muted | Light | Calm |
| `balanced` | Medium | Normal | Medium | Moderate |
| `bold` | High | Vivid | Heavy | Dynamic |
## Detail
### subtle
Calm, understated visual presence.
**Characteristics**:
- Low contrast between elements
- Muted, desaturated colors
- Light visual weight
- Gentle, refined aesthetic
- Soft edges and transitions
**Use Cases**:
- Thought leadership content
- Professional/corporate communications
- Meditation, wellness topics
- Academic or scholarly articles
- Luxury brand aesthetics
**Color Guidance**:
- Pastels, earth tones, neutrals
- Low saturation (30-50%)
- Soft gradients
- Minimal color variety (2-3 colors)
### balanced
Versatile, harmonious visual presence.
**Characteristics**:
- Medium contrast
- Natural saturation levels
- Balanced visual weight
- Clear but not aggressive
- Standard aesthetic approach
**Use Cases**:
- General articles (default)
- Most blog content
- Educational material
- Product documentation
- News and updates
**Color Guidance**:
- Standard saturation (50-70%)
- Complementary color schemes
- Clear foreground/background separation
- Moderate color variety (3-4 colors)
### bold
Dynamic, high-impact visual presence.
**Characteristics**:
- High contrast between elements
- Vivid, saturated colors
- Heavy visual weight
- Energetic, attention-grabbing
- Sharp edges and strong shapes
**Use Cases**:
- Product launches
- Promotional announcements
- Event marketing
- Call-to-action content
- Entertainment/gaming topics
**Color Guidance**:
- High saturation (70-100%)
- Vibrant, primary colors
- Strong contrast ratios
- Dynamic color combinations (4+ colors)
## Type Compatibility
| Type | subtle | balanced | bold |
|------|:------:|:--------:|:----:|
| hero | ✓ | ✓✓ | ✓✓ |
| conceptual | ✓✓ | ✓✓ | ✓ |
| typography | ✓ | ✓✓ | ✓✓ |
| metaphor | ✓✓ | ✓✓ | ✓ |
| scene | ✓✓ | ✓✓ | ✓ |
| minimal | ✓✓ | ✓✓ | ✗ |
✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
## Palette Interaction
Mood modifies the base palette characteristics:
| Palette Category | subtle | balanced | bold |
|------------------|--------|----------|------|
| Warm palettes (warm, earth, pastel) | More whitespace, softer tones | Standard colors | Deeper, richer warm tones |
| Cool palettes (cool, mono, elegant) | Lighter lines, muted colors | Standard colors | Stronger contrast, sharper definition |
| Dark palettes (dark, vivid) | Reduced contrast, softer glow | Standard colors | Maximum impact, vivid saturation |
| Vintage palettes (retro) | More faded, sepia-heavy | Standard colors | Bolder retro contrasts |
## Rendering Interaction
Mood adjusts rendering characteristics:
| Rendering | subtle | balanced | bold |
|-----------|--------|----------|------|
| flat-vector | Thinner strokes, lighter fills | Standard weight | Thicker strokes, stronger fills |
| hand-drawn | Lighter pencil pressure, more space | Standard strokes | Heavier marker strokes, denser elements |
| painterly | Diluted washes, more white | Standard brush | Thicker paint, saturated strokes |
| digital | Reduced shadows, lower contrast | Standard rendering | Stronger shadows, sharper edges |
| pixel | Fewer colors, simpler shapes | Standard palette | More colors, denser pixel detail |
| chalk | Lighter chalk, more board showing | Standard chalk | Heavy chalk, vivid colors, dense marks |
## Auto Selection
When `--mood` is omitted, select based on signals:
| Signals | Mood Level |
|---------|------------|
| Professional, corporate, thought leadership, academic, luxury | `subtle` |
| General, educational, standard, blog, documentation | `balanced` |
| Launch, announcement, promotion, event, gaming, entertainment | `bold` |
Default: `balanced`
@@ -0,0 +1,140 @@
---
name: text-dimension
description: Text density dimension for cover images
---
# Text Dimension
Controls text density and information hierarchy on cover images.
## Values
| Value | Title | Subtitle | Tags | Visual Area |
|-------|:-----:|:--------:|:----:|:-----------:|
| `none` | - | - | - | 100% |
| `title-only` | ✓ (≤8字) | - | - | 85% |
| `title-subtitle` | ✓ | ✓ (≤15字) | - | 75% |
| `text-rich` | ✓ | ✓ | ✓ (2-4) | 60% |
## Detail
### none
Pure visual cover with no text elements.
**Use Cases**:
- Photography-focused covers
- Abstract art pieces
- Visual-only social sharing
- When title added externally
**Composition**:
- Full visual area available
- No reserved text zones
- Emphasis on visual metaphor
### title-only
Single headline, maximum impact.
**Use Cases**:
- Most article covers (default)
- Clear single message
- Strong brand recognition
**Composition**:
- Title: ≤8 characters, prominent
- Reserved zone: top or bottom 15%
- Visual supports title message
**Title Guidelines**:
- Punchy, action-oriented
- Match content language
- Use engagement hooks (see below)
**Engagement Hooks**:
| Hook Type | Examples (EN) | Examples (ZH) |
|-----------|---------------|---------------|
| Numbers | "3 Traps", "5 Keys" | "3个陷阱", "5个关键" |
| Questions | "Why X?", "How?" | "为什么X?", "怎么做?" |
| Contrasts | "A vs B", "Old→New" | "A还是B", "旧→新" |
| Pain Points | "Stop X", "Never Do" | "别再X了", "千万别" |
| Suspense | "Hidden X", "Secret" | "隐藏的X", "秘密" |
### title-subtitle
Title with supporting context.
**Use Cases**:
- Technical articles needing clarification
- Series with episode/part info
- Content with dual messages
**Composition**:
- Title: ≤8 characters, primary
- Subtitle: ≤15 characters, secondary
- Reserved zone: 25%
- Clear hierarchy between title/subtitle
**Title Guidelines**:
- Use engagement hooks: numbers, questions, contrasts, pain points, suspense
- Punchy, action-oriented
**Subtitle Guidelines**:
- Clarify or contextualize title
- Can include series name, author, date
- Smaller, less prominent than title
### text-rich
Information-dense cover with multiple text elements.
**Use Cases**:
- Infographic-style covers
- Event announcements with details
- Promotional material with features
- Content with multiple key points
**Composition**:
- Title: primary focus
- Subtitle: supporting info
- Tags: 2-4 keyword labels
- Reserved zone: 40%
- Clear visual hierarchy
**Title Guidelines**:
- Use engagement hooks: numbers, questions, contrasts, pain points, suspense
- Punchy, action-oriented
**Tag Guidelines**:
- 2-4 tags maximum
- Short keywords (1-2 words each)
- Positioned as badges/labels
- Can highlight: category, date, author, key features
## Type Compatibility
| Type | none | title-only | title-subtitle | text-rich |
|------|:----:|:----------:|:--------------:|:---------:|
| hero | ✓ | ✓✓ | ✓✓ | ✓ |
| conceptual | ✓✓ | ✓✓ | ✓ | ✓ |
| typography | ✗ | ✓ | ✓✓ | ✓✓ |
| metaphor | ✓✓ | ✓ | ✓ | ✗ |
| scene | ✓✓ | ✓ | ✓ | ✗ |
| minimal | ✓✓ | ✓✓ | ✓ | ✗ |
✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
## Auto Selection
When `--text` is omitted, select based on signals:
| Signals | Text Level |
|---------|------------|
| Visual-only, photography, abstract, art | `none` |
| Article, blog, standard cover | `title-only` |
| Series, tutorial, technical with context | `title-subtitle` |
| Announcement, features, multiple points, infographic | `text-rich` |
Default: `title-only`
@@ -0,0 +1,26 @@
# cool
Technical, professional, precise
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Engineering Blue | #2563EB |
| Primary 2 | Navy Blue | #1E3A5F |
| Primary 3 | Cyan | #06B6D4 |
| Background | Light Gray | #F8F9FA |
| Background Alt | Blueprint Off-White | #FAF8F5 |
| Accent 1 | Amber | #F59E0B |
| Accent 2 | Light Blue | #BFDBFE |
## Decorative Hints
- Grid lines and alignment guides
- Dimension indicators and measurements
- Technical schematics and diagrams
- Geometric precision elements
## Best For
Architecture, system design, API, technical documentation, engineering, data analysis
@@ -0,0 +1,26 @@
# dark
Cinematic, premium, atmospheric
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Electric Purple | #8B5CF6 |
| Primary 2 | Cyan Blue | #06B6D4 |
| Primary 3 | Magenta Pink | #EC4899 |
| Background | Deep Purple-Black | #0A0A0A |
| Background Alt | Rich Navy | #1A1A2E |
| Accent 1 | Amber | #F59E0B |
| Accent 2 | Pure White | #FFFFFF |
## Decorative Hints
- Glowing accent elements and neon highlights
- Atmospheric fog or particle effects
- Silhouettes with backlit edges
- Subtle gradient backgrounds
## Best For
Entertainment, premium brands, cinematic storytelling, dark mode, gaming, night themes
@@ -0,0 +1,26 @@
# earth
Natural, organic, grounded
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Forest Green | #276749 |
| Primary 2 | Sage | #9AE6B4 |
| Primary 3 | Earth Brown | #744210 |
| Background | Sand Beige | #F5E6D3 |
| Background Alt | Sky Blue | #E0F2FE |
| Accent 1 | Sunset Orange | #ED8936 |
| Accent 2 | Water Blue | #63B3ED |
## Decorative Hints
- Leaves, trees, mountains, natural forms
- Sun, clouds, organic flowing lines
- Botanical illustrations
- Earthy textures and natural patterns
## Best For
Nature, wellness, eco, organic, travel, sustainability, outdoor topics, slow living
@@ -0,0 +1,26 @@
# elegant
Sophisticated, refined, understated luxury
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Soft Coral | #E8A598 |
| Primary 2 | Muted Teal | #5B8A8A |
| Primary 3 | Dusty Rose | #D4A5A5 |
| Background | Warm Cream | #F5F0E6 |
| Background Alt | Soft Beige | #F0EBE0 |
| Accent 1 | Gold | #C9A962 |
| Accent 2 | Copper | #B87333 |
## Decorative Hints
- Delicate ornamental details
- Subtle gradients and soft transitions
- Refined geometric patterns
- Balanced, symmetrical compositions
## Best For
Business, professional, thought leadership, luxury, corporate communications
@@ -0,0 +1,26 @@
# mono
Clean, focused, essential
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Pure Black | #000000 |
| Primary 2 | Near Black | #1F1F1F |
| Primary 3 | Dark Gray | #374151 |
| Background | White | #FFFFFF |
| Background Alt | Off-White | #FAFAFA |
| Accent 1 | Content-derived single color | - |
| Accent 2 | Medium Gray | #9CA3AF |
## Decorative Hints
- Maximum negative space
- Thin lines and minimal strokes
- Single focal point emphasis
- Stark contrast between elements
## Best For
Zen, focus, essential concepts, pure, simple, minimalist philosophy, clean design
@@ -0,0 +1,26 @@
# pastel
Gentle, whimsical, soft
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Soft Pink | #FFB6C1 |
| Primary 2 | Mint | #98D8C8 |
| Primary 3 | Lavender | #C8A2C8 |
| Background | White | #FFFFFF |
| Background Alt | Light Cream | #FFF8E7 |
| Accent 1 | Butter Yellow | #FFFACD |
| Accent 2 | Sky Blue | #BEE3F8 |
## Decorative Hints
- Cute rounded proportions
- Stars, sparkles, flowers, decorative flourishes
- Soft shadows and gentle highlights
- Storybook-style elements
## Best For
Fantasy, children, gentle content, creative, whimsical, casual, beginner guides
@@ -0,0 +1,30 @@
# retro
Nostalgic, vintage, classic
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Coral Red | #E07A5F |
| Primary 2 | Mint Green | #81B29A |
| Primary 3 | Mustard Yellow | #F2CC8F |
| Primary 4 | Dark Maroon | #5D3A3A |
| Background | Cream Off-White | #F5F0E6 |
| Background Alt | Aged Paper | #F5E6D3 |
| Accent 1 | Burnt Orange | #D4764A |
| Accent 2 | Rock Blue | #577590 |
| Accent 3 | Vintage Gold | #C9A227 |
| Accent 4 | Faded Teal | #2F7373 |
## Decorative Hints
- Halftone dots and vintage badges
- Aged textures with subtle paper grain
- Sunburst/radiating lines for energy
- Pill-shaped clouds, small dots and stars
- Classic icons and retro motifs
## Best For
History, vintage, retro, classic, exploration, retrospectives, throwback content, creative proposals, educational
@@ -0,0 +1,26 @@
# vivid
Energetic, bold, attention-grabbing
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Bright Red | #EF4444 |
| Primary 2 | Neon Green | #22C55E |
| Primary 3 | Electric Blue | #3B82F6 |
| Background | Light Blue | #EFF6FF |
| Background Alt | Soft Lavender | #F5F3FF |
| Accent 1 | Bright Orange | #FB923C |
| Accent 2 | Vivid Yellow | #FACC15 |
## Decorative Hints
- Dynamic diagonal lines and angles
- Bold geometric shapes and color blocks
- Dramatic lighting effects
- High-energy visual compositions
## Best For
Product launch, gaming, promotion, event, marketing, announcements, brand showcases
@@ -0,0 +1,26 @@
# warm
Friendly, approachable, human-centered
## Color Palette
| Role | Color | Hex |
|------|-------|-----|
| Primary 1 | Warm Orange | #ED8936 |
| Primary 2 | Golden Yellow | #F6AD55 |
| Primary 3 | Terracotta | #C05621 |
| Background | Cream | #FFFAF0 |
| Background Alt | Soft Peach | #FED7AA |
| Accent 1 | Deep Brown | #744210 |
| Accent 2 | Soft Red | #E53E3E |
## Decorative Hints
- Sun rays, warm lighting effects
- Rounded shapes, organic curves
- Hearts, smiling faces, friendly icons
- Warm gradient overlays
## Best For
Personal growth, lifestyle, education, human stories, emotion, community
@@ -0,0 +1,43 @@
# chalk
Educational, authentic, classroom
## Core Characteristics
Chalk on blackboard aesthetic with imperfect strokes, dust effects, and authentic classroom feel. Nostalgic educational warmth.
## Lines
- Imperfect chalk strokes with variable pressure
- Visible chalk texture and grain
- Slightly wobbly, hand-drawn quality
- Thick strokes for emphasis, thin for details
## Texture
- Chalk dust effects around text and elements
- Board surface (dark, slightly worn)
- Eraser smudges and residue
- Grainy chalk quality on all elements
## Depth
- None: flat chalk drawings on board surface
- Layering through erasure and redrawing
- No shadows or perspective
## Element Vocabulary
- Chalk doodles: stars, arrows, underlines
- Mathematical formulas and diagrams
- Stick figures and simple icons
- Connection lines with chalk feel
- Checkmarks, circles, boxes for lists
- Wooden frame border optional
## Typography Approach
- Hand-drawn chalk lettering
- Imperfect baseline, authentic classroom feel
- White or bright colored chalk for emphasis
- Variable sizing for hierarchy
@@ -0,0 +1,42 @@
# digital
Polished, precise, modern
## Core Characteristics
Clean digital illustration with polished finish, precise edges, and subtle modern effects. Feels like a professional UI mockup or corporate illustration.
## Lines
- Clean, precise, computer-perfect edges
- Consistent stroke weights
- Sharp corners where appropriate
- Anti-aliased smooth rendering
## Texture
- Smooth surfaces with no visible texture
- Subtle gradients permitted (soft, controlled)
- Frosted glass and blur effects
- Clean shadows with consistent direction
## Depth
- Subtle gradients and soft drop shadows
- Layered card-based layouts
- Light 3D effects (subtle, not realistic)
- Material Design-inspired elevation
## Element Vocabulary
- Polished icons and UI components
- Data visualizations: charts, graphs, metrics
- Card layouts and structured grids
- Tag chips, progress bars, status indicators
- Clean geometric shapes
## Typography Approach
- System UI or modern sans-serif (Inter, SF Pro style)
- Clean, functional, high readability
- Structured hierarchy with consistent spacing
@@ -0,0 +1,42 @@
# flat-vector
Clean, modern, geometric illustration
## Core Characteristics
Flat design with clean outlines, uniform fills, and no texture or depth. Think modern app icons, infographic illustrations, and vector-based editorial art.
## Lines
- Clean outlines with uniform stroke weight
- Closed shapes (coloring-book style)
- Rounded line endings, avoid sharp corners
- Consistent stroke width throughout
## Texture
- None: smooth, flat color fills only
- No gradients, shadows, or noise
- Solid color blocks
## Depth
- Flat: no shadows, no perspective
- 2D layering with overlap for depth illusion
- Optional 2.5D isometric layering (front/back occlusion, no atmospheric perspective)
- No 3D effects or bevels
## Element Vocabulary
- Geometric icons and simple shapes
- Bold outlined objects with clean fills
- Geometric simplification: complex objects → basic shapes (trees → lollipop/triangle, buildings → rectangles)
- "Toy model" aesthetic: cute, rounded proportions
- Decorative: dots, lines, sunbursts, pill-shaped clouds, small stars
- Isolated elements on clean backgrounds
## Typography Approach
- Clean sans-serif or bold geometric lettering
- Strong readability, consistent weight
- Easily scalable at any size
@@ -0,0 +1,40 @@
# hand-drawn
Sketchy, organic, personal
## Core Characteristics
Hand-drawn illustration with visible imperfections, organic line quality, and personal touch. Feels like a skilled artist's sketchbook or whiteboard drawing.
## Lines
- Sketchy, organic, slightly imperfect strokes
- Variable line weight (thicker at pressure points)
- Wavy connectors and arrows
- Natural hand tremor visible
## Texture
- Paper grain and subtle surface texture
- Pencil/pen/marker texture on strokes
- Casual fills with visible brush direction
## Depth
- Minimal: light hand-drawn shadows or hatching
- No realistic depth or perspective
- Simple layering with overlap
## Element Vocabulary
- Doodles, organic shapes, hand-lettered labels
- Conceptual icons with sketchy quality
- Connection lines with hand-drawn wavy feel
- Stars, arrows, underlines, circles, checkmarks
- Stick figures and simple characters
## Typography Approach
- Hand-lettered or marker-style text
- Bouncy baselines, organic feel
- Variable sizes for emphasis hierarchy
@@ -0,0 +1,40 @@
# painterly
Soft, artistic, expressive
## Core Characteristics
Watercolor or paint-style illustration with visible brush strokes, color bleeds, and artistic texture. Feels like a hand-painted art piece.
## Lines
- Soft brush strokes with variable opacity
- No hard outlines; edges defined by color transitions
- Organic flowing strokes with natural blending
## Texture
- Visible paint or watercolor wash textures
- Color bleeds and wet-on-wet effects
- Paper texture showing through transparent areas
- Brush stroke patterns visible
## Depth
- Soft edges with natural color blending
- Atmospheric depth through color fading
- Layered washes creating depth illusion
## Element Vocabulary
- Watercolor washes as backgrounds
- Natural elements: leaves, flowers, organic forms
- Soft gradients and color transitions
- Splatter and drip effects as accents
- Botanical and environmental motifs
## Typography Approach
- Elegant brush script or handwritten style
- Organic letterforms with brush texture
- Integrated with paint environment
@@ -0,0 +1,42 @@
# pixel
Retro 8-bit, nostalgic, chunky
## Core Characteristics
Pixel art aesthetic with visible pixel grid, limited color palette, and nostalgic gaming feel. Emulates classic 8-bit and 16-bit era graphics.
## Lines
- Pixel grid alignment, no anti-aliasing
- Staircase edges on diagonals
- Single-pixel or double-pixel outlines
- Blocky, angular forms
## Texture
- Dithering patterns for gradients
- No smooth transitions
- Cross-hatching with pixel precision
- Limited 16-32 color palette per scene
## Depth
- None: flat pixel planes only
- Parallax layering (foreground/background)
- No perspective or 3D effects
## Element Vocabulary
- 8-bit sprites and chunky shapes
- Simple iconography: stars, hearts, arrows
- Text bubbles with pixel borders
- Progress bars with chunky segments
- Retro gaming UI elements
## Typography Approach
- Pixelated bitmap font style
- Chunky blocky letterforms
- Fixed-width or monospace feel
- All-caps for headers
@@ -0,0 +1,32 @@
# Style Presets
`--style X` expands to a palette + rendering combination. Users can override either dimension.
| --style | Palette | Rendering |
|---------|---------|-----------|
| `elegant` | `elegant` | `hand-drawn` |
| `blueprint` | `cool` | `digital` |
| `chalkboard` | `dark` | `chalk` |
| `dark-atmospheric` | `dark` | `digital` |
| `editorial-infographic` | `cool` | `digital` |
| `fantasy-animation` | `pastel` | `painterly` |
| `flat-doodle` | `pastel` | `flat-vector` |
| `intuition-machine` | `retro` | `digital` |
| `minimal` | `mono` | `flat-vector` |
| `nature` | `earth` | `hand-drawn` |
| `notion` | `mono` | `digital` |
| `pixel-art` | `vivid` | `pixel` |
| `playful` | `pastel` | `hand-drawn` |
| `retro` | `retro` | `digital` |
| `sketch-notes` | `warm` | `hand-drawn` |
| `vector-illustration` | `retro` | `flat-vector` |
| `vintage` | `retro` | `hand-drawn` |
| `warm` | `warm` | `hand-drawn` |
| `watercolor` | `earth` | `painterly` |
## Override Examples
- `--style blueprint --rendering hand-drawn` = cool palette with hand-drawn rendering
- `--style elegant --palette warm` = warm palette with hand-drawn rendering
Explicit `--palette`/`--rendering` flags always override preset values.
@@ -1,25 +0,0 @@
# blueprint
Precise technical blueprint style with engineering aesthetic
## Color Palette
- Primary: Engineering Blue (#2563EB), Navy Blue (#1E3A5F)
- Background: Blueprint Off-White (#FAF8F5), subtle grid overlay
- Accents: Amber (#F59E0B), Light Blue (#BFDBFE)
## Visual Elements
- Precise lines with consistent stroke weights
- Technical schematics and clean vector graphics
- Dimension lines and measurement indicators
- Grid alignment for all elements
- Geometric precision for all shapes
## Typography
- Clean sans-serif hand lettering, technical and authoritative
## Best For
Technical architecture, system design, data analysis, engineering documentation
@@ -1,26 +0,0 @@
# bold-editorial
High-impact magazine editorial with bold visual expression
## Color Palette
- Primary: Pure White (#FFFFFF), Electric Blue (#3B82F6), Bright Orange (#FB923C)
- Background: Deep Black (#0A0A0A), Deep Blue (#0F172A)
- Accents: Magenta (#EC4899), Neon Green (#22C55E), Violet (#8B5CF6)
## Visual Elements
- Strong typography as visual element itself
- Geometric shapes and bold color blocks
- Full-bleed solid color backgrounds
- Dynamic diagonal lines and angles
- Dramatic lighting effects on text
- Minimal decoration, maximum impact
## Typography
- Bold condensed typeface, oversized headlines, all-caps, tight letter-spacing
## Best For
Product launches, marketing, keynote speeches, brand showcases, investor pitches
@@ -1,61 +0,0 @@
# chalkboard
Black chalkboard background with colorful chalk drawing style
## Design Aesthetic
Classic classroom chalkboard aesthetic with hand-drawn chalk illustrations. Nostalgic educational feel with imperfect, sketchy lines that capture the warmth of traditional teaching. Colorful chalk creates visual hierarchy while maintaining the authentic chalkboard experience.
## Background
- Color: Chalkboard Black (#1A1A1A) or Dark Green-Black (#1C2B1C)
- Texture: Realistic chalkboard texture with subtle scratches, dust particles, and faint eraser marks
## Typography
Hand-drawn chalk lettering style with visible chalk texture. Imperfect baseline adds authenticity. White or bright colored chalk for emphasis.
## Color Palette
| Role | Color | Hex | Usage |
|------|-------|-----|-------|
| Background | Chalkboard Black | #1A1A1A | Primary background |
| Alt Background | Green-Black | #1C2B1C | Traditional green board |
| Primary Text | Chalk White | #F5F5F5 | Main text, outlines |
| Accent 1 | Chalk Yellow | #FFE566 | Highlights, emphasis |
| Accent 2 | Chalk Pink | #FF9999 | Secondary highlights |
| Accent 3 | Chalk Blue | #66B3FF | Diagrams, links |
| Accent 4 | Chalk Green | #90EE90 | Success, nature |
| Accent 5 | Chalk Orange | #FFB366 | Warnings, energy |
## Visual Elements
- Hand-drawn chalk illustrations with sketchy, imperfect lines
- Chalk dust effects around text and key elements
- Doodles: stars, arrows, underlines, circles, checkmarks
- Mathematical formulas and simple diagrams
- Eraser smudges and chalk residue textures
- Wooden frame border optional
- Stick figures and simple icons
- Connection lines with hand-drawn feel
## Style Rules
### Do
- Maintain authentic chalk texture on all elements
- Use imperfect, hand-drawn quality throughout
- Add subtle chalk dust and smudge effects
- Create visual hierarchy with color variety
- Include playful doodles and annotations
### Don't
- Use perfect geometric shapes
- Create clean digital-looking lines
- Add photorealistic elements
- Use gradients or glossy effects
## Best For
Educational content, tutorials, classroom themes, teaching materials, workshops, informal learning sessions, knowledge sharing
@@ -1,25 +0,0 @@
# dark-atmospheric
Dark moody aesthetic with glowing accent elements
## Color Palette
- Primary: Electric Purple (#8B5CF6), Cyan Blue (#06B6D4), Magenta Pink (#EC4899)
- Background: Deep Purple-Black (#0D0D1A), Rich Navy (#1A1A2E)
- Accents: Amber (#F59E0B), Pure White (#FFFFFF)
## Visual Elements
- Glowing accent elements and borders
- Subtle gradient backgrounds
- Atmospheric fog or particle effects
- Neon-style highlights on key elements
- Silhouettes with backlit edges
## Typography
- Elegant serif or refined sans-serif in light/white with subtle glow
## Best For
Entertainment, creative industries, premium brands, cinematic storytelling
@@ -1,26 +0,0 @@
# editorial-infographic
Modern magazine-style editorial with clear visual storytelling
## Color Palette
- Primary: Near Black (#1A1A1A), Editorial Blue (#2563EB)
- Background: Pure White (#FFFFFF), Light Gray (#F8F9FA)
- Accents: Coral (#F97316), Emerald (#10B981), Amber (#F59E0B)
## Visual Elements
- Clean flat illustrations (not photos)
- Structured multi-section layouts
- Callout boxes for key insights
- Icon-based data visualization
- Visual metaphors for abstract concepts
- Pull quotes and highlight boxes
## Typography
- Bold display serif or modern sans-serif, editorial sophistication
## Best For
Technology explainers, science communication, research summaries, thought leadership
@@ -1,23 +0,0 @@
# elegant
Refined, sophisticated, understated
## Color Palette
- Primary: Soft coral (#E8A598), muted teal (#5B8A8A), dusty rose (#D4A5A5)
- Background: Warm cream (#F5F0E6), soft beige
- Accents: Gold (#C9A962), copper
## Visual Elements
- Delicate lines, refined icons
- Subtle gradients
- Balanced composition
## Typography
- Elegant serif-style hand lettering
## Best For
Professional content, thought leadership, business topics
@@ -1,25 +0,0 @@
# fantasy-animation
Whimsical hand-drawn animation style inspired by Ghibli and Disney
## Color Palette
- Primary: Golden Yellow (#F4D03F), Rose Pink (#E8A0BF), Deep Forest (#2D5A3D)
- Background: Soft Sky Blue (#E8F4FC), Warm Cream (#FFF8E7)
- Accents: Sage Green (#87A96B), Sky Blue (#7EC8E3), Coral (#F08080)
## Visual Elements
- Central illustrated character (friendly, expressive)
- Magical floating objects (books, orbs, sparkles)
- Storybook-style environment backgrounds
- Soft shadows and gentle highlights
- Decorative elements: stars, sparkles, flowers, leaves
## Typography
- Whimsical serif or decorative hand-lettered style, organic feel
## Best For
Educational content, storytelling, creative workshops, fantasy/gaming content
@@ -1,27 +0,0 @@
# flat-doodle
Cute, simple doodle illustrations with bold outlines
## Color Palette
- Primary: Bright pastel pink (#FFB6C1), mint (#98D8C8), lavender (#C8A2C8), butter yellow (#FFFACD)
- Background: Clean white (#FFFFFF)
- Accents: Bold black outlines, soft coral, sky blue
## Visual Elements
- Bold black outlines around all shapes
- Simple flat shapes with no shading
- Cute rounded proportions
- Productivity-themed icons
- Isolated elements on white background
- Minimal decorative details
## Typography
- Simple, clean sans-serif or hand-lettering
- Bold and easily readable
## Best For
Productivity content, SaaS articles, workflow tutorials, app features, beginner guides, casual business
@@ -1,26 +0,0 @@
# intuition-machine
Technical briefing style with aged paper and bilingual labels
## Color Palette
- Primary: Dark Maroon (#5D3A3A), Teal (#2F7373)
- Background: Aged Cream (#F5F0E6), subtle paper texture with light creases
- Accents: Warm Brown (#8B7355), Maroon (#722F37), Deep Charcoal (#2D2D2D)
## Visual Elements
- Isometric 3D technical illustrations or flat 2D diagrams
- Bilingual callout labels (English + Chinese)
- Faded thematic background patterns
- Clean black outlines on all elements
- Split or triptych layouts
- Key quote box at bottom
## Typography
- Bold display font in dark maroon, ALL CAPS for titles, bilingual labels
## Best For
Technical explanations, academic presentations, bilingual audiences, knowledge docs
@@ -1,23 +0,0 @@
# minimal
Ultra-clean, zen-like, focused
## Color Palette
- Primary: Pure black (#000000), white (#FFFFFF)
- Background: White or off-white (#FAFAFA)
- Accents: Single color (user's choice or content-derived)
## Visual Elements
- Single focal point
- Maximum negative space
- Thin lines
## Typography
- Clean, simple hand lettering, lots of breathing room
## Best For
Philosophy, minimalism, focused concepts
@@ -1,22 +0,0 @@
# nature
Organic, calm, earthy
## Color Palette
- Primary: Forest green (#276749), sage (#9AE6B4), earth brown (#744210)
- Background: Sand beige (#F5E6D3), sky blue (#E0F2FE)
- Accents: Sunset orange, water blue
## Visual Elements
- Leaves, trees, mountains
- Sun, clouds, organic flowing lines
## Typography
- Organic, flowing hand lettering with natural textures
## Best For
Sustainability, wellness, outdoor topics, slow living
@@ -1,25 +0,0 @@
# notion
Clean SaaS dashboard aesthetic with productivity tool styling
## Color Palette
- Primary: Near Black (#1F1F1F), Notion Blue (#2383E2)
- Background: Light Gray (#F7F7F5), Pure White (#FFFFFF)
- Accents: Success Green (#0F7B6C), Alert Red (#E03E3E), Warning Yellow (#DFAB01)
## Visual Elements
- Card-based layouts with subtle borders
- Clean data visualizations
- Tag and label chips
- Icon-based navigation hints
- Progress bars and metric displays
## Typography
- System UI or Inter style, clean and functional
## Best For
Product demos, SaaS presentations, productivity content, B2B topics
@@ -1,26 +0,0 @@
# pixel-art
Retro 8-bit pixel art aesthetic with nostalgic gaming style
## Color Palette
- Primary: Dark Navy (#1A1A2E), Pixel Green (#00FF00)
- Background: Light Blue (#87CEEB), Soft Lavender (#E6E6FA)
- Accents: Pixel Red (#FF0000), Pixel Yellow (#FFFF00), Pixel Cyan (#00FFFF)
## Visual Elements
- All elements with visible pixel structure
- Simple iconography: stars, hearts, arrows
- Text bubbles with pixel borders
- Progress bars with chunky segments
- Dithering patterns for gradients
- Limited 16-32 color palette
## Typography
- Pixelated bitmap font style, chunky blocky letterforms
## Best For
Gaming content, tech tutorials, developer talks, retro-themed topics
@@ -1,23 +0,0 @@
# playful
Fun, creative, whimsical
## Color Palette
- Primary: Pastel pink (#FED7E2), mint (#C6F6D5), lavender (#E9D8FD), sky blue (#BEE3F8)
- Background: Light cream (#FFFBEB), soft white
- Accents: Bright pops - yellow, coral, turquoise
## Visual Elements
- Doodles, stars, swirls
- Cute characters, emoji-style icons
- Playful compositions
## Typography
- Bouncy, irregular hand lettering, playful angles
## Best For
Casual content, tutorials, beginner guides, fun topics
@@ -1,22 +0,0 @@
# retro
Vintage, nostalgic, classic
## Color Palette
- Primary: Muted orange (#ED8936 at 70%), dusty pink (#FED7E2 at 80%), faded teal
- Background: Aged paper (#F5E6D3), sepia tones
- Accents: Faded red, vintage gold
## Visual Elements
- Halftone dots, vintage badges
- Classic icons, aged textures
## Typography
- Vintage-style hand lettering, classic serif influence
## Best For
History, retrospectives, classic topics, throwback content
@@ -1,25 +0,0 @@
# sketch-notes
Soft hand-drawn illustration style with fresh minimalist aesthetic
## Color Palette
- Primary: Deep Charcoal (#2C3E50), Soft Orange (#F4A261)
- Background: Warm Off-White (#FAF8F0), subtle paper grain
- Accents: Mustard Yellow (#E9C46A), Sage Green (#87A96B), Light Blue (#7EC8E3)
## Visual Elements
- Connection lines with hand-drawn wavy feel
- Conceptual abstract icons illustrating ideas
- Color fills with hand-painted casual feel
- Doodle-style decorative elements
- Arrows and pointers with sketchy style
## Typography
- Bold hand-written marker font for headlines, casual handwriting for body
## Best For
Educational content, knowledge sharing, technical explanations, tutorials
@@ -1,25 +0,0 @@
# vector-illustration
Flat vector illustration with black outlines and retro soft colors
## Color Palette
- Primary: Coral Red (#E07A5F), Mint Green (#81B29A), Mustard Yellow (#F2CC8F)
- Background: Cream Off-White (#F5F0E6), subtle paper texture
- Accents: Burnt Orange (#D4764A), Rock Blue (#577590), Deep Charcoal (#2D2D2D) outlines
## Visual Elements
- All objects have closed black outlines (coloring book style)
- Rounded line endings, avoid sharp corners
- Simplified geometric shapes
- 2.5D perspective with layering
- Decorative elements: sunbursts, pill clouds, dots, stars
## Typography
- Large bold retro serif for titles, clean geometric sans-serif for body
## Best For
Educational content, creative proposals, brand showcases, explainer content
@@ -1,26 +0,0 @@
# vintage
Vintage aged-paper aesthetic with historical document styling
## Color Palette
- Primary: Dark Brown (#3D2914), Forest Green (#2D5A3D), Navy Blue (#1E3A5F)
- Background: Aged Parchment (#F5E6D3), Sepia Cream (#FFF8DC)
- Accents: Burgundy (#722F37), Gold (#C9A227), Sepia Black (#3D3D3D)
## Visual Elements
- Antique maps with route lines and landmarks
- Compass roses and nautical elements
- Specimen drawings (flora, fauna)
- Handwritten-style annotations
- Rope, leather, brass decorative motifs
- Aged texture with subtle creases
## Typography
- Classic serif with historical character, elegant flourishes
## Best For
Historical content, travel, heritage storytelling, biography, scientific discovery
@@ -1,22 +0,0 @@
# warm
Friendly, approachable, human-centered
## Color Palette
- Primary: Warm orange (#ED8936), golden yellow (#F6AD55), terracotta (#C05621)
- Background: Cream (#FFFAF0), soft peach (#FED7AA)
- Accents: Deep brown (#744210), soft red
## Visual Elements
- Rounded shapes, smiling faces
- Sun rays, hearts, warm lighting
## Typography
- Friendly rounded hand lettering
## Best For
Personal growth, lifestyle, education, human stories
@@ -1,25 +0,0 @@
# watercolor
Soft watercolor illustration style with hand-painted textures
## Color Palette
- Primary: Soft Coral (#F4A261), Dusty Rose (#E8A0A0)
- Background: Warm Off-White (#FAF8F0), Soft Cream (#FFF9E6)
- Accents: Sage Green (#87A96B), Sky Blue (#7EC8E3), Soft Lavender (#C5B4E3)
## Visual Elements
- Watercolor washes as backgrounds
- Visible brush strokes and textures
- Natural elements: leaves, flowers, organic shapes
- Color bleeds and soft edges
- Hand-drawn arrows and connections
## Typography
- Elegant handwritten or brush script, organic letterforms
## Best For
Lifestyle content, wellness, travel guides, personal stories, creative topics
@@ -0,0 +1,23 @@
# Type Composition Guidelines
## Type Gallery
| Type | Description | Best For |
|------|-------------|----------|
| `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-Specific Composition
| Type | Composition Guidelines |
|------|------------------------|
| `hero` | Large focal visual (60-70% area), title overlay on visual, dramatic composition |
| `conceptual` | Abstract shapes representing core concepts, information hierarchy, clean zones |
| `typography` | Title as primary element (40%+ area), minimal supporting visuals, strong hierarchy |
| `metaphor` | Concrete object/scene representing abstract idea, symbolic elements, emotional resonance |
| `scene` | Atmospheric environment, narrative elements, mood-setting lighting and colors |
| `minimal` | Single focal element, generous whitespace (60%+), essential shapes only |
@@ -0,0 +1,132 @@
# Step 2: Confirm Options
## Purpose
Validate all 5 dimensions + aspect ratio.
## Skip Conditions
| Condition | Skipped Questions | Still Asked |
|-----------|-------------------|-------------|
| `--quick` flag | Type, Palette, Rendering, Text, Mood | **Aspect Ratio** (unless `--aspect` specified) |
| All 5 dimensions + `--aspect` specified | All | None |
| `quick_mode: true` in EXTEND.md | Type, Palette, Rendering, Text, Mood | **Aspect Ratio** (unless `--aspect` specified) |
| Otherwise | None | All 6 questions |
**Important**: Aspect ratio is ALWAYS asked unless explicitly specified via `--aspect` CLI flag. User presets in EXTEND.md are shown as recommended option, not auto-selected.
## Quick Mode Output
When skipping 5 dimensions:
```
Quick Mode: Auto-selected dimensions
• Type: [type] ([reason])
• Palette: [palette] ([reason])
• Rendering: [rendering] ([reason])
• Text: [text] ([reason])
• Mood: [mood] ([reason])
[Then ask Question 6: Aspect Ratio]
```
## Confirmation Flow
**Language**: Auto-determined (user's input language > saved preference > source language). No need to ask.
Present ALL options in a **single AskUserQuestion call** (4 questions max).
Skip any question where the dimension is already specified via CLI flag or `--style` preset.
### Q1: Type (skip if `--type`)
```yaml
header: "Type"
question: "Which cover type?"
multiSelect: false
options:
- label: "[auto-recommended type] (Recommended)"
description: "[reason based on content signals]"
- label: "hero"
description: "Large visual impact, title overlay - product launch, announcements"
- label: "conceptual"
description: "Concept visualization - technical, architecture"
- label: "typography"
description: "Text-focused layout - opinions, quotes"
```
### Q2: Palette (skip if `--palette` or `--style`)
```yaml
header: "Palette"
question: "Which color palette?"
multiSelect: false
options:
- label: "[auto-recommended palette] (Recommended)"
description: "[reason based on content signals]"
- label: "warm"
description: "Friendly - orange, golden yellow, terracotta"
- label: "elegant"
description: "Sophisticated - soft coral, muted teal, dusty rose"
- label: "cool"
description: "Technical - engineering blue, navy, cyan"
```
### Q3: Rendering (skip if `--rendering` or `--style`)
Show compatible renderings (✓✓ first from compatibility matrix):
```yaml
header: "Rendering"
question: "Which rendering style?"
multiSelect: false
options:
- label: "[best compatible rendering] (Recommended)"
description: "[reason based on palette + type + content]"
- label: "flat-vector"
description: "Clean outlines, flat fills, geometric icons"
- label: "hand-drawn"
description: "Sketchy, organic, imperfect strokes"
- label: "digital"
description: "Polished, precise, subtle gradients"
```
### Q4: Other Settings (skip if all remaining dimensions already specified)
Combine remaining settings into one question. Include: Output Dir (if no preference + file path input), Text, Mood, Aspect. Show auto-selected values as recommended option. User can accept all or type adjustments via "Other".
**When output dir needs asking** (no `default_output_dir` preference + file path input):
```yaml
header: "Settings"
question: "Output / Text / Mood / Aspect?"
multiSelect: false
options:
- label: "imgs/ / [auto-text] / [auto-mood] / [preset-aspect] (Recommended)"
description: "{article-dir}/imgs/, [text reason], [mood reason], [aspect source]"
- label: "same-dir / [auto-text] / [auto-mood] / [preset-aspect]"
description: "{article-dir}/, same directory as article"
- label: "independent / [auto-text] / [auto-mood] / [preset-aspect]"
description: "cover-image/{topic-slug}/, separate from article"
```
**When output dir already set** (preference exists or pasted content):
```yaml
header: "Settings"
question: "Text / Mood / Aspect?"
multiSelect: false
options:
- label: "[auto-text] / [auto-mood] / [preset-aspect] (Recommended)"
description: "Auto-selected: [text reason], [mood reason], [aspect source]"
- label: "[auto-text] / bold / [preset-aspect]"
description: "High contrast, vivid — matches [content signal]"
- label: "[auto-text] / subtle / [preset-aspect]"
description: "Low contrast, muted — calm, professional"
```
*Note*: "Other" (auto-added) allows typing custom combo. Parse `/`-separated values matching the question format.
## After Response
Proceed to Step 3 with confirmed dimensions.
@@ -0,0 +1,84 @@
# Step 3: Prompt Template
Save to `prompts/cover.md`:
```markdown
# Content Context
Article title: [full original title from source]
Content summary: [2-3 sentence summary of key points and themes]
Keywords: [5-8 key terms extracted from content]
# Visual Design
Cover theme: [2-3 words visual interpretation]
Type: [confirmed type]
Palette: [confirmed palette]
Rendering: [confirmed rendering]
Text level: [confirmed text level]
Mood: [confirmed mood]
Aspect ratio: [confirmed ratio]
Language: [confirmed language]
# Text Elements
[Based on text level:]
- none: "No text elements"
- title-only: "Title: [max 8 chars headline]"
- title-subtitle: "Title: [headline] / Subtitle: [max 15 chars context]"
- text-rich: "Title: [headline] / Subtitle: [context] / Tags: [2-4 keywords]"
# Mood Application
[Based on mood level:]
- subtle: "Use low contrast, muted colors, light visual weight, calm aesthetic"
- balanced: "Use medium contrast, normal saturation, balanced visual weight"
- bold: "Use high contrast, vivid saturated colors, heavy visual weight, dynamic energy"
# Composition
Type composition:
- [Type-specific layout and structure]
Visual composition:
- Main visual: [metaphor derived from content meaning]
- Layout: [positioning based on type and aspect ratio]
- Decorative: [palette-specific elements that reinforce content theme]
Color scheme: [primary, background, accent from palette definition, adjusted by mood]
Rendering notes: [key characteristics from rendering definition — lines, texture, depth, element style]
Type notes: [key characteristics from type definition]
Palette notes: [key characteristics from palette definition]
[Watermark section if enabled]
```
## Content-Driven Design
- Article title and summary inform the visual metaphor choice
- Keywords guide decorative elements and symbols
- The skill controls visual style; the content drives meaning
## Type-Specific Composition
| Type | Composition Guidelines |
|------|------------------------|
| `hero` | Large focal visual (60-70% area), title overlay on visual, dramatic composition |
| `conceptual` | Abstract shapes representing core concepts, information hierarchy, clean zones |
| `typography` | Title as primary element (40%+ area), minimal supporting visuals, strong hierarchy |
| `metaphor` | Concrete object/scene representing abstract idea, symbolic elements, emotional resonance |
| `scene` | Atmospheric environment, narrative elements, mood-setting lighting and colors |
| `minimal` | Single focal element, generous whitespace (60%+), essential shapes only |
## Title Guidelines
When text level includes title:
- Max 8 characters, punchy headline
- Use engagement hooks: numbers ("3个陷阱"), questions ("Why X?"), contrasts ("A vs B"), pain points ("别再X了")
- Match confirmed language
## Watermark Application
If enabled in preferences, add to prompt:
```
Include a subtle watermark "[content]" positioned at [position].
The watermark should be legible but not distracting from the main content.
```
Reference: `config/watermark-guide.md`
+81 -226
View File
@@ -1,15 +1,11 @@
--- ---
name: baoyu-danger-gemini-web name: baoyu-danger-gemini-web
description: Image generation skill using Gemini Web. Generates images from text prompts via Google Gemini. Also supports text generation. Use as the image generation backend for other skills like cover-image, xhs-images, article-illustrator. description: Generates images and text via reverse-engineered Gemini Web API. Supports text generation, image generation from prompts, reference images for vision input, and multi-turn conversations. Use when other skills need image generation backend, or when user requests "generate image with Gemini", "Gemini text generation", or needs vision-capable AI generation.
--- ---
# Gemini Web Client # Gemini Web Client
Supports: Text/image generation via Gemini Web API. Supports reference images and multi-turn conversations.
- Text generation
- Image generation (download + save)
- Reference images for vision input (attach local images)
- Multi-turn conversations via persisted `--sessionId`
## Script Directory ## Script Directory
@@ -26,146 +22,73 @@ Supports:
| `scripts/main.ts` | CLI entry point for text/image generation | | `scripts/main.ts` | CLI entry point for text/image generation |
| `scripts/gemini-webapi/*` | TypeScript port of `gemini_webapi` (GeminiClient, types, utils) | | `scripts/gemini-webapi/*` | TypeScript port of `gemini_webapi` (GeminiClient, types, utils) |
## ⚠️ Disclaimer (REQUIRED) ## Consent Check (REQUIRED)
**Before using this skill**, the consent check MUST be performed. Before first use, verify user consent for reverse-engineered API usage.
### Consent Check Flow **Consent file locations**:
- macOS: `~/Library/Application Support/baoyu-skills/gemini-web/consent.json`
- Linux: `~/.local/share/baoyu-skills/gemini-web/consent.json`
- Windows: `%APPDATA%\baoyu-skills\gemini-web\consent.json`
**Step 1**: Check consent file **Flow**:
1. Check if consent file exists with `accepted: true` and `disclaimerVersion: "1.0"`
```bash 2. If valid consent exists → print warning with `acceptedAt` date, proceed
# macOS 3. If no consent → show disclaimer, ask user via `AskUserQuestion`:
cat ~/Library/Application\ Support/baoyu-skills/gemini-web/consent.json 2>/dev/null - "Yes, I accept" → create consent file with ISO timestamp, proceed
- "No, I decline" → output decline message, stop
# Linux 4. Consent file format: `{"version":1,"accepted":true,"acceptedAt":"<ISO>","disclaimerVersion":"1.0"}`
cat ~/.local/share/baoyu-skills/gemini-web/consent.json 2>/dev/null
# Windows (PowerShell)
Get-Content "$env:APPDATA\baoyu-skills\gemini-web\consent.json" 2>$null
```
**Step 2**: If consent exists and `accepted: true` with matching `disclaimerVersion: "1.0"`:
Print warning and proceed:
```
⚠️ Warning: Using reverse-engineered Gemini Web API (not official). Accepted on: <acceptedAt date>
```
**Step 3**: If consent file doesn't exist or `disclaimerVersion` mismatch:
Display disclaimer and ask user:
```
⚠️ DISCLAIMER
This tool uses a reverse-engineered Gemini Web API, NOT an official Google API.
Risks:
- May break without notice if Google changes their API
- No official support or guarantees
- Use at your own risk
Do you accept these terms and wish to continue?
```
Use `AskUserQuestion` tool with options:
- **Yes, I accept** - Continue and save consent
- **No, I decline** - Exit immediately
**Step 4**: On acceptance, create consent file:
```bash
# macOS
mkdir -p ~/Library/Application\ Support/baoyu-skills/gemini-web
cat > ~/Library/Application\ Support/baoyu-skills/gemini-web/consent.json << 'EOF'
{
"version": 1,
"accepted": true,
"acceptedAt": "<ISO timestamp>",
"disclaimerVersion": "1.0"
}
EOF
# Linux
mkdir -p ~/.local/share/baoyu-skills/gemini-web
cat > ~/.local/share/baoyu-skills/gemini-web/consent.json << 'EOF'
{
"version": 1,
"accepted": true,
"acceptedAt": "<ISO timestamp>",
"disclaimerVersion": "1.0"
}
EOF
```
**Step 5**: On decline, output message and stop:
```
User declined the disclaimer. Exiting.
```
--- ---
## Quick start ## Preferences (EXTEND.md)
Use Bash to check EXTEND.md existence (priority order):
```bash ```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts "Hello, Gemini" # Check project-level first
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Explain quantum computing" test -f .baoyu-skills/baoyu-danger-gemini-web/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/baoyu-danger-gemini-web/EXTEND.md" && echo "user"
```
┌──────────────────────────────────────────────────────────┬───────────────────┐
│ Path │ Location │
├──────────────────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/baoyu-danger-gemini-web/EXTEND.md │ Project directory │
├──────────────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-danger-gemini-web/EXTEND.md │ User home │
└──────────────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, apply settings │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Use defaults │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Default model | Proxy settings | Custom data directory
## Usage
```bash
# Text generation
npx -y bun ${SKILL_DIR}/scripts/main.ts "Your prompt"
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Your prompt" --model gemini-2.5-pro
# Image generation
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cute cat" --image cat.png npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cute cat" --image cat.png
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
# Multi-turn conversation (agent generates unique sessionId) # Vision input (reference images)
npx -y bun ${SKILL_DIR}/scripts/main.ts "Remember this: 42" --sessionId my-unique-id-123 npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Describe this" --reference image.png
npx -y bun ${SKILL_DIR}/scripts/main.ts "What number?" --sessionId my-unique-id-123 npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Create variation" --reference a.png --image out.png
```
## Commands # Multi-turn conversation
npx -y bun ${SKILL_DIR}/scripts/main.ts "Remember: 42" --sessionId session-abc
### Text generation npx -y bun ${SKILL_DIR}/scripts/main.ts "What number?" --sessionId session-abc
```bash
# Simple prompt (positional)
npx -y bun ${SKILL_DIR}/scripts/main.ts "Your prompt here"
# Explicit prompt flag
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Your prompt here"
npx -y bun ${SKILL_DIR}/scripts/main.ts -p "Your prompt here"
# With model selection
npx -y bun ${SKILL_DIR}/scripts/main.ts -p "Hello" -m gemini-2.5-pro
# Pipe from stdin
echo "Summarize this" | npx -y bun ${SKILL_DIR}/scripts/main.ts
```
### Image generation
```bash
# Generate image with default path (./generated.png)
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A sunset over mountains" --image
# Generate image with custom path
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cute robot" --image robot.png
# Shorthand
npx -y bun ${SKILL_DIR}/scripts/main.ts "A dragon" --image=dragon.png
```
### Vision input (reference images)
```bash
# Text + image -> text
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Describe this image" --reference a.png
# Text + image -> image
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Generate a variation" --reference a.png --image out.png
```
### Output formats
```bash
# Plain text (default)
npx -y bun ${SKILL_DIR}/scripts/main.ts "Hello"
# JSON output # JSON output
npx -y bun ${SKILL_DIR}/scripts/main.ts "Hello" --json npx -y bun ${SKILL_DIR}/scripts/main.ts "Hello" --json
@@ -175,45 +98,35 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts "Hello" --json
| Option | Description | | Option | Description |
|--------|-------------| |--------|-------------|
| `--prompt <text>`, `-p` | Prompt text | | `--prompt`, `-p` | Prompt text |
| `--promptfiles <files...>` | Read prompt from files (concatenated in order) | | `--promptfiles` | Read prompt from files (concatenated) |
| `--model <id>`, `-m` | Model: gemini-3-pro (default), gemini-2.5-pro, gemini-2.5-flash | | `--model`, `-m` | Model: gemini-3-pro (default), gemini-2.5-pro, gemini-2.5-flash |
| `--image [path]` | Generate image, save to path (default: generated.png) | | `--image [path]` | Generate image (default: generated.png) |
| `--reference <files...>`, `--ref <files...>` | Reference images for vision input | | `--reference`, `--ref` | Reference images for vision input |
| `--sessionId <id>` | Session ID for multi-turn conversation (agent generates unique ID) | | `--sessionId` | Session ID for multi-turn conversation |
| `--list-sessions` | List saved sessions (max 100, sorted by update time) | | `--list-sessions` | List saved sessions |
| `--json` | Output as JSON | | `--json` | Output as JSON |
| `--login` | Refresh cookies only, then exit | | `--login` | Refresh cookies, then exit |
| `--cookie-path <path>` | Custom cookie file path | | `--cookie-path` | Custom cookie file path |
| `--profile-dir <path>` | Chrome profile directory | | `--profile-dir` | Chrome profile directory |
| `--help`, `-h` | Show help |
CLI note: `scripts/main.ts` supports text generation, image generation, reference images (`--reference/--ref`), and multi-turn conversations via `--sessionId`.
## Models ## Models
- `gemini-3-pro` - Default, latest model | Model | Description |
- `gemini-2.5-pro` - Previous generation pro |-------|-------------|
- `gemini-2.5-flash` - Fast, lightweight | `gemini-3-pro` | Default, latest |
| `gemini-2.5-pro` | Previous pro |
| `gemini-2.5-flash` | Fast, lightweight |
## Authentication ## Authentication
First run opens a browser to authenticate with Google. Cookies are cached for subsequent runs. First run opens browser for Google auth. Cookies cached automatically.
**Supported browsers** (auto-detected in order): Supported browsers (auto-detected): Chrome, Chrome Canary/Beta, Chromium, Edge.
- Google Chrome
- Google Chrome Canary / Beta
- Chromium
- Microsoft Edge
Override with `GEMINI_WEB_CHROME_PATH` environment variable if needed. Force refresh: `--login` flag. Override browser: `GEMINI_WEB_CHROME_PATH` env var.
```bash ## Environment Variables
# Force cookie refresh
npx -y bun ${SKILL_DIR}/scripts/main.ts --login
```
## Environment variables
| Variable | Description | | Variable | Description |
|----------|-------------| |----------|-------------|
@@ -221,72 +134,14 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts --login
| `GEMINI_WEB_COOKIE_PATH` | Cookie file path | | `GEMINI_WEB_COOKIE_PATH` | Cookie file path |
| `GEMINI_WEB_CHROME_PROFILE_DIR` | Chrome profile directory | | `GEMINI_WEB_CHROME_PROFILE_DIR` | Chrome profile directory |
| `GEMINI_WEB_CHROME_PATH` | Chrome executable path | | `GEMINI_WEB_CHROME_PATH` | Chrome executable path |
| `HTTP_PROXY`, `HTTPS_PROXY` | Proxy for Google access (set inline with command) |
## Proxy Configuration ## Sessions
If you need a proxy to access Google services (e.g., in China), set `HTTP_PROXY` and `HTTPS_PROXY` environment variables before running: Session files stored in data directory under `sessions/<id>.json`.
```bash Contains: `id`, `metadata` (Gemini chat state), `messages` array, timestamps.
# Example with local proxy
HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 npx -y bun ${SKILL_DIR}/scripts/main.ts "Hello"
# Image generation with proxy
HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png
# Cookie refresh with proxy
HTTP_PROXY=http://127.0.0.1:7890 HTTPS_PROXY=http://127.0.0.1:7890 npx -y bun ${SKILL_DIR}/scripts/main.ts --login
```
**Note**: Environment variables must be set inline with the command. Shell profile settings (e.g., `.bashrc`) may not be inherited by subprocesses.
## Examples
### Generate text response
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts "What is the capital of France?"
```
### Generate image
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts "A photorealistic image of a golden retriever puppy" --image puppy.png
```
### Get JSON output for parsing
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts "Hello" --json | jq '.text'
```
### Generate image from prompt files
```bash
# Concatenate system.md + content.md as prompt
npx -y bun ${SKILL_DIR}/scripts/main.ts --promptfiles system.md content.md --image output.png
```
### Multi-turn conversation
```bash
# Start a session with unique ID (agent generates this)
npx -y bun ${SKILL_DIR}/scripts/main.ts "You are a helpful math tutor." --sessionId task-abc123
# Continue the conversation (remembers context)
npx -y bun ${SKILL_DIR}/scripts/main.ts "What is 2+2?" --sessionId task-abc123
npx -y bun ${SKILL_DIR}/scripts/main.ts "Now multiply that by 10" --sessionId task-abc123
# List recent sessions (max 100, sorted by update time)
npx -y bun ${SKILL_DIR}/scripts/main.ts --list-sessions
```
Session files are stored in `~/Library/Application Support/baoyu-skills/gemini-web/sessions/<id>.json` and contain:
- `id`: Session ID
- `metadata`: Gemini chat metadata for continuation
- `messages`: Array of `{role, content, timestamp, error?}`
- `createdAt`, `updatedAt`: Timestamps
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/baoyu-danger-gemini-web/EXTEND.md` (project)
2. `~/.baoyu-skills/baoyu-danger-gemini-web/EXTEND.md` (user)
If found, load before workflow. Extension content overrides defaults.
+69 -102
View File
@@ -1,119 +1,107 @@
--- ---
name: baoyu-danger-x-to-markdown name: baoyu-danger-x-to-markdown
description: Convert X (Twitter) tweet or article URL to markdown. Uses reverse-engineered X API (private). Requires user consent before use. description: Converts X (Twitter) tweets and articles to markdown with YAML front matter. Uses reverse-engineered API requiring user consent. Use when user mentions "X to markdown", "tweet to markdown", "save tweet", or provides x.com/twitter.com URLs for conversion.
--- ---
# X to Markdown # X to Markdown
Converts X (Twitter) content to markdown format: Converts X content to markdown:
- Tweet threads → Markdown with YAML front matter - Tweets/threads → Markdown with YAML front matter
- X Articles → Full article content extraction - X Articles → Full content extraction
## Script Directory ## Script Directory
**Important**: All scripts are located in the `scripts/` subdirectory of this skill. Scripts located in `scripts/` subdirectory.
**Agent Execution Instructions**: **Path Resolution**:
1. Determine this SKILL.md file's directory path as `SKILL_DIR` 1. `SKILL_DIR` = this SKILL.md's directory
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts` 2. Script path = `${SKILL_DIR}/scripts/main.ts`
3. Replace all `${SKILL_DIR}` in this document with the actual path
**Script Reference**: ## Consent Requirement
| Script | Purpose |
|--------|---------|
| `scripts/main.ts` | CLI entry point for URL conversion |
## ⚠️ Disclaimer (REQUIRED) **Before any conversion**, check and obtain consent.
**Before using this skill**, the consent check MUST be performed. ### Consent Flow
### Consent Check Flow
**Step 1**: Check consent file **Step 1**: Check consent file
```bash ```bash
# macOS # macOS
cat ~/Library/Application\ Support/baoyu-skills/x-to-markdown/consent.json 2>/dev/null cat ~/Library/Application\ Support/baoyu-skills/x-to-markdown/consent.json
# Linux # Linux
cat ~/.local/share/baoyu-skills/x-to-markdown/consent.json 2>/dev/null cat ~/.local/share/baoyu-skills/x-to-markdown/consent.json
# Windows (PowerShell)
Get-Content "$env:APPDATA\baoyu-skills\x-to-markdown\consent.json" 2>$null
``` ```
**Step 2**: If consent exists and `accepted: true` with matching `disclaimerVersion: "1.0"`: **Step 2**: If `accepted: true` and `disclaimerVersion: "1.0"` → print warning and proceed:
Print warning and proceed:
``` ```
⚠️ Warning: Using reverse-engineered X API (not official). Accepted on: <acceptedAt date> Warning: Using reverse-engineered X API. Accepted on: <acceptedAt>
``` ```
**Step 3**: If consent file doesn't exist or `disclaimerVersion` mismatch: **Step 3**: If missing or version mismatch → display disclaimer:
Display disclaimer and ask user:
``` ```
⚠️ DISCLAIMER DISCLAIMER
This tool uses a reverse-engineered X (Twitter) API, NOT an official API. This tool uses a reverse-engineered X API, NOT official.
Risks: Risks:
- May break without notice if X changes their API - May break if X changes API
- No official support or guarantees - No guarantees or support
- Account restrictions possible if API usage detected - Possible account restrictions
- Use at your own risk - Use at your own risk
Do you accept these terms and wish to continue? Accept terms and continue?
``` ```
Use `AskUserQuestion` tool with options: Use `AskUserQuestion` with options: "Yes, I accept" | "No, I decline"
- **Yes, I accept** - Continue and save consent
- **No, I decline** - Exit immediately
**Step 4**: On acceptance, create consent file: **Step 4**: On accept create consent file:
```json
{
"version": 1,
"accepted": true,
"acceptedAt": "<ISO timestamp>",
"disclaimerVersion": "1.0"
}
```
**Step 5**: On decline → output "User declined. Exiting." and stop.
## Preferences (EXTEND.md)
Use Bash to check EXTEND.md existence (priority order):
```bash ```bash
# macOS # Check project-level first
mkdir -p ~/Library/Application\ Support/baoyu-skills/x-to-markdown test -f .baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md && echo "project"
cat > ~/Library/Application\ Support/baoyu-skills/x-to-markdown/consent.json << 'EOF'
{
"version": 1,
"accepted": true,
"acceptedAt": "<ISO timestamp>",
"disclaimerVersion": "1.0"
}
EOF
# Linux # Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
mkdir -p ~/.local/share/baoyu-skills/x-to-markdown test -f "$HOME/.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md" && echo "user"
cat > ~/.local/share/baoyu-skills/x-to-markdown/consent.json << 'EOF'
{
"version": 1,
"accepted": true,
"acceptedAt": "<ISO timestamp>",
"disclaimerVersion": "1.0"
}
EOF
``` ```
**Step 5**: On decline, output message and stop: ┌────────────────────────────────────────────────────────────┬───────────────────┐
``` │ Path │ Location │
User declined the disclaimer. Exiting. ├────────────────────────────────────────────────────────────┼───────────────────┤
``` │ .baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md │ Project directory │
├────────────────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md │ User home │
└────────────────────────────────────────────────────────────┴───────────────────┘
--- ┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, apply settings │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Use defaults │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Default output directory | Output format preferences
## Usage ## Usage
```bash ```bash
# Convert tweet (outputs markdown path)
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> npx -y bun ${SKILL_DIR}/scripts/main.ts <url>
# Save to specific file
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> -o output.md npx -y bun ${SKILL_DIR}/scripts/main.ts <url> -o output.md
# JSON output
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> --json npx -y bun ${SKILL_DIR}/scripts/main.ts <url> --json
``` ```
@@ -122,56 +110,35 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts <url> --json
| Option | Description | | Option | Description |
|--------|-------------| |--------|-------------|
| `<url>` | Tweet or article URL | | `<url>` | Tweet or article URL |
| `-o <path>` | Output path (file or dir) | | `-o <path>` | Output path |
| `--json` | Output as JSON | | `--json` | JSON output |
| `--login` | Refresh cookies only | | `--login` | Refresh cookies only |
## File Structure
```
x-to-markdown/
└── {username}/
└── {tweet-id}.md
```
## Supported URLs ## Supported URLs
- `https://x.com/<user>/status/<id>` - `https://x.com/<user>/status/<id>`
- `https://twitter.com/<user>/status/<id>` - `https://twitter.com/<user>/status/<id>`
- `https://x.com/i/article/<id>` - `https://x.com/i/article/<id>`
## Output Format ## Output
```markdown ```markdown
--- ---
url: https://x.com/username/status/123 url: https://x.com/user/status/123
author: "Display Name (@username)" author: "Name (@user)"
tweet_count: 3 tweet_count: 3
--- ---
Tweet content... Content...
---
Thread continuation...
``` ```
**File structure**: `x-to-markdown/{username}/{tweet-id}.md`
## Authentication ## Authentication
**Option 1**: Environment variables (recommended) 1. **Environment variables** (preferred): `X_AUTH_TOKEN`, `X_CT0`
- `X_AUTH_TOKEN` - auth_token cookie 2. **Chrome login** (fallback): Auto-opens Chrome, caches cookies locally
- `X_CT0` - ct0 cookie
**Option 2**: Chrome login (auto if env vars not set)
- First run opens Chrome for login
- Cookies cached locally
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md` (project)
2. `~/.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md` (user)
If found, load before workflow. Extension content overrides defaults.
+87 -157
View File
@@ -1,98 +1,68 @@
--- ---
name: baoyu-image-gen name: baoyu-image-gen
description: AI SDK-based image generation using official OpenAI and Google APIs. Supports text-to-image, reference images, aspect ratios, and quality presets. description: AI image generation with OpenAI and Google APIs. Supports text-to-image, reference images, aspect ratios, and parallel generation (recommended 4 concurrent subagents). Use when user asks to generate, create, or draw images.
--- ---
# Image Generation (AI SDK) # Image Generation (AI SDK)
Official API-based image generation via AI SDK. Supports OpenAI (DALL-E, GPT Image) and Google (Imagen, Gemini multimodal). Official API-based image generation. Supports OpenAI and Google providers.
## Script Directory ## Script Directory
**Important**: All scripts are located in the `scripts/` subdirectory of this skill. **Agent Execution**:
1. `SKILL_DIR` = this SKILL.md file's directory
2. Script path = `${SKILL_DIR}/scripts/main.ts`
**Agent Execution Instructions**: ## Preferences (EXTEND.md)
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
3. Replace all `${SKILL_DIR}` in this document with the actual path
**Script Reference**: Use Bash to check EXTEND.md existence (priority order):
| Script | Purpose |
|--------|---------|
| `scripts/main.ts` | CLI entry point for image generation |
## Quick Start
```bash ```bash
# Basic generation (auto-detect provider) # Check project-level first
test -f .baoyu-skills/baoyu-image-gen/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/baoyu-image-gen/EXTEND.md" && echo "user"
```
┌──────────────────────────────────────────────────┬───────────────────┐
│ Path │ Location │
├──────────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/baoyu-image-gen/EXTEND.md │ Project directory │
├──────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-image-gen/EXTEND.md │ User home │
└──────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, apply settings │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Use defaults │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Default provider | Default quality | Default aspect ratio
## Usage
```bash
# Basic
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png
# With aspect ratio # With aspect ratio
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A landscape" --image landscape.png --ar 16:9 npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A landscape" --image out.png --ar 16:9
# High quality (2k) # High quality
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png --quality 2k npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --quality 2k
# Specific provider
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png --provider openai
# 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 only)
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
```
## Commands # Specific provider
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider openai
### Basic Image Generation
```bash
# Generate with prompt
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A sunset over mountains" --image sunset.png
# Shorthand
npx -y bun ${SKILL_DIR}/scripts/main.ts -p "A cute robot" --image robot.png
```
### Aspect Ratios
```bash
# Common ratios: 1:1, 16:9, 9:16, 4:3, 3:4, 2.35:1
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A portrait" --image portrait.png --ar 3:4
# Or specify exact size
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Banner" --image banner.png --size 1792x1024
```
### Reference Images (Google Multimodal)
```bash
# Image editing with reference
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Make it blue" --image blue.png --ref original.png
# Multiple references
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "Combine these styles" --image out.png --ref a.png b.png
```
### Quality Presets
```bash
# Normal quality (default)
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png --quality normal
# High quality (2k resolution)
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png --quality 2k
```
### Output Formats
```bash
# Plain output (prints saved path)
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png
# JSON output
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png --json
``` ```
## Options ## Options
@@ -106,114 +76,74 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png --json
| `--model <id>`, `-m` | Model ID | | `--model <id>`, `-m` | Model ID |
| `--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: normal) | | `--quality normal\|2k` | Quality preset (default: 2k) |
| `--imageSize 1K\|2K\|4K` | Image size for Google (default: from quality) |
| `--ref <files...>` | Reference images (Google multimodal only) | | `--ref <files...>` | Reference images (Google multimodal only) |
| `--n <count>` | Number of images | | `--n <count>` | Number of images |
| `--json` | JSON output | | `--json` | JSON output |
| `--help`, `-h` | Show help |
## Environment Variables ## Environment Variables
| Variable | Description | Default | | Variable | Description |
|----------|-------------|---------| |----------|-------------|
| `OPENAI_API_KEY` | OpenAI API key | - | | `OPENAI_API_KEY` | OpenAI API key |
| `GOOGLE_API_KEY` | Google API key | - | | `GOOGLE_API_KEY` | Google API key |
| `OPENAI_IMAGE_MODEL` | OpenAI model | `gpt-image-1.5` | | `OPENAI_IMAGE_MODEL` | OpenAI model override |
| `GOOGLE_IMAGE_MODEL` | Google model | `gemini-3-pro-image-preview` | | `GOOGLE_IMAGE_MODEL` | Google model override |
| `OPENAI_BASE_URL` | Custom OpenAI endpoint | - | | `OPENAI_BASE_URL` | Custom OpenAI endpoint |
| `GOOGLE_BASE_URL` | Custom Google endpoint | - | | `GOOGLE_BASE_URL` | Custom Google endpoint |
**Load Priority**: CLI args > `process.env` > `<cwd>/.baoyu-skills/.env` > `~/.baoyu-skills/.env` **Load Priority**: CLI args > env vars > `<cwd>/.baoyu-skills/.env` > `~/.baoyu-skills/.env`
## Provider & Model Strategy ## Provider Selection
### Auto-Selection 1. `--provider` specified → use it
2. Only one API key available → use that provider
1. If `--provider` specified → use it 3. Both available → default to Google
2. If only one API key available → use that provider
3. If both available → default to Google (multimodal LLMs more versatile)
### API Selection by Model Type
| Model Category | API Function | Example Models |
|----------------|--------------|----------------|
| Google Multimodal | `generateText` | `gemini-2.0-flash-exp-image-generation` |
| Google Imagen | `experimental_generateImage` | `imagen-3.0-generate-002` |
| OpenAI | `experimental_generateImage` | `gpt-image-1`, `dall-e-3` |
### Available Models
**Google**:
- `gemini-3-pro-image-preview` - Default, multimodal generation
- `gemini-2.0-flash-exp-image-generation` - Gemini 2.0 Flash
- `imagen-3.0-generate-002` - Imagen 3
**OpenAI**:
- `gpt-image-1.5` - Default, GPT Image 1.5
- `gpt-image-1` - GPT Image 1
- `dall-e-3` - DALL-E 3
## Quality Presets ## Quality Presets
| Preset | OpenAI | Google | Use Case | | Preset | Google imageSize | OpenAI Size | Use Case |
|--------|--------|--------|----------| |--------|------------------|-------------|----------|
| `normal` | 1024x1024 | Default | Covers, illustrations | | `normal` | 1K | 1024px | Quick previews |
| `2k` | 2048x2048 | "2048px" in prompt | Infographics, slides | | `2k` (default) | 2K | 2048px | Covers, illustrations, infographics |
## Aspect Ratio Handling **Google imageSize**: Can be overridden with `--imageSize 1K|2K|4K`
- **Multimodal LLMs**: Embedded in prompt (e.g., `"... aspect ratio 16:9"`) ## Aspect Ratios
- **Image-only models**: Uses `aspectRatio` or `size` parameter
- **Common ratios**: 1:1, 16:9, 9:16, 4:3, 3:4, 2.35:1
## Examples Supported: `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `2.35:1`
### Generate Cover Image - Google multimodal: uses `imageConfig.aspectRatio`
- Google Imagen: uses `aspectRatio` parameter
- OpenAI: maps to closest supported size
```bash ## Parallel Generation
npx -y bun ${SKILL_DIR}/scripts/main.ts \
--prompt "A minimalist tech illustration with blue gradients" \ Supports concurrent image generation via background subagents for batch operations.
--image cover.png --ar 2.35:1 --quality 2k
| Setting | Value |
|---------|-------|
| Recommended concurrency | 4 subagents |
| Max concurrency | 8 subagents |
| Use case | Batch generation (slides, comics, infographics) |
**Agent Implementation**:
```
# Launch multiple generations in parallel using Task tool
# Each Task runs as background subagent with run_in_background=true
# Collect results via TaskOutput when all complete
``` ```
### Generate Social Media Post **Best Practice**: When generating 4+ images, spawn background subagents (recommended 4 concurrent) instead of sequential execution.
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts \
--prompt "Instagram post about coffee" \
--image post.png --ar 1:1
```
### Edit Image with Reference
```bash
npx -y bun ${SKILL_DIR}/scripts/main.ts \
--prompt "Change the background to sunset" \
--image edited.png --ref original.png --provider google
```
### Batch Generation from Prompt File
```bash
# Create prompt file with detailed instructions
npx -y bun ${SKILL_DIR}/scripts/main.ts \
--promptfiles style-guide.md scene-description.md \
--image scene.png
```
## Error Handling ## Error Handling
- **Missing API key**: Clear error with setup instructions - Missing API key error with setup instructions
- **Generation failure**: Auto-retry once, then error - Generation failure → auto-retry once
- **Invalid aspect ratio**: Warning, proceed with default - Invalid aspect ratio → warning, proceed with default
- **Reference images with image-only model**: Warning, ignore refs - Reference images with non-multimodal model → warning, ignore refs
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/baoyu-image-gen/EXTEND.md` (project)
2. `~/.baoyu-skills/baoyu-image-gen/EXTEND.md` (user)
If found, load before workflow. Extension content overrides defaults.
+26 -257
View File
@@ -1,36 +1,8 @@
import fs from "node:fs";
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 { mkdir, readFile, writeFile } from "node:fs/promises";
import type { CliArgs, Provider } from "./types";
type Provider = "google" | "openai";
type Quality = "normal" | "2k";
type CliArgs = {
prompt: string | null;
promptFiles: string[];
imagePath: string | null;
provider: Provider | null;
model: string | null;
aspectRatio: string | null;
size: string | null;
quality: Quality;
referenceImages: string[];
n: number;
json: boolean;
help: boolean;
};
const GOOGLE_MULTIMODAL_MODELS = [
"gemini-3-pro-image-preview",
"gemini-2.0-flash-exp-image-generation",
"gemini-2.5-flash-preview-native-audio-dialog",
];
const GOOGLE_IMAGEN_MODELS = ["imagen-3.0-generate-002", "imagen-3.0-generate-001"];
const OPENAI_IMAGE_MODELS = ["gpt-image-1.5", "gpt-image-1", "dall-e-3", "dall-e-2"];
function printUsage(): void { function printUsage(): void {
console.log(`Usage: console.log(`Usage:
@@ -46,7 +18,8 @@ Options:
-m, --model <id> Model ID -m, --model <id> Model ID
--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: normal) --quality normal|2k Quality preset (default: 2k)
--imageSize 1K|2K|4K Image size for Google (default: from quality)
--ref <files...> Reference images (Google multimodal only) --ref <files...> Reference images (Google multimodal only)
--n <count> Number of images (default: 1) --n <count> Number of images (default: 1)
--json JSON output --json JSON output
@@ -55,6 +28,7 @@ Options:
Environment variables: Environment variables:
OPENAI_API_KEY OpenAI API key OPENAI_API_KEY OpenAI API key
GOOGLE_API_KEY Google API key GOOGLE_API_KEY Google API key
GEMINI_API_KEY Gemini API key (alias for GOOGLE_API_KEY)
OPENAI_IMAGE_MODEL Default OpenAI model (gpt-image-1.5) OPENAI_IMAGE_MODEL Default OpenAI model (gpt-image-1.5)
GOOGLE_IMAGE_MODEL Default Google model (gemini-3-pro-image-preview) GOOGLE_IMAGE_MODEL Default Google model (gemini-3-pro-image-preview)
OPENAI_BASE_URL Custom OpenAI endpoint OPENAI_BASE_URL Custom OpenAI endpoint
@@ -72,7 +46,8 @@ function parseArgs(argv: string[]): CliArgs {
model: null, model: null,
aspectRatio: null, aspectRatio: null,
size: null, size: null,
quality: "normal", quality: "2k",
imageSize: null,
referenceImages: [], referenceImages: [],
n: 1, n: 1,
json: false, json: false,
@@ -163,6 +138,13 @@ function parseArgs(argv: string[]): CliArgs {
continue; continue;
} }
if (a === "--imageSize") {
const v = argv[++i]?.toUpperCase();
if (v !== "1K" && v !== "2K" && v !== "4K") throw new Error(`Invalid imageSize: ${v}`);
out.imageSize = v;
continue;
}
if (a === "--ref" || a === "--reference") { if (a === "--ref" || a === "--reference") {
const { items, next } = takeMany(i); const { items, next } = takeMany(i);
if (items.length === 0) throw new Error(`Missing files for ${a}`); if (items.length === 0) throw new Error(`Missing files for ${a}`);
@@ -259,7 +241,7 @@ function normalizeOutputImagePath(p: string): string {
function detectProvider(args: CliArgs): Provider { function detectProvider(args: CliArgs): Provider {
if (args.provider) return args.provider; if (args.provider) return args.provider;
const hasGoogle = !!process.env.GOOGLE_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;
if (hasGoogle && !hasOpenai) return "google"; if (hasGoogle && !hasOpenai) return "google";
@@ -267,235 +249,21 @@ function detectProvider(args: CliArgs): Provider {
if (hasGoogle && hasOpenai) return "google"; if (hasGoogle && hasOpenai) return "google";
throw new Error( throw new Error(
"No API key found. Set GOOGLE_API_KEY or OPENAI_API_KEY.\n" + "No API key found. Set GOOGLE_API_KEY, GEMINI_API_KEY, or OPENAI_API_KEY.\n" +
"Create ~/.baoyu-skills/.env or <cwd>/.baoyu-skills/.env with your keys." "Create ~/.baoyu-skills/.env or <cwd>/.baoyu-skills/.env with your keys."
); );
} }
function getDefaultModel(provider: Provider): string { type ProviderModule = {
getDefaultModel: () => string;
generateImage: (prompt: string, model: string, args: CliArgs) => Promise<Uint8Array>;
};
async function loadProviderModule(provider: Provider): Promise<ProviderModule> {
if (provider === "google") { if (provider === "google") {
return process.env.GOOGLE_IMAGE_MODEL || "gemini-3-pro-image-preview"; return (await import("./providers/google")) as ProviderModule;
} }
return process.env.OPENAI_IMAGE_MODEL || "gpt-image-1.5"; return (await import("./providers/openai")) as ProviderModule;
}
function isGoogleMultimodal(model: string): boolean {
return GOOGLE_MULTIMODAL_MODELS.some((m) => model.includes(m));
}
function isGoogleImagen(model: string): boolean {
return GOOGLE_IMAGEN_MODELS.some((m) => model.includes(m));
}
function buildPromptWithAspect(prompt: string, ar: string | null, quality: Quality): string {
let result = prompt;
if (ar) {
result += ` Aspect ratio: ${ar}.`;
}
if (quality === "2k") {
result += " High resolution 2048px.";
}
return result;
}
function parseAspectRatio(ar: string): { width: number; height: number } | null {
const match = ar.match(/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/);
if (!match) return null;
const w = parseFloat(match[1]!);
const h = parseFloat(match[2]!);
if (w <= 0 || h <= 0) return null;
return { width: w, height: h };
}
function getOpenAISize(ar: string | null, quality: Quality): string {
const base = quality === "2k" ? 2048 : 1024;
if (!ar) return `${base}x${base}`;
const parsed = parseAspectRatio(ar);
if (!parsed) return `${base}x${base}`;
const ratio = parsed.width / parsed.height;
if (Math.abs(ratio - 1) < 0.1) return `${base}x${base}`;
if (ratio > 1.5) return quality === "2k" ? "2048x1024" : "1792x1024";
if (ratio < 0.67) return quality === "2k" ? "1024x2048" : "1024x1792";
return `${base}x${base}`;
}
async function readImageAsBase64(p: string): Promise<{ data: string; mimeType: string }> {
const buf = await readFile(p);
const ext = path.extname(p).toLowerCase();
let mimeType = "image/png";
if (ext === ".jpg" || ext === ".jpeg") mimeType = "image/jpeg";
else if (ext === ".gif") mimeType = "image/gif";
else if (ext === ".webp") mimeType = "image/webp";
return { data: buf.toString("base64"), mimeType };
}
async function generateWithGoogleMultimodal(
prompt: string,
model: string,
args: CliArgs
): Promise<Uint8Array> {
const { generateText } = await import("ai");
const { createGoogleGenerativeAI } = await import("@ai-sdk/google");
const google = createGoogleGenerativeAI({
apiKey: process.env.GOOGLE_API_KEY,
baseURL: process.env.GOOGLE_BASE_URL,
});
const fullPrompt = buildPromptWithAspect(prompt, args.aspectRatio, args.quality);
const messages: any[] = [];
const content: any[] = [];
for (const refPath of args.referenceImages) {
const { data, mimeType } = await readImageAsBase64(refPath);
content.push({ type: "image", image: data, mimeType });
}
content.push({ type: "text", text: fullPrompt });
messages.push({ role: "user", content });
const result = await generateText({
model: google(model, { useSearchGrounding: false }),
messages,
providerOptions: {
google: {
responseModalities: ["TEXT", "IMAGE"],
},
},
});
const files = (result as any).files;
if (!files || files.length === 0) {
const expRes = (result as any).response?.body?.candidates?.[0]?.content?.parts;
if (expRes) {
for (const part of expRes) {
if (part.inlineData?.data) {
return Uint8Array.from(Buffer.from(part.inlineData.data, "base64"));
}
}
}
throw new Error("No image in response");
}
const img = files[0];
if (img.uint8Array) return img.uint8Array;
if (img.base64) return Uint8Array.from(Buffer.from(img.base64, "base64"));
throw new Error("Cannot extract image data");
}
async function generateWithGoogleImagen(
prompt: string,
model: string,
args: CliArgs
): Promise<Uint8Array> {
const { experimental_generateImage: generateImage } = await import("ai");
const { createGoogleGenerativeAI } = await import("@ai-sdk/google");
const google = createGoogleGenerativeAI({
apiKey: process.env.GOOGLE_API_KEY,
baseURL: process.env.GOOGLE_BASE_URL,
});
const fullPrompt = buildPromptWithAspect(prompt, args.aspectRatio, args.quality);
const result = await generateImage({
model: google.image(model),
prompt: fullPrompt,
n: args.n,
aspectRatio: args.aspectRatio || undefined,
});
const img = result.images[0];
if (!img) throw new Error("No image in response");
if (img.uint8Array) return img.uint8Array;
if (img.base64) return Uint8Array.from(Buffer.from(img.base64, "base64"));
throw new Error("Cannot extract image data");
}
async function generateWithOpenAI(
prompt: string,
model: string,
args: CliArgs
): Promise<Uint8Array> {
const baseURL = process.env.OPENAI_BASE_URL || "https://api.openai.com/v1";
const apiKey = process.env.OPENAI_API_KEY;
if (!apiKey) throw new Error("OPENAI_API_KEY is required");
const size = args.size || getOpenAISize(args.aspectRatio, args.quality);
const body: Record<string, any> = {
model,
prompt,
size,
};
if (model.includes("dall-e-3")) {
body.quality = args.quality === "2k" ? "hd" : "standard";
}
const res = await fetch(`${baseURL}/images/generations`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify(body),
});
if (!res.ok) {
const err = await res.text();
throw new Error(`OpenAI API error: ${err}`);
}
const result = (await res.json()) as { data: Array<{ url?: string; b64_json?: string }> };
const img = result.data[0];
if (img?.b64_json) {
return Uint8Array.from(Buffer.from(img.b64_json, "base64"));
}
if (img?.url) {
const imgRes = await fetch(img.url);
if (!imgRes.ok) throw new Error("Failed to download image");
const buf = await imgRes.arrayBuffer();
return new Uint8Array(buf);
}
throw new Error("No image in response");
}
async function generate(
provider: Provider,
model: string,
prompt: string,
args: CliArgs
): Promise<Uint8Array> {
if (provider === "google") {
if (isGoogleMultimodal(model)) {
return generateWithGoogleMultimodal(prompt, model, args);
}
if (isGoogleImagen(model)) {
if (args.referenceImages.length > 0) {
console.error("Warning: Reference images not supported with Imagen models, ignoring.");
}
return generateWithGoogleImagen(prompt, model, args);
}
return generateWithGoogleMultimodal(prompt, model, args);
}
if (args.referenceImages.length > 0) {
console.error("Warning: Reference images not supported with OpenAI, ignoring.");
}
return generateWithOpenAI(prompt, model, args);
} }
async function main(): Promise<void> { async function main(): Promise<void> {
@@ -527,7 +295,8 @@ async function main(): Promise<void> {
} }
const provider = detectProvider(args); const provider = detectProvider(args);
const model = args.model || getDefaultModel(provider); const providerModule = await loadProviderModule(provider);
const model = args.model || providerModule.getDefaultModel();
const outputPath = normalizeOutputImagePath(args.imagePath); const outputPath = normalizeOutputImagePath(args.imagePath);
let imageData: Uint8Array; let imageData: Uint8Array;
@@ -535,7 +304,7 @@ async function main(): Promise<void> {
while (true) { while (true) {
try { try {
imageData = await generate(provider, model, prompt, args); imageData = await providerModule.generateImage(prompt, model, args);
break; break;
} catch (e) { } catch (e) {
if (!retried) { if (!retried) {
@@ -0,0 +1,229 @@
import path from "node:path";
import { readFile } from "node:fs/promises";
import type { CliArgs } from "../types";
const GOOGLE_MULTIMODAL_MODELS = ["gemini-3-pro-image-preview", "gemini-3-flash-preview"];
const GOOGLE_IMAGEN_MODELS = ["imagen-3.0-generate-002", "imagen-3.0-generate-001"];
export function getDefaultModel(): string {
return process.env.GOOGLE_IMAGE_MODEL || "gemini-3-pro-image-preview";
}
function normalizeGoogleModelId(model: string): string {
return model.startsWith("models/") ? model.slice("models/".length) : model;
}
function isGoogleMultimodal(model: string): boolean {
const normalized = normalizeGoogleModelId(model);
return GOOGLE_MULTIMODAL_MODELS.some((m) => normalized.includes(m));
}
function isGoogleImagen(model: string): boolean {
const normalized = normalizeGoogleModelId(model);
return GOOGLE_IMAGEN_MODELS.some((m) => normalized.includes(m));
}
function getGoogleApiKey(): string | null {
return process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY || null;
}
function getGoogleImageSize(args: CliArgs): "1K" | "2K" | "4K" {
if (args.imageSize) return args.imageSize as "1K" | "2K" | "4K";
return args.quality === "2k" ? "2K" : "1K";
}
function getGoogleBaseUrl(): string {
const base = process.env.GOOGLE_BASE_URL || "https://generativelanguage.googleapis.com";
return base.replace(/\/+$/g, "");
}
function buildGoogleUrl(pathname: string): string {
const base = getGoogleBaseUrl();
const cleanedPath = pathname.replace(/^\/+/g, "");
if (base.endsWith("/v1beta")) return `${base}/${cleanedPath}`;
return `${base}/v1beta/${cleanedPath}`;
}
function toModelPath(model: string): string {
const modelId = normalizeGoogleModelId(model);
return `models/${modelId}`;
}
async function postGoogleJson<T>(pathname: string, body: unknown): Promise<T> {
const apiKey = getGoogleApiKey();
if (!apiKey) throw new Error("GOOGLE_API_KEY or GEMINI_API_KEY is required");
const res = await fetch(buildGoogleUrl(pathname), {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-goog-api-key": apiKey,
},
body: JSON.stringify(body),
});
if (!res.ok) {
const err = await res.text();
throw new Error(`Google API error (${res.status}): ${err}`);
}
return (await res.json()) as T;
}
function buildPromptWithAspect(prompt: string, ar: string | null, quality: CliArgs["quality"]): string {
let result = prompt;
if (ar) {
result += ` Aspect ratio: ${ar}.`;
}
if (quality === "2k") {
result += " High resolution 2048px.";
}
return result;
}
function addAspectRatioToPrompt(prompt: string, ar: string | null): string {
if (!ar) return prompt;
return `${prompt} Aspect ratio: ${ar}.`;
}
async function readImageAsBase64(p: string): Promise<{ data: string; mimeType: string }> {
const buf = await readFile(p);
const ext = path.extname(p).toLowerCase();
let mimeType = "image/png";
if (ext === ".jpg" || ext === ".jpeg") mimeType = "image/jpeg";
else if (ext === ".gif") mimeType = "image/gif";
else if (ext === ".webp") mimeType = "image/webp";
return { data: buf.toString("base64"), mimeType };
}
function extractInlineImageData(response: {
candidates?: Array<{ content?: { parts?: Array<{ inlineData?: { data?: string } }> } }>;
}): string | null {
for (const candidate of response.candidates || []) {
for (const part of candidate.content?.parts || []) {
const data = part.inlineData?.data;
if (typeof data === "string" && data.length > 0) return data;
}
}
return null;
}
function extractPredictedImageData(response: {
predictions?: Array<any>;
generatedImages?: Array<any>;
}): string | null {
const candidates = [...(response.predictions || []), ...(response.generatedImages || [])];
for (const candidate of candidates) {
if (!candidate || typeof candidate !== "object") continue;
if (typeof candidate.imageBytes === "string") return candidate.imageBytes;
if (typeof candidate.bytesBase64Encoded === "string") return candidate.bytesBase64Encoded;
if (typeof candidate.data === "string") return candidate.data;
const image = candidate.image;
if (image && typeof image === "object") {
if (typeof image.imageBytes === "string") return image.imageBytes;
if (typeof image.bytesBase64Encoded === "string") return image.bytesBase64Encoded;
if (typeof image.data === "string") return image.data;
}
}
return null;
}
async function generateWithGemini(
prompt: string,
model: string,
args: CliArgs
): Promise<Uint8Array> {
const promptWithAspect = addAspectRatioToPrompt(prompt, args.aspectRatio);
const parts: Array<{ text?: string; inlineData?: { data: string; mimeType: string } }> = [];
for (const refPath of args.referenceImages) {
const { data, mimeType } = await readImageAsBase64(refPath);
parts.push({ inlineData: { data, mimeType } });
}
parts.push({ text: promptWithAspect });
const imageConfig: { imageSize: "1K" | "2K" | "4K" } = {
imageSize: getGoogleImageSize(args),
};
console.log("Generating image with Gemini...", imageConfig);
const response = await postGoogleJson<{
candidates?: Array<{ content?: { parts?: Array<{ inlineData?: { data?: string } }> } }>;
}>(`${toModelPath(model)}:generateContent`, {
contents: [
{
role: "user",
parts,
},
],
generationConfig: {
responseModalities: ["IMAGE"],
imageConfig,
},
});
console.log("Generation completed.");
const imageData = extractInlineImageData(response);
if (imageData) return Uint8Array.from(Buffer.from(imageData, "base64"));
throw new Error("No image in response");
}
async function generateWithImagen(
prompt: string,
model: string,
args: CliArgs
): Promise<Uint8Array> {
const fullPrompt = buildPromptWithAspect(prompt, args.aspectRatio, args.quality);
const imageSize = getGoogleImageSize(args);
if (imageSize === "4K") {
console.error("Warning: Imagen models do not support 4K imageSize, using 2K instead.");
}
const parameters: Record<string, unknown> = {
sampleCount: args.n,
};
if (args.aspectRatio) {
parameters.aspectRatio = args.aspectRatio;
}
if (imageSize === "1K" || imageSize === "2K") {
parameters.imageSize = imageSize;
} else {
parameters.imageSize = "2K";
}
const response = await postGoogleJson<{
predictions?: Array<any>;
generatedImages?: Array<any>;
}>(`${toModelPath(model)}:predict`, {
instances: [
{
prompt: fullPrompt,
},
],
parameters,
});
const imageData = extractPredictedImageData(response);
if (imageData) return Uint8Array.from(Buffer.from(imageData, "base64"));
throw new Error("No image in response");
}
export async function generateImage(
prompt: string,
model: string,
args: CliArgs
): Promise<Uint8Array> {
if (isGoogleImagen(model)) {
if (args.referenceImages.length > 0) {
console.error("Warning: Reference images not supported with Imagen models, ignoring.");
}
return generateWithImagen(prompt, model, args);
}
if (!isGoogleMultimodal(model) && args.referenceImages.length > 0) {
console.error("Warning: Reference images are only supported with Gemini multimodal models.");
}
return generateWithGemini(prompt, model, args);
}
@@ -0,0 +1,114 @@
import type { CliArgs } from "../types";
export function getDefaultModel(): string {
return process.env.OPENAI_IMAGE_MODEL || "gpt-image-1.5";
}
function parseAspectRatio(ar: string): { width: number; height: number } | null {
const match = ar.match(/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/);
if (!match) return null;
const w = parseFloat(match[1]!);
const h = parseFloat(match[2]!);
if (w <= 0 || h <= 0) return null;
return { width: w, height: h };
}
type SizeMapping = {
square: string;
landscape: string;
portrait: string;
};
function getOpenAISize(
model: string,
ar: string | null,
quality: CliArgs["quality"]
): string {
const isDalle3 = model.includes("dall-e-3");
const isDalle2 = model.includes("dall-e-2");
if (isDalle2) {
return "1024x1024";
}
const sizes: SizeMapping = isDalle3
? {
square: "1024x1024",
landscape: "1792x1024",
portrait: "1024x1792",
}
: {
square: "1024x1024",
landscape: "1536x1024",
portrait: "1024x1536",
};
if (!ar) return sizes.square;
const parsed = parseAspectRatio(ar);
if (!parsed) return sizes.square;
const ratio = parsed.width / parsed.height;
if (Math.abs(ratio - 1) < 0.1) return sizes.square;
if (ratio > 1.5) return sizes.landscape;
if (ratio < 0.67) return sizes.portrait;
return sizes.square;
}
export async function generateImage(
prompt: string,
model: string,
args: CliArgs
): Promise<Uint8Array> {
const baseURL = process.env.OPENAI_BASE_URL || "https://api.openai.com/v1";
const apiKey = process.env.OPENAI_API_KEY;
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 body: Record<string, any> = {
model,
prompt,
size,
};
if (model.includes("dall-e-3")) {
body.quality = args.quality === "2k" ? "hd" : "standard";
}
const res = await fetch(`${baseURL}/images/generations`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify(body),
});
if (!res.ok) {
const err = await res.text();
throw new Error(`OpenAI API error: ${err}`);
}
const result = (await res.json()) as { data: Array<{ url?: string; b64_json?: string }> };
const img = result.data[0];
if (img?.b64_json) {
return Uint8Array.from(Buffer.from(img.b64_json, "base64"));
}
if (img?.url) {
const imgRes = await fetch(img.url);
if (!imgRes.ok) throw new Error("Failed to download image");
const buf = await imgRes.arrayBuffer();
return new Uint8Array(buf);
}
throw new Error("No image in response");
}
+18
View File
@@ -0,0 +1,18 @@
export type Provider = "google" | "openai";
export type Quality = "normal" | "2k";
export type CliArgs = {
prompt: string | null;
promptFiles: string[];
imagePath: string | null;
provider: Provider | null;
model: string | null;
aspectRatio: string | null;
size: string | null;
quality: Quality;
imageSize: string | null;
referenceImages: string[];
n: number;
json: boolean;
help: boolean;
};
+75 -48
View File
@@ -1,84 +1,111 @@
--- ---
name: baoyu-post-to-wechat name: baoyu-post-to-wechat
description: Post content to WeChat Official Account (微信公众号). Supports both article posting (文章) and image-text posting (图文). description: Posts content to WeChat Official Account (微信公众号) via Chrome CDP automation. Supports article posting (文章) with full markdown formatting and image-text posting (图文) with multiple images. Use when user mentions "发布公众号", "post to wechat", "微信公众号", or "图文/文章".
--- ---
# Post to WeChat Official Account (微信公众号) # Post to WeChat Official Account
Post content to WeChat Official Account using Chrome CDP automation.
## Script Directory ## Script Directory
**Important**: All scripts are located in the `scripts/` subdirectory of this skill. **Agent Execution**: Determine this SKILL.md directory as `SKILL_DIR`, then use `${SKILL_DIR}/scripts/<name>.ts`.
**Agent Execution Instructions**:
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
3. Replace all `${SKILL_DIR}` in this document with the actual path
**Script Reference**:
| Script | Purpose | | Script | Purpose |
|--------|---------| |--------|---------|
| `scripts/wechat-browser.ts` | Image-text posts (图文) | | `scripts/wechat-browser.ts` | Image-text posts (图文) |
| `scripts/wechat-article.ts` | Full article posting (文章) | | `scripts/wechat-article.ts` | Article posting (文章) |
| `scripts/md-to-wechat.ts` | Markdown → WeChat HTML conversion | | `scripts/md-to-wechat.ts` | Markdown → WeChat HTML |
| `scripts/copy-to-clipboard.ts` | Copy content to clipboard |
| `scripts/paste-from-clipboard.ts` | Send real paste keystroke |
## Quick Usage ## Preferences (EXTEND.md)
### Image-Text (图文) - Multiple images with title/content Use Bash to check EXTEND.md existence (priority order):
```bash
# Check project-level first
test -f .baoyu-skills/baoyu-post-to-wechat/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md" && echo "user"
```
┌────────────────────────────────────────────────────────┬───────────────────┐
│ Path │ Location │
├────────────────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/baoyu-post-to-wechat/EXTEND.md │ Project directory │
├────────────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md │ User home │
└────────────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, apply settings │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Use defaults │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Default theme | Auto-submit preference | Chrome profile path
## Usage
### Image-Text (图文)
```bash ```bash
# From markdown file and image directory
npx -y bun ${SKILL_DIR}/scripts/wechat-browser.ts --markdown article.md --images ./images/ npx -y bun ${SKILL_DIR}/scripts/wechat-browser.ts --markdown article.md --images ./images/
npx -y bun ${SKILL_DIR}/scripts/wechat-browser.ts --title "标题" --content "内容" --image img.png --submit
# With explicit parameters
npx -y bun ${SKILL_DIR}/scripts/wechat-browser.ts --title "标题" --content "内容" --image img1.png --image img2.png --submit
``` ```
### Article (文章) - Full markdown with formatting ### Article (文章)
Before posting, ask user to choose a theme using AskUserQuestion:
| Theme | Description |
|-------|-------------|
| `default` | 经典主题 - 传统排版,标题居中带底边,二级标题白字彩底 |
| `grace` | 优雅主题 - 文字阴影,圆角卡片,精致引用块 (by @brzhang) |
| `simple` | 简洁主题 - 现代极简风,不对称圆角,清爽留白 (by @okooo5km) |
Default: `default`. If user has already specified a theme, skip the question.
**Workflow**:
1. Generate HTML preview and print the full `htmlPath` from JSON output so user can click to preview:
```bash ```bash
# Post markdown article npx -y bun ${SKILL_DIR}/scripts/md-to-wechat.ts article.md --theme <chosen-theme>
npx -y bun ${SKILL_DIR}/scripts/wechat-article.ts --markdown article.md --theme grace ```
2. Post to WeChat:
```bash
npx -y bun ${SKILL_DIR}/scripts/wechat-article.ts --markdown article.md --theme <chosen-theme>
``` ```
> **Note**: `${SKILL_DIR}` represents this skill's installation directory. Agent replaces with actual path at runtime. ## Detailed References
## References | Topic | Reference |
|-------|-----------|
| Image-text parameters, auto-compression | [references/image-text-posting.md](references/image-text-posting.md) |
| Article themes, image handling | [references/article-posting.md](references/article-posting.md) |
- **Image-Text Posting**: See `references/image-text-posting.md` for detailed image-text posting guide ## Feature Comparison
- **Article Posting**: See `references/article-posting.md` for detailed article posting guide
## Prerequisites
- Google Chrome installed
- `bun` runtime (via `npx -y bun`)
- First run: log in to WeChat Official Account in the opened browser window
## Features
| Feature | Image-Text | Article | | Feature | Image-Text | Article |
|---------|------------|---------| |---------|------------|---------|
| Multiple images | ✓ (up to 9) | ✓ (inline) | | Multiple images | ✓ (up to 9) | ✓ (inline) |
| Markdown support | Title/content extraction | Full formatting | | Markdown support | Title/content extraction | Full formatting |
| Auto title compression | ✓ (to 20 chars) | ✗ | | Auto compression | ✓ (title: 20, content: 1000 chars) | ✗ |
| Content compression | ✓ (to 1000 chars) | ✗ |
| Themes | ✗ | ✓ (default, grace, simple) | | Themes | ✗ | ✓ (default, grace, simple) |
## Prerequisites
- Google Chrome
- First run: log in to WeChat Official Account (session preserved)
## Troubleshooting ## Troubleshooting
- **Not logged in**: First run opens browser - scan QR code to log in, session is preserved | Issue | Solution |
- **Chrome not found**: Set `WECHAT_BROWSER_CHROME_PATH` environment variable |-------|----------|
- **Paste fails**: Check system clipboard permissions | Not logged in | First run opens browser - scan QR to log in |
| Chrome not found | Set `WECHAT_BROWSER_CHROME_PATH` env var |
| Paste fails | Check system clipboard permissions |
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/baoyu-post-to-wechat/EXTEND.md` (project)
2. `~/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md` (user)
If found, load before workflow. Extension content overrides defaults.
@@ -53,7 +53,7 @@ Regular paragraph with **bold** and *italic*.
## Image Handling ## Image Handling
1. **Parse**: Images in markdown are replaced with `[[IMAGE_PLACEHOLDER_N]]` 1. **Parse**: Images in markdown are replaced with `WECHATIMGPH_N`
2. **Render**: HTML is generated with placeholders in text 2. **Render**: HTML is generated with placeholders in text
3. **Paste**: HTML content is pasted into WeChat editor 3. **Paste**: HTML content is pasted into WeChat editor
4. **Replace**: For each placeholder: 4. **Replace**: For each placeholder:
@@ -81,7 +81,7 @@ Claude:
3. Opens Chrome, navigates to WeChat editor 3. Opens Chrome, navigates to WeChat editor
4. Pastes HTML content 4. Pastes HTML content
5. For each image: 5. For each image:
- Selects [[IMAGE_PLACEHOLDER_1]] - Selects WECHATIMGPH_1
- Scrolls into view - Scrolls into view
- Presses Backspace to delete - Presses Backspace to delete
- Pastes image - Pastes image
@@ -3,6 +3,7 @@ import path from 'node:path';
import { mkdir, writeFile } from 'node:fs/promises'; import { mkdir, writeFile } from 'node:fs/promises';
import os from 'node:os'; import os from 'node:os';
import { createHash } from 'node:crypto'; import { createHash } from 'node:crypto';
import { fileURLToPath } from 'node:url';
import https from 'node:https'; import https from 'node:https';
import http from 'node:http'; import http from 'node:http';
import { spawnSync } from 'node:child_process'; import { spawnSync } from 'node:child_process';
@@ -111,17 +112,11 @@ function parseFrontmatter(content: string): { frontmatter: Record<string, string
return { frontmatter, body: match[2]! }; return { frontmatter, body: match[2]! };
} }
async function parseMarkdownForWechat( export async function convertMarkdown(markdownPath: string, options?: { title?: string; theme?: string }): Promise<ParsedResult> {
markdownPath: string,
options?: { title?: string; theme?: string; tempDir?: string },
): Promise<ParsedResult> {
const content = fs.readFileSync(markdownPath, 'utf-8');
const baseDir = path.dirname(markdownPath); const baseDir = path.dirname(markdownPath);
const tempDir = options?.tempDir ?? path.join(os.tmpdir(), 'wechat-article-images'); const content = fs.readFileSync(markdownPath, 'utf-8');
const theme = options?.theme ?? 'default'; const theme = options?.theme ?? 'default';
await mkdir(tempDir, { recursive: true });
const { frontmatter, body } = parseFrontmatter(content); const { frontmatter, body } = parseFrontmatter(content);
let title = options?.title ?? frontmatter.title ?? ''; let title = options?.title ?? frontmatter.title ?? '';
@@ -129,9 +124,9 @@ async function parseMarkdownForWechat(
const h1Match = body.match(/^#\s+(.+)$/m); const h1Match = body.match(/^#\s+(.+)$/m);
if (h1Match) title = h1Match[1]!; if (h1Match) title = h1Match[1]!;
} }
if (!title) title = path.basename(markdownPath, path.extname(markdownPath));
const author = frontmatter.author ?? ''; const author = frontmatter.author || '';
let summary = frontmatter.summary ?? frontmatter.description ?? ''; let summary = frontmatter.description || frontmatter.summary || '';
if (!summary) { if (!summary) {
const lines = body.split('\n'); const lines = body.split('\n');
@@ -161,20 +156,23 @@ async function parseMarkdownForWechat(
let imageCounter = 0; let imageCounter = 0;
const modifiedBody = body.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (match, alt, src) => { const modifiedBody = body.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (match, alt, src) => {
const placeholder = `[[IMAGE_PLACEHOLDER_${++imageCounter}]]`; const placeholder = `WECHATIMGPH_${++imageCounter}`;
images.push({ src, placeholder }); images.push({ src, placeholder });
return placeholder; return placeholder;
}); });
const modifiedMarkdown = `---\n${Object.entries(frontmatter).map(([k, v]) => `${k}: ${v}`).join('\n')}\n---\n${modifiedBody}`; const modifiedMarkdown = `---\n${Object.entries(frontmatter).map(([k, v]) => `${k}: ${v}`).join('\n')}\n---\n${modifiedBody}`;
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-article-images-'));
const tempMdPath = path.join(tempDir, 'temp-article.md'); const tempMdPath = path.join(tempDir, 'temp-article.md');
await writeFile(tempMdPath, modifiedMarkdown, 'utf-8'); await writeFile(tempMdPath, modifiedMarkdown, 'utf-8');
const scriptDir = path.dirname(new URL(import.meta.url).pathname); const __filename = fileURLToPath(import.meta.url);
const renderScript = path.join(scriptDir, 'md', 'render.ts'); const __dirname = path.dirname(__filename);
const renderScript = path.join(__dirname, 'md', 'render.ts');
console.error(`[md-to-wechat] Rendering markdown with theme: ${theme}`); console.error(`[md-to-wechat] Rendering markdown with theme: ${theme}`);
const result = spawnSync('npx', ['-y', 'bun', renderScript, tempMdPath, '--theme', theme], { const result = spawnSync('npx', ['-y', 'bun', renderScript, tempMdPath, '--theme', theme], {
stdio: ['inherit', 'pipe', 'pipe'], stdio: ['inherit', 'pipe', 'pipe'],
cwd: baseDir, cwd: baseDir,
@@ -226,8 +224,8 @@ Output JSON format:
"htmlPath": "/tmp/wechat-article-images/temp-article.html", "htmlPath": "/tmp/wechat-article-images/temp-article.html",
"contentImages": [ "contentImages": [
{ {
"placeholder": "[[IMAGE_PLACEHOLDER_1]]", "placeholder": "WECHATIMGPH_1",
"localPath": "/tmp/wechat-article-images/img.png", "localPath": "/tmp/wechat-image/img.png",
"originalPath": "imgs/image.png" "originalPath": "imgs/image.png"
} }
] ]
@@ -262,7 +260,7 @@ async function main(): Promise<void> {
} }
if (!markdownPath) { if (!markdownPath) {
console.error('Error: Markdown file path required'); console.error('Error: Markdown file path is required');
process.exit(1); process.exit(1);
} }
@@ -271,7 +269,7 @@ async function main(): Promise<void> {
process.exit(1); process.exit(1);
} }
const result = await parseMarkdownForWechat(markdownPath, { title, theme }); const result = await convertMarkdown(markdownPath, { title, theme });
console.log(JSON.stringify(result, null, 2)); console.log(JSON.stringify(result, null, 2));
} }
@@ -2,6 +2,7 @@ import fs from 'node:fs';
import path from 'node:path'; import path from 'node:path';
import { spawnSync } from 'node:child_process'; import { spawnSync } from 'node:child_process';
import process from 'node:process'; import process from 'node:process';
import { fileURLToPath } from 'node:url';
import { launchChrome, getPageSession, waitForNewTab, clickElement, typeText, evaluate, sleep, type ChromeSession, type CdpConnection } from './cdp.ts'; import { launchChrome, getPageSession, waitForNewTab, clickElement, typeText, evaluate, sleep, type ChromeSession, type CdpConnection } from './cdp.ts';
const WECHAT_URL = 'https://mp.weixin.qq.com/'; const WECHAT_URL = 'https://mp.weixin.qq.com/';
@@ -65,8 +66,9 @@ async function clickMenuByText(session: ChromeSession, text: string): Promise<vo
} }
async function copyImageToClipboard(imagePath: string): Promise<void> { async function copyImageToClipboard(imagePath: string): Promise<void> {
const scriptDir = path.dirname(new URL(import.meta.url).pathname); const __filename = fileURLToPath(import.meta.url);
const copyScript = path.join(scriptDir, './copy-to-clipboard.ts'); const __dirname = path.dirname(__filename);
const copyScript = path.join(__dirname, './copy-to-clipboard.ts');
const result = spawnSync('npx', ['-y', 'bun', copyScript, 'image', imagePath], { stdio: 'inherit' }); const result = spawnSync('npx', ['-y', 'bun', copyScript, 'image', imagePath], { stdio: 'inherit' });
if (result.status !== 0) throw new Error(`Failed to copy image: ${imagePath}`); if (result.status !== 0) throw new Error(`Failed to copy image: ${imagePath}`);
} }
@@ -78,6 +80,30 @@ async function pasteInEditor(session: ChromeSession): Promise<void> {
await session.cdp.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'v', code: 'KeyV', modifiers, windowsVirtualKeyCode: 86 }, { sessionId: session.sessionId }); await session.cdp.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'v', code: 'KeyV', modifiers, windowsVirtualKeyCode: 86 }, { sessionId: session.sessionId });
} }
async function sendCopy(cdp?: CdpConnection, sessionId?: string): Promise<void> {
if (process.platform === 'darwin') {
spawnSync('osascript', ['-e', 'tell application "System Events" to keystroke "c" using command down']);
} else if (process.platform === 'linux') {
spawnSync('xdotool', ['key', 'ctrl+c']);
} else if (cdp && sessionId) {
await cdp.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'c', code: 'KeyC', modifiers: 2, windowsVirtualKeyCode: 67 }, { sessionId });
await sleep(50);
await cdp.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'c', code: 'KeyC', modifiers: 2, windowsVirtualKeyCode: 67 }, { sessionId });
}
}
async function sendPaste(cdp?: CdpConnection, sessionId?: string): Promise<void> {
if (process.platform === 'darwin') {
spawnSync('osascript', ['-e', 'tell application "System Events" to keystroke "v" using command down']);
} else if (process.platform === 'linux') {
spawnSync('xdotool', ['key', 'ctrl+v']);
} else if (cdp && sessionId) {
await cdp.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'v', code: 'KeyV', modifiers: 2, windowsVirtualKeyCode: 86 }, { sessionId });
await sleep(50);
await cdp.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'v', code: 'KeyV', modifiers: 2, windowsVirtualKeyCode: 86 }, { sessionId });
}
}
async function copyHtmlFromBrowser(cdp: CdpConnection, htmlFilePath: string): Promise<void> { async function copyHtmlFromBrowser(cdp: CdpConnection, htmlFilePath: string): Promise<void> {
const absolutePath = path.isAbsolute(htmlFilePath) ? htmlFilePath : path.resolve(process.cwd(), htmlFilePath); const absolutePath = path.isAbsolute(htmlFilePath) ? htmlFilePath : path.resolve(process.cwd(), htmlFilePath);
const fileUrl = `file://${absolutePath}`; const fileUrl = `file://${absolutePath}`;
@@ -108,30 +134,24 @@ async function copyHtmlFromBrowser(cdp: CdpConnection, htmlFilePath: string): Pr
}, { sessionId }); }, { sessionId });
await sleep(300); await sleep(300);
console.log('[wechat] Copying with system Cmd+C...'); console.log('[wechat] Copying content...');
if (process.platform === 'darwin') { await sendCopy(cdp, sessionId);
spawnSync('osascript', ['-e', 'tell application "System Events" to keystroke "c" using command down']);
} else {
spawnSync('xdotool', ['key', 'ctrl+c']);
}
await sleep(1000); await sleep(1000);
console.log('[wechat] Closing HTML tab...'); console.log('[wechat] Closing HTML tab...');
await cdp.send('Target.closeTarget', { targetId }); await cdp.send('Target.closeTarget', { targetId });
} }
async function pasteFromClipboardInEditor(): Promise<void> { async function pasteFromClipboardInEditor(session: ChromeSession): Promise<void> {
if (process.platform === 'darwin') { console.log('[wechat] Pasting content...');
spawnSync('osascript', ['-e', 'tell application "System Events" to keystroke "v" using command down']); await sendPaste(session.cdp, session.sessionId);
} else {
spawnSync('xdotool', ['key', 'ctrl+v']);
}
await sleep(1000); await sleep(1000);
} }
async function parseMarkdownWithPlaceholders(markdownPath: string, theme?: string): Promise<{ title: string; author: string; summary: string; htmlPath: string; contentImages: ImageInfo[] }> { async function parseMarkdownWithPlaceholders(markdownPath: string, theme?: string): Promise<{ title: string; author: string; summary: string; htmlPath: string; contentImages: ImageInfo[] }> {
const scriptDir = path.dirname(new URL(import.meta.url).pathname); const __filename = fileURLToPath(import.meta.url);
const mdToWechatScript = path.join(scriptDir, 'md-to-wechat.ts'); const __dirname = path.dirname(__filename);
const mdToWechatScript = path.join(__dirname, 'md-to-wechat.ts');
const args = ['-y', 'bun', mdToWechatScript, markdownPath]; const args = ['-y', 'bun', mdToWechatScript, markdownPath];
if (theme) args.push('--theme', theme); if (theme) args.push('--theme', theme);
@@ -295,6 +315,10 @@ export async function postArticle(options: ArticleOptions): Promise<void> {
console.log('[wechat] Clicking on editor...'); console.log('[wechat] Clicking on editor...');
await clickElement(session, '.ProseMirror'); await clickElement(session, '.ProseMirror');
await sleep(1000);
console.log('[wechat] Ensuring editor focus...');
await clickElement(session, '.ProseMirror');
await sleep(500); await sleep(500);
if (effectiveHtmlFile && fs.existsSync(effectiveHtmlFile)) { if (effectiveHtmlFile && fs.existsSync(effectiveHtmlFile)) {
@@ -302,7 +326,7 @@ export async function postArticle(options: ArticleOptions): Promise<void> {
await copyHtmlFromBrowser(cdp, effectiveHtmlFile); await copyHtmlFromBrowser(cdp, effectiveHtmlFile);
await sleep(500); await sleep(500);
console.log('[wechat] Pasting into editor...'); console.log('[wechat] Pasting into editor...');
await pasteFromClipboardInEditor(); await pasteFromClipboardInEditor(session);
await sleep(3000); await sleep(3000);
if (contentImages.length > 0) { if (contentImages.length > 0) {
@@ -328,7 +352,7 @@ export async function postArticle(options: ArticleOptions): Promise<void> {
await sleep(200); await sleep(200);
console.log('[wechat] Pasting image...'); console.log('[wechat] Pasting image...');
await pasteFromClipboardInEditor(); await pasteFromClipboardInEditor(session);
await sleep(3000); await sleep(3000);
} }
console.log('[wechat] All images inserted.'); console.log('[wechat] All images inserted.');
+68 -71
View File
@@ -1,11 +1,11 @@
--- ---
name: baoyu-post-to-x name: baoyu-post-to-x
description: Post content and articles to X (Twitter). Supports regular posts with images/videos and X Articles (long-form Markdown). Uses real Chrome with CDP to bypass anti-automation. description: Posts content and articles to X (Twitter). Supports regular posts with images/videos and X Articles (long-form Markdown). Uses real Chrome with CDP to bypass anti-automation. Use when user asks to "post to X", "tweet", "publish to Twitter", or "share on X".
--- ---
# Post to X (Twitter) # Post to X (Twitter)
Post content, images, videos, and long-form articles to X using real Chrome browser (bypasses anti-bot detection). Posts text, images, videos, and long-form articles to X via real Chrome browser (bypasses anti-bot detection).
## Script Directory ## Script Directory
@@ -27,11 +27,41 @@ Post content, images, videos, and long-form articles to X using real Chrome brow
| `scripts/copy-to-clipboard.ts` | Copy content to clipboard | | `scripts/copy-to-clipboard.ts` | Copy content to clipboard |
| `scripts/paste-from-clipboard.ts` | Send real paste keystroke | | `scripts/paste-from-clipboard.ts` | Send real paste keystroke |
## Preferences (EXTEND.md)
Use Bash to check EXTEND.md existence (priority order):
```bash
# Check project-level first
test -f .baoyu-skills/baoyu-post-to-x/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/baoyu-post-to-x/EXTEND.md" && echo "user"
```
┌──────────────────────────────────────────────────┬───────────────────┐
│ Path │ Location │
├──────────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/baoyu-post-to-x/EXTEND.md │ Project directory │
├──────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-post-to-x/EXTEND.md │ User home │
└──────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, apply settings │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Use defaults │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Default Chrome profile | Auto-submit preference
## Prerequisites ## Prerequisites
- Google Chrome or Chromium installed - Google Chrome or Chromium
- `bun` installed (for running scripts) - `bun` runtime
- First run: log in to X in the opened browser window - First run: log in to X manually (session saved)
## References ## References
@@ -45,72 +75,57 @@ Post content, images, videos, and long-form articles to X using real Chrome brow
Text + up to 4 images. Text + up to 4 images.
```bash ```bash
# Preview mode (doesn't post) npx -y bun ${SKILL_DIR}/scripts/x-browser.ts "Hello!" --image ./photo.png # Preview
npx -y bun ${SKILL_DIR}/scripts/x-browser.ts "Hello from Claude!" --image ./screenshot.png npx -y bun ${SKILL_DIR}/scripts/x-browser.ts "Hello!" --image ./photo.png --submit # Post
# Actually post
npx -y bun ${SKILL_DIR}/scripts/x-browser.ts "Hello!" --image ./photo.png --submit
``` ```
> **Note**: `${SKILL_DIR}` represents this skill's installation directory. Agent replaces with actual path at runtime.
**Parameters**: **Parameters**:
| Parameter | Description | | Parameter | Description |
|-----------|-------------| |-----------|-------------|
| `<text>` | Post content (positional argument) | | `<text>` | Post content (positional) |
| `--image <path>` | Image file path (can be repeated, max 4) | | `--image <path>` | Image file (repeatable, max 4) |
| `--submit` | Actually post (default: preview only) | | `--submit` | Post (default: preview) |
| `--profile <dir>` | Custom Chrome profile directory | | `--profile <dir>` | Custom Chrome profile |
--- ---
## Video Posts ## Video Posts
Text + video file (MP4, MOV, WebM). Text + video file.
```bash ```bash
# Preview mode (doesn't post) npx -y bun ${SKILL_DIR}/scripts/x-video.ts "Check this out!" --video ./clip.mp4 # Preview
npx -y bun ${SKILL_DIR}/scripts/x-video.ts "Check out this video!" --video ./clip.mp4 npx -y bun ${SKILL_DIR}/scripts/x-video.ts "Amazing content" --video ./demo.mp4 --submit # Post
# Actually post
npx -y bun ${SKILL_DIR}/scripts/x-video.ts "Amazing content" --video ./demo.mp4 --submit
``` ```
**Parameters**: **Parameters**:
| Parameter | Description | | Parameter | Description |
|-----------|-------------| |-----------|-------------|
| `<text>` | Post content (positional argument) | | `<text>` | Post content (positional) |
| `--video <path>` | Video file path (required) | | `--video <path>` | Video file (MP4, MOV, WebM) |
| `--submit` | Actually post (default: preview only) | | `--submit` | Post (default: preview) |
| `--profile <dir>` | Custom Chrome profile directory | | `--profile <dir>` | Custom Chrome profile |
**Video Limits**: **Limits**: Regular 140s max, Premium 60min. Processing: 30-60s.
- Regular accounts: 140 seconds max
- X Premium: up to 60 minutes
- Supported formats: MP4, MOV, WebM
- Processing time: 30-60 seconds depending on file size
--- ---
## Quote Tweets ## Quote Tweets
Quote an existing tweet with your comment - a way to share content while giving credit to the original creator. Quote an existing tweet with comment.
```bash ```bash
# Preview mode (doesn't post) npx -y bun ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123 "Great insight!" # Preview
npx -y bun ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123456789 "Great insight!" npx -y bun ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123 "I agree!" --submit # Post
# Actually post
npx -y bun ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123456789 "I agree!" --submit
``` ```
**Parameters**: **Parameters**:
| Parameter | Description | | Parameter | Description |
|-----------|-------------| |-----------|-------------|
| `<tweet-url>` | URL of the tweet to quote (positional argument) | | `<tweet-url>` | URL to quote (positional) |
| `<comment>` | Your comment text (positional argument, optional) | | `<comment>` | Comment text (positional, optional) |
| `--submit` | Actually post (default: preview only) | | `--submit` | Post (default: preview) |
| `--profile <dir>` | Custom Chrome profile directory | | `--profile <dir>` | Custom Chrome profile |
--- ---
@@ -119,47 +134,29 @@ npx -y bun ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123456789 "
Long-form Markdown articles (requires X Premium). Long-form Markdown articles (requires X Premium).
```bash ```bash
# Preview mode npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md # Preview
npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg # With cover
npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md --submit # Publish
# With cover image
npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg
# Publish
npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md --submit
``` ```
**Parameters**: **Parameters**:
| Parameter | Description | | Parameter | Description |
|-----------|-------------| |-----------|-------------|
| `<markdown>` | Markdown file path (positional argument) | | `<markdown>` | Markdown file (positional) |
| `--cover <path>` | Cover image path | | `--cover <path>` | Cover image |
| `--title <text>` | Override article title | | `--title <text>` | Override title |
| `--submit` | Actually publish (default: preview only) | | `--submit` | Publish (default: preview) |
**Frontmatter** (optional): **Frontmatter**: `title`, `cover_image` supported in YAML front matter.
```yaml
---
title: My Article Title
cover_image: /path/to/cover.jpg
---
```
--- ---
## Notes ## Notes
- First run requires manual login (session is saved) - First run: manual login required (session persists)
- Always preview before using `--submit` - Always preview before `--submit`
- Browser closes automatically after operation - Cross-platform: macOS, Linux, Windows
- Supports macOS, Linux, and Windows
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/baoyu-post-to-x/EXTEND.md` (project)
2. `~/.baoyu-skills/baoyu-post-to-x/EXTEND.md` (user)
If found, load before workflow. Extension content overrides defaults.
@@ -67,7 +67,7 @@ Code blocks become blockquotes (X doesn't support code)
1. **Cover Image**: First image or `cover_image` from frontmatter 1. **Cover Image**: First image or `cover_image` from frontmatter
2. **Remote Images**: Automatically downloaded to temp directory 2. **Remote Images**: Automatically downloaded to temp directory
3. **Placeholders**: Images in content use `[[IMAGE_PLACEHOLDER_N]]` format 3. **Placeholders**: Images in content use `XIMGPH_N` format
4. **Insertion**: Placeholders are found, selected, and replaced with actual images 4. **Insertion**: Placeholders are found, selected, and replaced with actual images
## Markdown to HTML Script ## Markdown to HTML Script
@@ -92,7 +92,7 @@ JSON output:
"coverImage": "/path/to/cover.jpg", "coverImage": "/path/to/cover.jpg",
"contentImages": [ "contentImages": [
{ {
"placeholder": "[[IMAGE_PLACEHOLDER_1]]", "placeholder": "XIMGPH_1",
"localPath": "/tmp/x-article-images/img.png", "localPath": "/tmp/x-article-images/img.png",
"blockIndex": 5 "blockIndex": 5
} }
+5 -5
View File
@@ -280,7 +280,7 @@ export async function parseMarkdown(
let imageCounter = 0; let imageCounter = 0;
const { html, totalBlocks } = convertMarkdownToHtml(body, (src, alt) => { const { html, totalBlocks } = convertMarkdownToHtml(body, (src, alt) => {
const placeholder = `[[IMAGE_PLACEHOLDER_${++imageCounter}]]`; const placeholder = `XIMGPH_${++imageCounter}`;
const currentBlockIndex = images.length; // Will be set properly after HTML generation const currentBlockIndex = images.length; // Will be set properly after HTML generation
images.push({ src, alt, blockIndex: -1 }); // blockIndex set later images.push({ src, alt, blockIndex: -1 }); // blockIndex set later
@@ -292,7 +292,7 @@ export async function parseMarkdown(
let blockIdx = 0; let blockIdx = 0;
for (const line of htmlLines) { for (const line of htmlLines) {
for (let i = 0; i < images.length; i++) { for (let i = 0; i < images.length; i++) {
const placeholder = `[[IMAGE_PLACEHOLDER_${i + 1}]]`; const placeholder = `XIMGPH_${i + 1}`;
if (line.includes(placeholder)) { if (line.includes(placeholder)) {
images[i]!.blockIndex = blockIdx; images[i]!.blockIndex = blockIdx;
} }
@@ -312,7 +312,7 @@ export async function parseMarkdown(
// First image becomes cover if no cover specified // First image becomes cover if no cover specified
if (isFirstImage && !coverImagePath) { if (isFirstImage && !coverImagePath) {
coverImagePath = localPath; coverImagePath = localPath;
coverPlaceholder = `[[IMAGE_PLACEHOLDER_${i + 1}]]`; coverPlaceholder = `XIMGPH_${i + 1}`;
isFirstImage = false; isFirstImage = false;
// Don't add to contentImages, it's the cover // Don't add to contentImages, it's the cover
continue; continue;
@@ -320,7 +320,7 @@ export async function parseMarkdown(
isFirstImage = false; isFirstImage = false;
contentImages.push({ contentImages.push({
placeholder: `[[IMAGE_PLACEHOLDER_${i + 1}]]`, placeholder: `XIMGPH_${i + 1}`,
localPath, localPath,
originalPath: img.src, originalPath: img.src,
blockIndex: img.blockIndex, blockIndex: img.blockIndex,
@@ -331,7 +331,7 @@ export async function parseMarkdown(
let finalHtml = html; let finalHtml = html;
if (coverPlaceholder) { if (coverPlaceholder) {
// Remove the placeholder and its containing <p> tag // Remove the placeholder and its containing <p> tag
finalHtml = finalHtml.replace(new RegExp(`<p>${coverPlaceholder.replace(/[[\]]/g, '\\$&')}</p>\\n?`, 'g'), ''); finalHtml = finalHtml.replace(new RegExp(`<p>${coverPlaceholder}</p>\\n?`, 'g'), '');
} }
// Resolve cover image path // Resolve cover image path
File diff suppressed because it is too large Load Diff
@@ -52,8 +52,33 @@ You are "The Architect" - a master visual storyteller creating presentation slid
## STYLE_INSTRUCTIONS ## STYLE_INSTRUCTIONS
[Insert style-specific instructions here] [Extract from outline.md - do NOT re-read style files]
The STYLE_INSTRUCTIONS block from the outline contains:
- Design Aesthetic
- Background (Texture + Base Color)
- Typography (Headlines + Body descriptions)
- Color Palette (with hex codes)
- Visual Elements
- Density Guidelines
- Style Rules (Do/Don't)
Copy the entire `<STYLE_INSTRUCTIONS>...</STYLE_INSTRUCTIONS>` block from the outline here.
--- ---
Please use nano banana pro to generate the slide image based on the content provided below: ## SLIDE CONTENT
[Insert slide-specific content from outline]
Include:
- Slide number and filename
- Type (Cover/Content/Back Cover)
- Narrative Goal
- Key Content (Headline, Sub-headline, Body points)
- Visual description
- Layout guidance (if specified)
---
Please use nano banana pro to generate the slide image based on the content provided above.
@@ -0,0 +1,125 @@
# EXTEND.md Schema
Structure for user preferences in `.baoyu-skills/baoyu-slide-deck/EXTEND.md`.
## Full Schema
```yaml
# Slide Deck Preferences
## Defaults
style: blueprint # Preset name OR "custom"
audience: general # beginners | intermediate | experts | executives | general
language: auto # auto | en | zh | ja | etc.
review: true # true = review outline before generation
## Custom Dimensions (only when style: custom)
dimensions:
texture: clean # clean | grid | organic | pixel | paper
mood: professional # professional | warm | cool | vibrant | dark | neutral
typography: geometric # geometric | humanist | handwritten | editorial | technical
density: balanced # minimal | balanced | dense
## Custom Styles (optional)
custom_styles:
my-style:
texture: organic
mood: warm
typography: humanist
density: minimal
description: "My custom warm and friendly style"
```
## Field Descriptions
### Defaults
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `style` | string | `blueprint` | Preset name, `custom`, or custom style name |
| `audience` | string | `general` | Default target audience |
| `language` | string | `auto` | Output language (auto = detect from input) |
| `review` | boolean | `true` | Show outline review before generation |
### Custom Dimensions
Only used when `style: custom`. Defines dimension values directly.
| Field | Options | Default |
|-------|---------|---------|
| `texture` | clean, grid, organic, pixel, paper | clean |
| `mood` | professional, warm, cool, vibrant, dark, neutral | professional |
| `typography` | geometric, humanist, handwritten, editorial, technical | geometric |
| `density` | minimal, balanced, dense | balanced |
### Custom Styles
Define reusable custom dimension combinations.
```yaml
custom_styles:
style-name:
texture: <texture>
mood: <mood>
typography: <typography>
density: <density>
description: "Optional description"
```
Then use with: `/baoyu-slide-deck content.md --style style-name`
## Minimal Examples
### Just change default style
```yaml
style: sketch-notes
```
### Prefer no reviews
```yaml
review: false
```
### Custom default dimensions
```yaml
style: custom
dimensions:
texture: organic
mood: professional
typography: humanist
density: minimal
```
### Define reusable custom style
```yaml
custom_styles:
brand-style:
texture: clean
mood: vibrant
typography: editorial
density: balanced
description: "Company brand style"
```
## File Locations
Priority order (first found wins):
1. `.baoyu-skills/baoyu-slide-deck/EXTEND.md` (project)
2. `$HOME/.baoyu-skills/baoyu-slide-deck/EXTEND.md` (user)
## First-Time Setup
When no EXTEND.md exists, the skill prompts for initial preferences:
1. Preferred style (preset or custom)
2. Default audience
3. Language preference
4. Review preference
5. Save location (project or user)
Creates EXTEND.md at chosen location.
@@ -0,0 +1,208 @@
# Design Guidelines
Detailed design principles for slide decks.
## Audience Guidelines
Design decisions adapt to target audience. Use `--audience` to set.
| Audience | Content Density | Visual Style | Terminology | Slides |
|----------|-----------------|--------------|-------------|--------|
| `beginners` | Low | Friendly, illustrative | Plain language | 8-15 |
| `intermediate` | Medium | Balanced, structured | Some jargon OK | 10-20 |
| `experts` | High | Data-rich, precise | Technical terms | 12-25 |
| `executives` | Low-Medium | Clean, impactful | Business language | 8-12 |
| `general` | Medium | Accessible, engaging | Minimal jargon | 10-18 |
### Audience → Density Mapping
Recommended density dimension based on audience:
| Audience | Recommended Density | Rationale |
|----------|-------------------|-----------|
| `executives` | minimal | One insight per slide, respect time |
| `beginners` | minimal → balanced | Single concepts, build understanding |
| `general` | balanced | Accessible but informative |
| `intermediate` | balanced | Standard information density |
| `experts` | balanced → dense | Can handle more data per slide |
**Automatic Density Selection**:
- If `--audience executives` → default to `minimal` density
- If `--audience beginners` → default to `minimal` or `balanced`
- If `--audience experts` → allow `dense` density
- Otherwise → default to `balanced`
### Audience-Specific Principles
**Beginners**:
- One concept per slide
- Visual metaphors over abstract diagrams
- Step-by-step progression
- Generous whitespace
**Experts**:
- Multiple data points per slide acceptable
- Technical diagrams with precise labels
- Assume domain knowledge
- Dense but organized information
**Executives**:
- Lead with insights, not data
- "So what?" on every slide
- Decision-enabling content
- Bottom-line upfront (BLUF)
## Visual Hierarchy Principles
| Principle | Description |
|-----------|-------------|
| Focal Point | ONE dominant element per slide draws attention first |
| Rule of Thirds | Position key elements at grid intersections |
| Z-Pattern | Guide eye: top-left → top-right → bottom-left → bottom-right |
| Size Contrast | Headlines 2-3x larger than body text |
| Breathing Room | Minimum 10% margin from all edges |
## Content Density
See `references/dimensions/density.md` for full density dimension specs.
| Level | Description | Use When |
|-------|-------------|----------|
| High | Multiple data points, detailed charts, dense text | Expert audience, technical reviews |
| Medium | Key points with supporting details | General business, mixed audiences |
| Low | One main idea, large visuals, minimal text | Beginners, keynotes, emotional impact |
**High-Density Principles** (McKinsey-style):
- Every element earns its space
- Data speaks louder than decoration
- Annotations explain insights, not describe data
- White space is strategic, not filler
**Density by Slide Type**:
| Slide Type | Recommended Density |
|------------|-------------------|
| Cover/Title | minimal |
| Agenda/Overview | balanced |
| Content/Analysis | balanced or dense |
| Data/Metrics | dense |
| Quote/Impact | minimal |
| Summary/Takeaway | balanced |
## Color Selection
See `references/dimensions/mood.md` for full mood dimension specs.
**Content-First Approach**:
1. Analyze content topic, mood, and industry
2. Consider target audience expectations
3. Match palette to subject matter
4. Ensure strong contrast for readability
**Quick Palette Guide**:
| Content Type | Recommended Mood |
|--------------|-----------------|
| Technical/Architecture | cool |
| Educational/Friendly | warm |
| Corporate/Professional | professional |
| Creative/Artistic | vibrant |
| Scientific/Medical | cool or neutral |
| Entertainment/Gaming | dark or vibrant |
## Typography Principles
See `references/dimensions/typography.md` for full typography dimension specs.
| Element | Treatment |
|---------|-----------|
| Headlines | Bold, 2-3x body size, narrative style |
| Body Text | Regular weight, readable size |
| Captions | Smaller, lighter weight |
| Data Labels | Monospace for technical content |
| Emphasis | Use bold or color, not underlines |
## Font Recommendations
**English Fonts**:
| Font | Style | Best For |
|------|-------|----------|
| Liter | Sans-serif, geometric | Modern, clean, technical |
| HedvigLettersSans | Sans-serif, distinctive | Brand-forward, creative |
| Oranienbaum | High-contrast serif | Elegant, classical |
| SortsMillGoudy | Classical serif | Traditional, readable |
| Coda | Round sans-serif | Friendly, approachable |
**Chinese Fonts**:
| Font | Style | Best For |
|------|-------|----------|
| MiSans | Modern sans-serif | Clean, versatile, screen-optimized |
| Noto Sans SC | Neutral sans-serif | Standard, multilingual |
| siyuanSongti | Refined Song typeface | Elegant, editorial |
| alimamashuheiti | Geometric sans-serif | Commercial, structured |
| LXGW Bright | Song-Kai hybrid | Warm, readable |
**Multilingual Pairing**:
| Use Case | English | Chinese |
|----------|---------|---------|
| Technical | Liter | MiSans |
| Editorial | Oranienbaum | siyuanSongti |
| Friendly | Coda | LXGW Bright |
| Corporate | HedvigLettersSans | alimamashuheiti |
## Visual Elements Reference
See `references/dimensions/texture.md` for full texture dimension specs.
### Background Treatments
| Treatment | Description | Best For |
|-----------|-------------|----------|
| Solid color | Single background color | Clean, minimal |
| Split background | Two colors, diagonal or vertical | Contrast, sections |
| Gradient | Subtle vertical or diagonal fade | Modern, dynamic |
| Textured | Pattern or texture overlay | Character, style |
### Typography Treatments
| Treatment | Description | Best For |
|-----------|-------------|----------|
| Size contrast | 3-4x difference headline vs body | Impact, hierarchy |
| All-caps headers | Uppercase with letter spacing | Authority, structure |
| Monospace data | Fixed-width for numbers/code | Technical, precision |
| Hand-drawn | Organic, imperfect letterforms | Friendly, approachable |
### Geometric Accents
| Element | Description | Best For |
|---------|-------------|----------|
| Diagonal dividers | Angled section separators | Energy, movement |
| Corner brackets | L-shaped frames | Focus, framing |
| Circles/hexagons | Shape frames for images | Modern, tech |
| Underline accents | Thick lines under headers | Emphasis, hierarchy |
## Consistency Requirements
| Element | Guideline |
|---------|-----------|
| Spacing | Consistent margins and padding throughout |
| Colors | Maximum 3-4 colors per slide, palette consistent across deck |
| Typography | Same font families and sizes for same content types |
| Visual Language | Repeat patterns, shapes, and treatments |
## Dimension Combination Guide
When combining dimensions, consider compatibility:
| Audience | Recommended Dimensions |
|----------|----------------------|
| Executives | clean + neutral + geometric + minimal |
| Beginners | organic + warm + humanist + minimal |
| General | any texture + any mood + humanist/geometric + balanced |
| Experts | grid/clean + cool + technical + balanced/dense |
| Content Type | Recommended Dimensions |
|--------------|----------------------|
| Tutorial | organic + warm + handwritten + balanced |
| Technical | grid + cool + technical + balanced |
| Business | clean + professional + geometric + balanced |
| Creative | organic + vibrant + humanist + balanced |
| Data-heavy | clean + cool + technical + dense |
@@ -0,0 +1,118 @@
# Density Dimension
Information density per slide.
## Options
| Option | Content/Slide | Whitespace | Best For |
|--------|---------------|------------|----------|
| `minimal` | One focus point | Maximum | Executive briefings, keynotes, emotional impact |
| `balanced` | 2-3 key points | Standard | General presentations, mixed audiences |
| `dense` | Multiple data points | Compact | Data-heavy, technical reviews, detailed analysis |
## Rendering Guidelines
### minimal
- ONE main idea per slide
- Large visuals dominate
- Minimal text (headline + 1-2 lines max)
- Generous margins (15%+ from edges)
- Maximum breathing room between elements
- Let single element carry full weight
**Principles**:
- "One slide, one message"
- Visual > text
- Empty space is intentional
- Every element must earn its space
### balanced
- 2-3 key points per slide
- Standard margins (10% from edges)
- Balanced text/visual ratio
- Clear hierarchy with supporting details
- Comfortable reading experience
**Principles**:
- Primary point + supporting context
- Visuals complement text
- Structured but not crowded
- Good for diverse audiences
### dense
- Multiple data points acceptable
- Compact margins (5-8% from edges)
- Information-rich layouts
- Charts, tables, detailed annotations
- Assume engaged, attentive audience
**Principles**:
- Data speaks louder than decoration
- Annotations explain insights
- White space is strategic
- Every pixel serves a purpose
## Audience → Density Mapping
| Audience | Recommended Density |
|----------|-------------------|
| Executives | minimal |
| Beginners | minimal to balanced |
| General | balanced |
| Intermediate | balanced |
| Experts | balanced to dense |
## Slide Type → Density Guidelines
| Slide Type | Recommended Density |
|------------|-------------------|
| Cover/Title | minimal |
| Section break | minimal |
| Quote/Impact | minimal |
| Agenda/Overview | balanced |
| Content/Analysis | balanced or dense |
| Summary/Takeaway | balanced |
| Data/Metrics | dense |
## Content Guidelines Per Density
### minimal
| Element | Guideline |
|---------|-----------|
| Headlines | Large (40-60pt equivalent) |
| Body text | Minimal or none |
| Bullet points | 0-2 max |
| Visual elements | 1 dominant element |
| Charts/Data | 1 key stat only |
### balanced
| Element | Guideline |
|---------|-----------|
| Headlines | Medium-large (32-48pt equivalent) |
| Body text | 2-4 lines |
| Bullet points | 2-4 |
| Visual elements | 1-2 elements |
| Charts/Data | Simple charts OK |
### dense
| Element | Guideline |
|---------|-----------|
| Headlines | Medium (24-36pt equivalent) |
| Body text | Multiple paragraphs OK |
| Bullet points | 4-6+ |
| Visual elements | Multiple allowed |
| Charts/Data | Complex charts, tables OK |
## Combination Notes
| Density | Works Best With | Avoid With |
|---------|-----------------|------------|
| minimal | neutral mood, geometric typography | dense data content |
| balanced | any mood/typography | extremes (too sparse or too packed) |
| dense | cool mood, technical typography | handwritten typography, organic texture |
@@ -0,0 +1,135 @@
# Mood Dimension
Color temperature and palette style.
## Options
| Option | Color Temperature | Palette Style | Best For |
|--------|-------------------|---------------|----------|
| `professional` | Cool-neutral | Navy, gold, structured grays | Business, investor, corporate |
| `warm` | Warm | Earth tones, oranges, natural colors | Education, friendly, approachable |
| `cool` | Cool | Blues, grays, cyan, teal | Technical, data, analytical |
| `vibrant` | Varied | High saturation, bold colors | Marketing, creative, attention-grabbing |
| `dark` | Dark | Deep backgrounds with bright accents | Entertainment, gaming, atmospheric |
| `neutral` | Neutral | Minimal color, grayscale focus | Executive, minimal, sophisticated |
## Palette Specifications
### professional
```
Background: #FFFFFF (Pure White)
Primary Text: #1E3A5F (Navy)
Secondary Text: #4A5568 (Dark Gray)
Accent 1: #C9A227 (Gold)
Accent 2: #3D5A80 (Light Navy)
```
### warm
```
Background: #FAF8F0 (Warm Off-White)
Primary Text: #2C3E50 (Deep Charcoal)
Secondary Text: #4A4A4A (Deep Brown)
Accent 1: #F4A261 (Soft Orange)
Accent 2: #E9C46A (Mustard Yellow)
Accent 3: #87A96B (Sage Green)
```
### cool
```
Background: #FAF8F5 (Blueprint Off-White)
Primary Text: #334155 (Deep Slate)
Secondary Text: #64748B (Slate Gray)
Accent 1: #2563EB (Engineering Blue)
Accent 2: #1E3A5F (Navy Blue)
Accent 3: #BFDBFE (Light Blue)
```
### vibrant
```
Background: #FFFFFF or #1A1A2E (Light or Dark)
Primary Text: #1A1A2E or #FFFFFF
Accent 1: #E94560 (Coral Red)
Accent 2: #0F3460 (Deep Blue)
Accent 3: #16C79A (Teal Green)
Accent 4: #F9B208 (Golden Yellow)
```
### dark
```
Background: #0D1117 (Deep Black)
Primary Text: #E6EDF3 (Soft White)
Secondary Text: #8B949E (Muted Gray)
Accent 1: #58A6FF (Bright Blue)
Accent 2: #7EE787 (Bright Green)
Accent 3: #FF7B72 (Coral)
```
### neutral
```
Background: #FFFFFF (Pure White)
Primary Text: #18181B (Near Black)
Secondary Text: #71717A (Medium Gray)
Accent 1: #18181B (Black)
Accent 2: #A1A1AA (Light Gray)
```
## Rendering Guidelines
### professional
- Restrained use of accent colors
- Gold for emphasis only
- Clean, institutional feel
- Balanced contrast
### warm
- Generous use of warm tones
- Natural, approachable colors
- Soft transitions between colors
- Welcoming atmosphere
### cool
- Blue-dominant palette
- Technical precision in color use
- High contrast for clarity
- Analytical, trustworthy feel
### vibrant
- Bold color combinations
- High saturation throughout
- Dynamic color contrasts
- Energetic visual presence
### dark
- Deep backgrounds dominate
- Accent colors pop against dark
- Glowing/luminous effects
- Cinematic atmosphere
### neutral
- Minimal color usage
- Typography carries weight
- Grayscale hierarchy
- Maximum sophistication
## Combination Notes
| Mood | Works Best With | Avoid With |
|------|-----------------|------------|
| professional | clean texture, geometric typography | organic texture, handwritten |
| warm | organic texture, humanist typography | pixel texture, minimal density |
| cool | grid texture, technical typography | paper texture, handwritten |
| vibrant | pixel/organic texture, editorial typography | neutral mood overlaps |
| dark | clean/pixel texture, technical typography | paper texture |
| neutral | clean texture, geometric typography | organic texture, vibrant elements |
@@ -0,0 +1,126 @@
# Preset → Dimension Mapping
Maps 16 preset styles to their dimension combinations.
## Mapping Table
| Preset | Texture | Mood | Typography | Density |
|--------|---------|------|------------|---------|
| blueprint | grid | cool | technical | balanced |
| chalkboard | organic | warm | handwritten | balanced |
| corporate | clean | professional | geometric | balanced |
| minimal | clean | neutral | geometric | minimal |
| sketch-notes | organic | warm | handwritten | balanced |
| watercolor | organic | warm | humanist | minimal |
| dark-atmospheric | clean | dark | editorial | balanced |
| notion | clean | neutral | geometric | dense |
| bold-editorial | clean | vibrant | editorial | balanced |
| editorial-infographic | clean | cool | editorial | dense |
| fantasy-animation | organic | vibrant | handwritten | minimal |
| intuition-machine | clean | cool | technical | dense |
| pixel-art | pixel | vibrant | technical | balanced |
| scientific | clean | cool | technical | dense |
| vector-illustration | clean | vibrant | humanist | balanced |
| vintage | paper | warm | editorial | balanced |
## Preset Details
### blueprint
- **Dimensions**: grid + cool + technical + balanced
- **Feel**: Engineering precision, analytical clarity
- **Auto-select**: architecture, system, data, analysis, technical
### chalkboard
- **Dimensions**: organic + warm + handwritten + balanced
- **Feel**: Classroom warmth, educational
- **Auto-select**: classroom, teaching, school, chalkboard
### corporate
- **Dimensions**: clean + professional + geometric + balanced
- **Feel**: Business credibility, institutional trust
- **Auto-select**: investor, quarterly, business, corporate
### minimal
- **Dimensions**: clean + neutral + geometric + minimal
- **Feel**: Maximum sophistication, executive focus
- **Auto-select**: executive, minimal, clean, simple
### sketch-notes
- **Dimensions**: organic + warm + handwritten + balanced
- **Feel**: Friendly learning, approachable education
- **Auto-select**: tutorial, learn, education, guide, beginner
### watercolor
- **Dimensions**: organic + warm + humanist + minimal
- **Feel**: Artistic, natural, lifestyle
- **Auto-select**: lifestyle, wellness, travel, artistic
### dark-atmospheric
- **Dimensions**: clean + dark + editorial + balanced
- **Feel**: Cinematic, entertainment
- **Auto-select**: entertainment, music, gaming, atmospheric
### notion
- **Dimensions**: clean + neutral + geometric + dense
- **Feel**: SaaS professional, data-forward
- **Auto-select**: saas, product, dashboard, metrics
### bold-editorial
- **Dimensions**: clean + vibrant + editorial + balanced
- **Feel**: Magazine impact, keynote drama
- **Auto-select**: launch, marketing, keynote, magazine
### editorial-infographic
- **Dimensions**: clean + cool + editorial + dense
- **Feel**: Publication quality, informative
- **Auto-select**: explainer, journalism, science communication
### fantasy-animation
- **Dimensions**: organic + vibrant + handwritten + minimal
- **Feel**: Magical, storytelling
- **Auto-select**: story, fantasy, animation, magical
### intuition-machine
- **Dimensions**: clean + cool + technical + dense
- **Feel**: Technical briefing, bilingual documentation
- **Auto-select**: briefing, academic, research, bilingual
### pixel-art
- **Dimensions**: pixel + vibrant + technical + balanced
- **Feel**: Retro gaming, developer culture
- **Auto-select**: gaming, retro, pixel, developer
### scientific
- **Dimensions**: clean + cool + technical + dense
- **Feel**: Academic precision, research quality
- **Auto-select**: biology, chemistry, medical, scientific
### vector-illustration
- **Dimensions**: clean + vibrant + humanist + balanced
- **Feel**: Flat design, friendly creative
- **Auto-select**: creative, children, kids, cute
### vintage
- **Dimensions**: paper + warm + editorial + balanced
- **Feel**: Historical, heritage storytelling
- **Auto-select**: history, heritage, vintage, expedition
## Building Custom Combinations
When user selects "Custom dimensions", combine any:
- **Texture** (5): clean, grid, organic, pixel, paper
- **Mood** (6): professional, warm, cool, vibrant, dark, neutral
- **Typography** (5): geometric, humanist, handwritten, editorial, technical
- **Density** (3): minimal, balanced, dense
Total possible combinations: 5 × 6 × 5 × 3 = **450 unique styles**
## Recommended Combinations (Beyond Presets)
| Custom Name | Texture | Mood | Typography | Density | Use Case |
|-------------|---------|------|------------|---------|----------|
| tech-minimal | clean | neutral | technical | minimal | Developer keynotes |
| warm-editorial | paper | warm | editorial | balanced | Heritage brands |
| dark-technical | grid | dark | technical | dense | Security, DevOps |
| playful-clean | clean | vibrant | humanist | balanced | Startups, apps |
@@ -0,0 +1,60 @@
# Texture Dimension
Visual texture and background treatment.
## Options
| Option | Background | Visual Elements | Best For |
|--------|------------|-----------------|----------|
| `clean` | Pure solid color, no texture | Clean lines, geometric shapes | Executive, minimal, corporate |
| `grid` | Subtle grid overlay | Grid lines, schematics, technical diagrams | Technical, architecture, engineering |
| `organic` | Soft textures, hand-drawn feel | Brush strokes, watercolor, sketchy lines | Creative, educational, friendly |
| `pixel` | Chunky pixels, 8-bit aesthetic | Pixel art, retro game elements | Gaming, developer, nostalgic |
| `paper` | Aged/textured paper | Vintage elements, stamps, weathering | Historical, heritage, storytelling |
## Rendering Guidelines
### clean
- Solid background colors with no visible texture
- Crisp, sharp edges on all elements
- Digital precision and clarity
- Maximum contrast for readability
### grid
- Light grid overlay (5-10% opacity)
- Engineering paper or blueprint feel
- Alignment guides visible but subtle
- Technical drawing aesthetic
### organic
- Paper grain or canvas texture
- Imperfect edges, natural variations
- Hand-painted color fills
- Casual, approachable feel
### pixel
- Visible pixel grid (chunky, not fine)
- 8-bit color palette aesthetic
- Aliased edges (no smoothing)
- Retro game UI elements
### paper
- Aged paper texture (subtle creases, discoloration)
- Vintage printing artifacts
- Sepia or warm tones
- Historical document feel
## Combination Notes
| Texture | Works Best With | Avoid With |
|---------|-----------------|------------|
| clean | professional, neutral moods | handwritten typography |
| grid | cool, professional moods | handwritten, vibrant moods |
| organic | warm, vibrant moods | technical typography |
| pixel | vibrant, dark moods | editorial typography |
| paper | warm moods | geometric typography, minimal density |
@@ -0,0 +1,97 @@
# Typography Dimension
Headline and body text styling.
## Options
| Option | Headline Style | Body Style | Best For |
|--------|----------------|------------|----------|
| `geometric` | Modern sans-serif, clean angles | Clean sans-serif | Corporate, tech, modern |
| `humanist` | Friendly sans-serif, warm curves | Readable sans-serif | Education, general audiences |
| `handwritten` | Marker/brush, organic feel | Casual script or print | Creative, sketch, friendly |
| `editorial` | Bold serif/sans mix, magazine style | Classic serif | Keynote, magazine, premium |
| `technical` | Monospace accents, precise | Clean sans-serif | Developer, data, engineering |
## Rendering Guidelines
### geometric
**Headlines**: Modern geometric sans-serif with clean angles and consistent stroke width. Think Futura, Avenir, or Proxima Nova. Bold to semi-bold weight. Perfect circles in O, G characters.
**Body**: Clean sans-serif optimized for readability. Regular weight. Consistent x-height. Sufficient letter spacing.
**Characteristics**:
- Mathematical precision in letterforms
- Consistent stroke widths
- Perfect geometry in curves
- Modern, authoritative presence
### humanist
**Headlines**: Friendly sans-serif with subtle stroke variations. Think Frutiger, Open Sans, or Myriad. Medium to semi-bold weight. Warm, approachable letterforms.
**Body**: Readable humanist sans-serif. Comfortable line height. Slight calligraphic influence.
**Characteristics**:
- Warm, approachable feel
- Subtle stroke contrast
- Open counters for readability
- Natural, human touch
### handwritten
**Headlines**: Bold hand-written marker or brush lettering. Thick strokes with organic edges. Slightly uneven baseline. Render as actual hand-drawn letters.
**Body**: Clear handwritten style mimicking notes. Casual but legible. Natural variation in letter forms.
**Characteristics**:
- Organic, imperfect letterforms
- Visible brush/pen character
- Casual, personal feel
- NOT computer fonts - actual drawn letters
### editorial
**Headlines**: Bold serif or high-contrast sans-serif. Magazine cover style. Dramatic scale contrast. Think Playfair Display, Didot, or bold condensed sans.
**Body**: Classic serif for extended reading. Elegant, refined letterforms. Traditional publishing quality.
**Characteristics**:
- High contrast (thick/thin strokes)
- Dramatic headlines
- Sophisticated presence
- Premium, publication quality
### technical
**Headlines**: Clean sans-serif with monospace accents for data/code. Precise, engineered appearance. Think SF Mono for code, Inter for headers.
**Body**: Clean sans-serif optimized for technical content. Fixed-width for numbers and code.
**Characteristics**:
- Monospace for data elements
- Precise alignment
- Clear number distinction (0 vs O, 1 vs l)
- Engineering precision
## Font Rendering Instructions
Since image generators cannot use font names, describe visual characteristics:
| Option | Headline Description | Body Description |
|--------|---------------------|------------------|
| geometric | "bold geometric sans-serif with perfect circular O shapes" | "clean modern sans-serif" |
| humanist | "friendly rounded sans-serif with warm letterforms" | "readable humanist sans-serif" |
| handwritten | "bold hand-drawn marker lettering with organic strokes" | "casual handwritten notes style" |
| editorial | "dramatic high-contrast serif with thick-thin stroke variation" | "elegant classic serif" |
| technical | "precise sans-serif with monospace numbers" | "technical sans-serif, fixed-width for code" |
## Combination Notes
| Typography | Works Best With | Avoid With |
|------------|-----------------|------------|
| geometric | clean texture, professional/neutral mood | organic texture |
| humanist | organic/clean texture, warm mood | pixel texture |
| handwritten | organic/paper texture, warm/vibrant mood | grid texture, professional mood |
| editorial | clean texture, vibrant/professional mood | pixel texture |
| technical | grid/clean texture, cool/dark mood | paper texture, warm mood |
@@ -0,0 +1,65 @@
# Layout Gallery
Optional layout hints for individual slides. Specify in outline's `// LAYOUT` section.
## Slide-Specific Layouts
| Layout | Description | Best For |
|--------|-------------|----------|
| `title-hero` | Large centered title + subtitle | Cover slides, section breaks |
| `quote-callout` | Featured quote with attribution | Testimonials, key insights |
| `key-stat` | Single large number as focal point | Impact statistics, metrics |
| `split-screen` | Half image, half text | Feature highlights, comparisons |
| `icon-grid` | Grid of icons with labels | Features, capabilities, benefits |
| `two-columns` | Content in balanced columns | Paired information, dual points |
| `three-columns` | Content in three columns | Triple comparisons, categories |
| `image-caption` | Full-bleed image + text overlay | Visual storytelling, emotional |
| `agenda` | Numbered list with highlights | Session overview, roadmap |
| `bullet-list` | Structured bullet points | Simple content, lists |
## Infographic-Derived Layouts
| Layout | Description | Best For |
|--------|-------------|----------|
| `linear-progression` | Sequential flow left-to-right | Timelines, step-by-step |
| `binary-comparison` | Side-by-side A vs B | Before/after, pros-cons |
| `comparison-matrix` | Multi-factor grid | Feature comparisons |
| `hierarchical-layers` | Pyramid or stacked levels | Priority, importance |
| `hub-spoke` | Central node with radiating items | Concept maps, ecosystems |
| `bento-grid` | Varied-size tiles | Overview, summary |
| `funnel` | Narrowing stages | Conversion, filtering |
| `dashboard` | Metrics with charts/numbers | KPIs, data display |
| `venn-diagram` | Overlapping circles | Relationships, intersections |
| `circular-flow` | Continuous cycle | Recurring processes |
| `winding-roadmap` | Curved path with milestones | Journey, timeline |
| `tree-branching` | Parent-child hierarchy | Org charts, taxonomies |
| `iceberg` | Visible vs hidden layers | Surface vs depth |
| `bridge` | Gap with connection | Problem-solution |
**Usage**: Add `Layout: <name>` in slide's `// LAYOUT` section.
## Layout Selection Tips
**Match Layout to Content**:
| Content Type | Recommended Layouts |
|--------------|-------------------|
| Single narrative | `bullet-list`, `image-caption` |
| Two concepts | `split-screen`, `binary-comparison` |
| Three items | `three-columns`, `icon-grid` |
| Process/Steps | `linear-progression`, `winding-roadmap` |
| Data/Metrics | `dashboard`, `key-stat` |
| Relationships | `hub-spoke`, `venn-diagram` |
| Hierarchy | `hierarchical-layers`, `tree-branching` |
**Layout Flow Patterns**:
| Position | Recommended Layouts |
|----------|-------------------|
| Opening | `title-hero`, `agenda` |
| Middle | Content-specific layouts |
| Closing | `quote-callout`, `key-stat` |
**Common Mistakes to Avoid**:
- Using 3-column layout for 2 items (leaves columns empty)
- Stacking charts/tables below text (use side-by-side instead)
- Image layouts without actual images
- Quote layouts for emphasis (use only for real quotes with attribution)
@@ -8,7 +8,8 @@ Standard structure for slide deck outlines with style instructions.
# Slide Deck Outline # Slide Deck Outline
**Topic**: [topic description] **Topic**: [topic description]
**Style**: [selected style] **Style**: [preset name OR "custom"]
**Dimensions**: [texture] + [mood] + [typography] + [density]
**Audience**: [target audience] **Audience**: [target audience]
**Language**: [output language] **Language**: [output language]
**Slide Count**: N slides **Slide Count**: N slides
@@ -17,15 +18,15 @@ Standard structure for slide deck outlines with style instructions.
--- ---
<STYLE_INSTRUCTIONS> <STYLE_INSTRUCTIONS>
Design Aesthetic: [2-3 sentence description from style file] Design Aesthetic: [2-3 sentence description combining dimension characteristics]
Background: Background:
Color: [Name] ([Hex]) Texture: [from texture dimension]
Texture: [description] Base Color: [from mood dimension palette]
Typography: Typography:
Primary Font: [detailed description for image generation] Headlines: [from typography dimension - describe visual appearance]
Secondary Font: [detailed description for image generation] Body: [from typography dimension - describe visual appearance]
Color Palette: Color Palette:
Primary Text: [Name] ([Hex]) - [usage] Primary Text: [Name] ([Hex]) - [usage]
@@ -34,13 +35,17 @@ Color Palette:
Accent 2: [Name] ([Hex]) - [usage] Accent 2: [Name] ([Hex]) - [usage]
Visual Elements: Visual Elements:
- [element 1 with rendering guidance] - [element 1 from texture + mood combination]
- [element 2 with rendering guidance] - [element 2 with rendering guidance]
- ... - ...
Density Guidelines:
- Content per slide: [from density dimension]
- Whitespace: [from density dimension]
Style Rules: Style Rules:
Do: [guidelines from style file] Do: [guidelines from dimension combinations]
Don't: [anti-patterns from style file] Don't: [anti-patterns from dimension combinations]
</STYLE_INSTRUCTIONS> </STYLE_INSTRUCTIONS>
--- ---
@@ -48,6 +53,88 @@ Style Rules:
[Slide entries follow...] [Slide entries follow...]
``` ```
## Building STYLE_INSTRUCTIONS from Dimensions
When using custom dimensions or presets, build STYLE_INSTRUCTIONS by combining:
### 1. Design Aesthetic
Combine characteristics from all four dimensions into 2-3 sentences:
| Texture | Contribution |
|---------|--------------|
| clean | "Clean, digital precision with crisp edges" |
| grid | "Technical grid overlay with engineering precision" |
| organic | "Hand-drawn feel with soft textures" |
| pixel | "Chunky pixel aesthetic with 8-bit charm" |
| paper | "Aged paper texture with vintage character" |
| Mood | Contribution |
|------|--------------|
| professional | "Professional navy and gold palette" |
| warm | "Warm earth tones creating approachable atmosphere" |
| cool | "Cool analytical blues and grays" |
| vibrant | "Bold, high-saturation colors with energy" |
| dark | "Deep cinematic backgrounds with glowing accents" |
| neutral | "Minimal grayscale sophistication" |
### 2. Background
From `references/dimensions/texture.md`:
- Texture description
- Base color from mood palette
### 3. Typography
From `references/dimensions/typography.md`:
- Headline visual description (NOT font names)
- Body text visual description (NOT font names)
**Important**: Describe appearance for image generation: "bold geometric sans-serif with perfect circular O shapes" NOT "Inter font".
### 4. Color Palette
From `references/dimensions/mood.md`:
- Copy the palette specifications for the selected mood
- Include hex codes and usage notes
### 5. Visual Elements
Combine texture and mood characteristics:
| Combination | Visual Elements |
|-------------|-----------------|
| clean + professional | Clean charts, outlined icons, structured grids |
| grid + cool | Technical schematics, dimension lines, blueprints |
| organic + warm | Hand-drawn icons, brush strokes, doodles |
| pixel + vibrant | Pixel art icons, retro game elements |
| paper + warm | Vintage stamps, aged elements, sepia overlays |
### 6. Density Guidelines
From `references/dimensions/density.md`:
- Content per slide limits
- Whitespace requirements
- Element count guidelines
### 7. Style Rules
Combine dimension-specific rules:
**Do rules by texture**:
- clean: Maintain sharp edges, use grid alignment
- grid: Show precise measurements, use technical diagrams
- organic: Allow imperfection, layer with subtle overlaps
- pixel: Keep aliased edges, use chunky elements
- paper: Add subtle aging effects, use warm tones
**Don't rules by texture**:
- clean: Don't use hand-drawn elements
- grid: Don't use organic curves
- organic: Don't use perfect geometry
- pixel: Don't smooth edges
- paper: Don't use bright digital colors
## Cover Slide Template ## Cover Slide Template
```markdown ```markdown
@@ -123,18 +210,33 @@ Layout: [optional: layout name from gallery]
## STYLE_INSTRUCTIONS Block ## STYLE_INSTRUCTIONS Block
The `<STYLE_INSTRUCTIONS>` block contains all style-specific guidance for image generation: The `<STYLE_INSTRUCTIONS>` block is the SINGLE SOURCE OF TRUTH for style information in this outline.
| Section | Content | | Section | Content | Source |
|---------|---------| |---------|---------|--------|
| Design Aesthetic | Overall visual direction from style file | | Design Aesthetic | Overall visual direction | Combined from all dimensions |
| Background | Base color and texture details | | Background | Base color and texture details | texture + mood dimensions |
| Typography | Font descriptions for Gemini (no font names, describe appearance) | | Typography | Font descriptions (visual, not names) | typography dimension |
| Color Palette | Named colors with hex codes and usage guidance | | Color Palette | Named colors with hex codes and usage | mood dimension |
| Visual Elements | Specific graphic elements with rendering instructions | | Visual Elements | Graphic elements with rendering instructions | texture + mood dimensions |
| Style Rules | Do/Don't guidelines from style file | | Density Guidelines | Content limits and whitespace | density dimension |
| Style Rules | Do/Don't guidelines | Combined from dimensions |
**Important**: Typography descriptions must describe the visual appearance (e.g., "rounded sans-serif", "bold geometric") since image generators cannot use font names. **Important**:
- Typography descriptions must describe visual appearance (e.g., "rounded sans-serif", "bold geometric") since image generators cannot use font names
- Prompts should extract STYLE_INSTRUCTIONS from this outline, NOT re-read style files
## Preset → Dimensions Reference
When using a preset, look up dimensions in `references/dimensions/presets.md`:
| Preset | Dimensions |
|--------|------------|
| blueprint | grid + cool + technical + balanced |
| sketch-notes | organic + warm + handwritten + balanced |
| corporate | clean + professional + geometric + balanced |
| minimal | clean + neutral + geometric + minimal |
| ... | See presets.md for full mapping |
## Section Dividers ## Section Dividers
+45 -94
View File
@@ -21,6 +21,36 @@ Fetches any URL via Chrome CDP and converts HTML to clean markdown.
|--------|---------| |--------|---------|
| `scripts/main.ts` | CLI entry point for URL fetching | | `scripts/main.ts` | CLI entry point for URL fetching |
## Preferences (EXTEND.md)
Use Bash to check EXTEND.md existence (priority order):
```bash
# Check project-level first
test -f .baoyu-skills/baoyu-url-to-markdown/EXTEND.md && echo "project"
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
test -f "$HOME/.baoyu-skills/baoyu-url-to-markdown/EXTEND.md" && echo "user"
```
┌────────────────────────────────────────────────────────┬───────────────────┐
│ Path │ Location │
├────────────────────────────────────────────────────────┼───────────────────┤
│ .baoyu-skills/baoyu-url-to-markdown/EXTEND.md │ Project directory │
├────────────────────────────────────────────────────────┼───────────────────┤
│ $HOME/.baoyu-skills/baoyu-url-to-markdown/EXTEND.md │ User home │
└────────────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
│ Result │ Action │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Found │ Read, parse, apply settings │
├───────────┼───────────────────────────────────────────────────────────────────────────┤
│ Not found │ Use defaults │
└───────────┴───────────────────────────────────────────────────────────────────────────┘
**EXTEND.md Supports**: Default output directory | Default capture mode | Timeout settings
## Features ## Features
- Chrome CDP for full JavaScript rendering - Chrome CDP for full JavaScript rendering
@@ -52,103 +82,28 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts <url> -o output.md
## Capture Modes ## Capture Modes
### Auto Mode (default) | Mode | Behavior | Use When |
|------|----------|----------|
| Auto (default) | Capture on network idle | Public pages, static content |
| Wait (`--wait`) | User signals when ready | Login-required, lazy loading, paywalls |
Page loads → waits for network idle → captures immediately. **Wait mode workflow**:
1. Run with `--wait` → script outputs "Press Enter when ready"
Best for: 2. Ask user to confirm page is ready
- Public pages 3. Send newline to stdin to trigger capture
- Static content
- No login required
### Wait Mode (`--wait`)
Page opens → user can interact (login, scroll, etc.) → user signals ready → captures.
Best for:
- Login-required pages
- Dynamic content needing interaction
- Pages with lazy loading
**Agent workflow for wait mode**:
1. Run script with `--wait` flag
2. Script outputs: `Page opened. Press Enter when ready to capture...`
3. Use `AskUserQuestion` to ask user if page is ready
4. When user confirms, send newline to stdin to trigger capture
## Output Format ## Output Format
```markdown YAML front matter with `url`, `title`, `description`, `author`, `published`, `captured_at` fields, followed by converted markdown content.
---
url: https://example.com/page
title: "Page Title"
description: "Meta description if available"
author: "Author if available"
published: "2024-01-01"
captured_at: "2024-01-15T10:30:00Z"
---
# Page Title
Converted markdown content...
```
## Mode Selection Guide
When user requests URL capture, help select appropriate mode:
**Suggest Auto Mode when**:
- URL is public (no login wall visible)
- Content appears static
- User doesn't mention login requirements
**Suggest Wait Mode when**:
- User mentions needing to log in
- Site known to require authentication
- User wants to scroll/interact before capture
- Content is behind paywall
**Ask user when unclear**:
```
The page may require login or interaction before capturing.
Which mode should I use?
1. Auto - Capture immediately when loaded
2. Wait - Wait for you to interact first
```
## Output Directory ## Output Directory
Each capture creates a file organized by domain:
``` ```
url-to-markdown/ url-to-markdown/<domain>/<slug>.md
└── <domain>/
└── <slug>.md
``` ```
**Path Components**: - `<slug>`: From page title or URL path (kebab-case, 2-6 words)
- `<domain>`: Site domain (e.g., `example.com`, `github.com`) - Conflict resolution: Append timestamp `<slug>-YYYYMMDD-HHMMSS.md`
- `<slug>`: Generated from page title or URL path (kebab-case)
**Slug Generation**:
1. Extract from page title (preferred) or URL path
2. Convert to kebab-case, 2-6 words
3. Example: "Getting Started with React" → `getting-started-with-react`
**Conflict Resolution**:
If `url-to-markdown/<domain>/<slug>.md` already exists:
- Append timestamp: `<slug>-YYYYMMDD-HHMMSS.md`
- Example: `getting-started.md` exists → `getting-started-20260118-143052.md`
## Error Handling
| Error | Resolution |
|-------|------------|
| Chrome not found | Install Chrome or set `URL_CHROME_PATH` env |
| Page timeout | Increase `--timeout` value |
| Capture failed | Try wait mode for complex pages |
| Empty content | Page may need JS rendering time |
## Environment Variables ## Environment Variables
@@ -158,12 +113,8 @@ If `url-to-markdown/<domain>/<slug>.md` already exists:
| `URL_DATA_DIR` | Custom data directory | | `URL_DATA_DIR` | Custom data directory |
| `URL_CHROME_PROFILE_DIR` | Custom Chrome profile directory | | `URL_CHROME_PROFILE_DIR` | Custom Chrome profile directory |
**Troubleshooting**: Chrome not found → set `URL_CHROME_PATH`. Timeout → increase `--timeout`. Complex pages → try `--wait` mode.
## Extension Support ## Extension Support
Custom configurations via EXTEND.md. Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
**Check paths** (priority order):
1. `.baoyu-skills/baoyu-url-to-markdown/EXTEND.md` (project)
2. `~/.baoyu-skills/baoyu-url-to-markdown/EXTEND.md` (user)
If found, load before workflow. Extension content overrides defaults.
+2 -3
View File
@@ -359,9 +359,8 @@ With confirmed outline + style + layout:
**Watermark Application** (if enabled in preferences): **Watermark Application** (if enabled in preferences):
Add to each image generation prompt: Add to each image generation prompt:
``` ```
Include a subtle watermark "[content]" positioned at [position] Include a subtle watermark "[content]" positioned at [position].
with approximately [opacity*100]% visibility. The watermark should The watermark should be legible but not distracting from the main content.
be legible but not distracting from the main content.
``` ```
Reference: `references/config/watermark-guide.md` Reference: `references/config/watermark-guide.md`
@@ -15,7 +15,6 @@ watermark:
enabled: false enabled: false
content: "" content: ""
position: bottom-right # bottom-right|bottom-left|bottom-center|top-right position: bottom-right # bottom-right|bottom-left|bottom-center|top-right
opacity: 0.7 # 0.1-1.0
preferred_style: preferred_style:
name: null # Built-in or custom style name name: null # Built-in or custom style name
@@ -46,7 +45,6 @@ custom_styles:
| `watermark.enabled` | bool | false | Enable watermark | | `watermark.enabled` | bool | false | Enable watermark |
| `watermark.content` | string | "" | Watermark text (@username or custom) | | `watermark.content` | string | "" | Watermark text (@username or custom) |
| `watermark.position` | enum | bottom-right | Position on image | | `watermark.position` | enum | bottom-right | Position on image |
| `watermark.opacity` | float | 0.7 | Transparency (0.1-1.0) |
| `preferred_style.name` | string | null | Style name or null | | `preferred_style.name` | string | null | Style name or null |
| `preferred_style.description` | string | "" | Custom notes/override | | `preferred_style.description` | string | "" | Custom notes/override |
| `preferred_layout` | string | null | Layout preference or null | | `preferred_layout` | string | null | Layout preference or null |
@@ -97,7 +95,6 @@ watermark:
enabled: true enabled: true
content: "@myxhsaccount" content: "@myxhsaccount"
position: bottom-right position: bottom-right
opacity: 0.5
preferred_style: preferred_style:
name: notion name: notion
@@ -28,15 +28,6 @@ description: Watermark configuration guide for baoyu-xhs-images
| `bottom-center` | Centered designs | Text-heavy bottom area | | `bottom-center` | Centered designs | Text-heavy bottom area |
| `top-right` | Bottom-heavy content | Title/header in top-right | | `top-right` | Bottom-heavy content | Title/header in top-right |
## Opacity Examples
| Opacity | Visual Effect | Use Case |
|---------|---------------|----------|
| 0.3 | Very subtle, barely visible | Clean aesthetic priority |
| 0.5 | Balanced, noticeable but not distracting | Default recommendation |
| 0.7 | Clearly visible | Brand recognition priority |
| 0.9 | Strong presence | Anti-copy protection |
## Content Format ## Content Format
| Format | Example | Style | | Format | Example | Style |
@@ -51,23 +42,21 @@ description: Watermark configuration guide for baoyu-xhs-images
1. **Consistency**: Use same watermark across all images in series 1. **Consistency**: Use same watermark across all images in series
2. **Legibility**: Ensure watermark readable on both light/dark areas 2. **Legibility**: Ensure watermark readable on both light/dark areas
3. **Size**: Keep subtle - should not distract from content 3. **Size**: Keep subtle - should not distract from content
4. **Contrast**: Opacity may need adjustment per image background
## Prompt Integration ## Prompt Integration
When watermark is enabled, add to image generation prompt: When watermark is enabled, add to image generation prompt:
``` ```
Include a subtle watermark "[content]" positioned at [position] Include a subtle watermark "[content]" positioned at [position].
with approximately [opacity*100]% visibility. The watermark should The watermark should be legible but not distracting from the main content.
be legible but not distracting from the main content.
``` ```
## Common Issues ## Common Issues
| Issue | Solution | | Issue | Solution |
|-------|----------| |-------|----------|
| Watermark invisible | Increase opacity or adjust position | | Watermark invisible | Adjust position or check contrast |
| Watermark too prominent | Decrease opacity (0.3-0.5) | | Watermark too prominent | Change position or reduce size |
| Watermark overlaps content | Change position | | Watermark overlaps content | Change position |
| Inconsistent across images | Use session ID for consistency | | Inconsistent across images | Use session ID for consistency |