mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-13 22:29:48 +08:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e6a9b217e6 | |||
| ec1743592c | |||
| fe647a11bb | |||
| 5a11b49b00 | |||
| 04692515bb | |||
| eb54c2a2e7 | |||
| a39c8eb0bd | |||
| 715555c2ab | |||
| 02b039f2ff | |||
| 00306414fe | |||
| db1179e057 | |||
| 7b0c9ca372 | |||
| e7255efdd6 | |||
| b15a95e73d | |||
| 07af3c4c21 | |||
| 7842e4d188 | |||
| fcd49cd5ea | |||
| f454257b5c |
@@ -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.21.4"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -149,3 +149,6 @@ xhs-images/
|
|||||||
url-to-markdown/
|
url-to-markdown/
|
||||||
cover-image/
|
cover-image/
|
||||||
slide-deck/
|
slide-deck/
|
||||||
|
infographic/
|
||||||
|
illustrations/
|
||||||
|
comic/
|
||||||
|
|||||||
@@ -2,6 +2,96 @@
|
|||||||
|
|
||||||
English | [中文](./CHANGELOG.zh.md)
|
English | [中文](./CHANGELOG.zh.md)
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|||||||
@@ -2,6 +2,96 @@
|
|||||||
|
|
||||||
[English](./CHANGELOG.md) | 中文
|
[English](./CHANGELOG.md) | 中文
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
### 重构
|
### 重构
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -245,24 +245,31 @@ 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 4 dimensions: Type × Style × Text × Mood.
|
||||||
|
|
||||||
```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 --quick
|
||||||
|
|
||||||
|
# Specify dimensions
|
||||||
/baoyu-cover-image path/to/article.md --type conceptual --style blueprint
|
/baoyu-cover-image path/to/article.md --type conceptual --style blueprint
|
||||||
/baoyu-cover-image path/to/article.md --style warm
|
/baoyu-cover-image path/to/article.md --text title-subtitle --mood bold
|
||||||
|
|
||||||
# Specify aspect ratio (default: 2.35:1)
|
# Specify aspect ratio (default: 2.35:1)
|
||||||
/baoyu-cover-image path/to/article.md --aspect 16:9
|
/baoyu-cover-image path/to/article.md --aspect 16:9
|
||||||
|
|
||||||
# Without title text
|
# 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`
|
**Four Dimensions**:
|
||||||
|
- **Type**: `hero`, `conceptual`, `typography`, `metaphor`, `scene`, `minimal`
|
||||||
|
- **Style**: 20 built-in styles (see previews below)
|
||||||
|
- **Text**: `none`, `title-only` (default), `title-subtitle`, `text-rich`
|
||||||
|
- **Mood**: `subtle`, `balanced` (default), `bold`
|
||||||
|
|
||||||
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`
|
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`
|
||||||
|
|
||||||
@@ -297,6 +304,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 +314,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 +376,7 @@ Generate professional slide deck images from content. Creates comprehensive outl
|
|||||||
|  | | |
|
|  | | |
|
||||||
| 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
|
||||||
|
|
||||||
|
|||||||
+60
-25
@@ -245,24 +245,31 @@ npx skills add jimliu/baoyu-skills
|
|||||||
|
|
||||||
#### baoyu-cover-image
|
#### baoyu-cover-image
|
||||||
|
|
||||||
为文章生成封面图,支持类型 × 风格二维系统。
|
为文章生成封面图,支持四维定制系统:类型 × 风格 × 文字 × 氛围。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 根据内容自动选择类型和风格
|
# 根据内容自动选择所有维度
|
||||||
/baoyu-cover-image path/to/article.md
|
/baoyu-cover-image path/to/article.md
|
||||||
|
|
||||||
# 指定类型和/或风格
|
# 快速模式:跳过确认,使用自动选择
|
||||||
|
/baoyu-cover-image path/to/article.md --quick
|
||||||
|
|
||||||
|
# 指定维度
|
||||||
/baoyu-cover-image path/to/article.md --type conceptual --style blueprint
|
/baoyu-cover-image path/to/article.md --type conceptual --style blueprint
|
||||||
/baoyu-cover-image path/to/article.md --style warm
|
/baoyu-cover-image path/to/article.md --text title-subtitle --mood bold
|
||||||
|
|
||||||
# 指定宽高比(默认:2.35:1)
|
# 指定宽高比(默认:2.35:1)
|
||||||
/baoyu-cover-image path/to/article.md --aspect 16:9
|
/baoyu-cover-image path/to/article.md --aspect 16:9
|
||||||
|
|
||||||
# 不包含标题文字
|
# 纯视觉(不含标题文字)
|
||||||
/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`
|
||||||
|
- **风格 (Style)**:20 种内置风格(见下方预览)
|
||||||
|
- **文字 (Text)**:`none`、`title-only`(默认)、`title-subtitle`、`text-rich`
|
||||||
|
- **氛围 (Mood)**:`subtle`、`balanced`(默认)、`bold`
|
||||||
|
|
||||||
可用风格:`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`
|
可用风格:`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`
|
||||||
|
|
||||||
@@ -297,6 +304,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 +314,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 +376,7 @@ npx skills add jimliu/baoyu-skills
|
|||||||
|  | | |
|
|  | | |
|
||||||
| watercolor | | |
|
| watercolor | | |
|
||||||
|
|
||||||
生成完成后,所有幻灯片会自动合并为 `.pptx` 文件,方便分享。
|
生成完成后,所有幻灯片会自动合并为 `.pptx` 和 `.pdf` 文件,方便分享。
|
||||||
|
|
||||||
#### baoyu-comic
|
#### baoyu-comic
|
||||||
|
|
||||||
|
|||||||
@@ -7,236 +7,188 @@ 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}" |
|
||||||
|
| `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}/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**
|
||||||
|
Based on Type, suggest compatible styles from matrix:
|
||||||
|
- [Best compatible] (Recommended)
|
||||||
|
- [Other ✓✓ styles]
|
||||||
|
- [Other ✓ styles]
|
||||||
|
|
||||||
- minimal (1-2 images) - Core concepts only
|
**Q4** (only if source ≠ user language):
|
||||||
- balanced (3-5 images) (Recommended) - Major sections
|
- Language: Source / User language
|
||||||
- rich (6+ images) - Comprehensive visual support
|
|
||||||
|
|
||||||
**Question 3: Style**
|
---
|
||||||
|
|
||||||
Based on recommended Type, suggest compatible styles (see Type × Style Compatibility matrix):
|
### Step 4: Generate Outline
|
||||||
- [Best compatible style for recommended type] (Recommended)
|
|
||||||
- [Other highly compatible styles: ✓✓ from matrix]
|
|
||||||
- [Compatible styles: ✓ from matrix]
|
|
||||||
|
|
||||||
**Question 4** (only if source ≠ user language):
|
Save as `outline.md`:
|
||||||
- Language: Source language / User language
|
|
||||||
|
|
||||||
### Step 3: Generate Outline
|
|
||||||
|
|
||||||
Based on confirmed Type + Density + Style, generate illustration outline.
|
|
||||||
|
|
||||||
**Outline Format** (`outline.md`):
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
@@ -249,44 +201,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 +251,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
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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.
|
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
---
|
---
|
||||||
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 4 dimensions (type, style, text, mood) and 20 hand-drawn 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 4-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
|
||||||
/baoyu-cover-image article.md --aspect 16:9
|
/baoyu-cover-image article.md --type conceptual --style blueprint
|
||||||
|
/baoyu-cover-image article.md --text title-subtitle --mood bold
|
||||||
|
|
||||||
# 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 +28,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 --style notion --aspect 1:1 --quick
|
||||||
[paste content]
|
[paste content]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -35,20 +36,25 @@ 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) |
|
| `--style <name>` | Cover style (see Style Gallery) |
|
||||||
| `--aspect <ratio>` | 2.35:1 (default), 16:9, 1:1 |
|
| `--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
|
## Four 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 |
|
| **Style** | Visual aesthetics, colors, technique | 20 built-in styles | 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. Example: `--type conceptual --style blueprint --text title-only --mood subtle` creates a calm technical concept visualization.
|
||||||
|
|
||||||
## Type Gallery
|
## Type Gallery
|
||||||
|
|
||||||
@@ -101,19 +107,6 @@ When `--type` is omitted, select based on content signals:
|
|||||||
|
|
||||||
Style definitions: [references/styles/](references/styles/)
|
Style definitions: [references/styles/](references/styles/)
|
||||||
|
|
||||||
## Type × Style Compatibility
|
|
||||||
|
|
||||||
| | elegant | blueprint | notion | warm | minimal | watercolor | bold-editorial | dark-atmospheric |
|
|
||||||
|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|
||||||
| hero | ✓✓ | ✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓✓ |
|
|
||||||
| conceptual | ✓✓ | ✓✓ | ✓✓ | ✓ | ✓✓ | ✗ | ✓ | ✓ |
|
|
||||||
| typography | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓✓ |
|
|
||||||
| metaphor | ✓✓ | ✗ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ |
|
|
||||||
| scene | ✓ | ✗ | ✗ | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ |
|
|
||||||
| minimal | ✓✓ | ✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✗ | ✓ |
|
|
||||||
|
|
||||||
✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
|
|
||||||
|
|
||||||
## Auto Style Selection
|
## Auto Style Selection
|
||||||
|
|
||||||
When `--style` is omitted, select based on content signals:
|
When `--style` is omitted, select based on content signals:
|
||||||
@@ -140,6 +133,89 @@ When `--style` is omitted, select based on content signals:
|
|||||||
| Lifestyle, travel | `watercolor` |
|
| Lifestyle, travel | `watercolor` |
|
||||||
| Business, professional | `elegant` |
|
| Business, professional | `elegant` |
|
||||||
|
|
||||||
|
## Text Dimension
|
||||||
|
|
||||||
|
| Value | 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 |
|
||||||
|
|
||||||
|
Full guide: [references/dimensions/text.md](references/dimensions/text.md)
|
||||||
|
|
||||||
|
## Auto Text Selection
|
||||||
|
|
||||||
|
When `--text` is omitted, select based on content 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`
|
||||||
|
|
||||||
|
## Mood Dimension
|
||||||
|
|
||||||
|
| Value | Contrast | Saturation | Weight | Use Case |
|
||||||
|
|-------|:--------:|:----------:|:------:|----------|
|
||||||
|
| `subtle` | Low | Muted | Light | Corporate, thought leadership |
|
||||||
|
| `balanced` | Medium | Normal | Medium | General articles (default) |
|
||||||
|
| `bold` | High | Vivid | Heavy | Announcements, promotions |
|
||||||
|
|
||||||
|
Full guide: [references/dimensions/mood.md](references/dimensions/mood.md)
|
||||||
|
|
||||||
|
## Auto Mood Selection
|
||||||
|
|
||||||
|
When `--mood` is omitted, select based on content 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`
|
||||||
|
|
||||||
|
## Compatibility Matrices
|
||||||
|
|
||||||
|
### Type × Style
|
||||||
|
|
||||||
|
| | elegant | blueprint | notion | warm | minimal | watercolor | bold-editorial | dark-atmospheric |
|
||||||
|
|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
|
| 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 | ✓✓ | ✓✓ | ✗ |
|
||||||
|
|
||||||
|
✓✓ = highly recommended | ✓ = compatible | ✗ = not recommended
|
||||||
|
|
||||||
## File Structure
|
## File Structure
|
||||||
|
|
||||||
Each session creates an independent directory named by content slug:
|
Each session creates an independent directory named by content slug:
|
||||||
@@ -175,7 +251,7 @@ 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
|
||||||
- [ ] Step 2: Confirm options (type + style + aspect) ⚠️ REQUIRED
|
- [ ] Step 2: Confirm options (4 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 +260,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 → [Confirm: 4 Dimensions] → Prompt → Generate → Complete
|
||||||
|
↓
|
||||||
|
(skip if --quick or all dimensions specified)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 0: Load Preferences (EXTEND.md) ⚠️
|
### Step 0: Load Preferences (EXTEND.md) ⚠️
|
||||||
@@ -226,7 +304,10 @@ Preferences loaded from [project/user]:
|
|||||||
• Watermark: [enabled/disabled] [content if enabled]
|
• Watermark: [enabled/disabled] [content if enabled]
|
||||||
• Type: [preferred_type or "auto"]
|
• Type: [preferred_type or "auto"]
|
||||||
• Style: [preferred_style or "auto"]
|
• Style: [preferred_style or "auto"]
|
||||||
|
• Text: [preferred_text or "title-only"]
|
||||||
|
• Mood: [preferred_mood or "balanced"]
|
||||||
• Aspect: [default_aspect]
|
• Aspect: [default_aspect]
|
||||||
|
• Quick mode: [enabled/disabled]
|
||||||
• Language: [language or "auto"]
|
• Language: [language or "auto"]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -276,15 +357,30 @@ options:
|
|||||||
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"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Q5: Save Location**
|
Note: More ratios (4:3, 3:2) available during generation. This sets the default recommendation.
|
||||||
|
|
||||||
|
**Q5: 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"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Q6: Save Location**
|
||||||
```yaml
|
```yaml
|
||||||
header: "Save"
|
header: "Save"
|
||||||
question: "Where to save preferences?"
|
question: "Where to save preferences?"
|
||||||
@@ -299,7 +395,7 @@ options:
|
|||||||
|
|
||||||
Full setup details: `references/config/first-time-setup.md`
|
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
|
**EXTEND.md Supports**: Watermark | Preferred type | Preferred style | Preferred text | Preferred mood | Default aspect ratio | Quick mode | Custom style definitions | Language preference
|
||||||
|
|
||||||
Schema: `references/config/preferences-schema.md`
|
Schema: `references/config/preferences-schema.md`
|
||||||
|
|
||||||
@@ -323,7 +419,31 @@ Read source content, save it if needed, and perform analysis.
|
|||||||
|
|
||||||
### Step 2: Confirm Options ⚠️
|
### Step 2: Confirm Options ⚠️
|
||||||
|
|
||||||
**Purpose**: Validate type, style and aspect ratio. **Do NOT skip.**
|
**Purpose**: Validate all 4 dimensions + aspect ratio.
|
||||||
|
|
||||||
|
**Skip Conditions**:
|
||||||
|
| Condition | Skipped Questions | Still Asked |
|
||||||
|
|-----------|-------------------|-------------|
|
||||||
|
| `--quick` flag | Type, Style, Text, Mood | **Aspect Ratio** (unless `--aspect` specified) |
|
||||||
|
| All 4 dimensions + `--aspect` specified | All | None |
|
||||||
|
| `quick_mode: true` in EXTEND.md | Type, Style, Text, Mood | **Aspect Ratio** (unless `--aspect` specified) |
|
||||||
|
| Otherwise | None | All 5 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 4 dimensions):
|
||||||
|
|
||||||
|
```
|
||||||
|
Quick Mode: Auto-selected dimensions
|
||||||
|
• Type: [type] ([reason])
|
||||||
|
• Style: [style] ([reason])
|
||||||
|
• Text: [text] ([reason])
|
||||||
|
• Mood: [mood] ([reason])
|
||||||
|
|
||||||
|
[Then ask Question 5: Aspect Ratio]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Confirmation Flow** (when NOT skipping):
|
||||||
|
|
||||||
**Language**: Auto-determined (user's input language > saved preference > source language). No need to ask.
|
**Language**: Auto-determined (user's input language > saved preference > source language). No need to ask.
|
||||||
|
|
||||||
@@ -364,50 +484,118 @@ options:
|
|||||||
description: "[reason]"
|
description: "[reason]"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Question 3: Aspect Ratio** (if not specified via `--aspect`)
|
**Question 3: Text** (if not specified via `--text`)
|
||||||
|
- Based on selected Type, show compatible text levels (✓✓ first from compatibility matrix)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
header: "Text"
|
||||||
|
question: "Text density level?"
|
||||||
|
multiSelect: false
|
||||||
|
options:
|
||||||
|
- label: "title-only (Recommended)"
|
||||||
|
description: "Simple headline, ≤8 characters"
|
||||||
|
- label: "none"
|
||||||
|
description: "Pure visual, no text elements"
|
||||||
|
- label: "title-subtitle"
|
||||||
|
description: "Title + supporting context"
|
||||||
|
- label: "text-rich"
|
||||||
|
description: "Title + subtitle + keyword tags"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Question 4: Mood** (if not specified via `--mood`)
|
||||||
|
- Based on content analysis, show recommended mood
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
header: "Mood"
|
||||||
|
question: "Emotional intensity?"
|
||||||
|
multiSelect: false
|
||||||
|
options:
|
||||||
|
- label: "balanced (Recommended)"
|
||||||
|
description: "Medium contrast and saturation, versatile"
|
||||||
|
- label: "subtle"
|
||||||
|
description: "Low contrast, muted colors, calm"
|
||||||
|
- label: "bold"
|
||||||
|
description: "High contrast, vivid colors, dynamic"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Question 5: Aspect Ratio** (ALWAYS ask unless `--aspect` specified via CLI)
|
||||||
|
|
||||||
|
Note: Even if user has a preset in EXTEND.md, still ask this question. The preset is shown as the recommended option.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
header: "Aspect"
|
header: "Aspect"
|
||||||
question: "Cover aspect ratio?"
|
question: "Cover aspect ratio?"
|
||||||
multiSelect: false
|
multiSelect: false
|
||||||
options:
|
options:
|
||||||
- label: "2.35:1 (Recommended)"
|
- label: "[user preset or 16:9] (Recommended)"
|
||||||
description: "Cinematic widescreen, best for article headers"
|
description: "[based on preset or default: Standard widescreen, versatile]"
|
||||||
- label: "16:9"
|
- label: "2.35:1"
|
||||||
description: "Standard widescreen, versatile"
|
description: "Cinematic widescreen - article headers, blog posts"
|
||||||
|
- label: "4:3"
|
||||||
|
description: "Traditional screen - PPT slides, classic displays"
|
||||||
|
- label: "3:2"
|
||||||
|
description: "Photography ratio - blog articles, Medium posts"
|
||||||
- label: "1:1"
|
- label: "1:1"
|
||||||
description: "Square, social media friendly"
|
description: "Square - Instagram, WeChat moments, social cards"
|
||||||
|
- label: "3:4"
|
||||||
|
description: "Portrait - Xiaohongshu, Pinterest, mobile-first content"
|
||||||
```
|
```
|
||||||
|
|
||||||
**After response**: Proceed to Step 3 with confirmed type + style + aspect ratio.
|
**After response**: Proceed to Step 3 with confirmed dimensions.
|
||||||
|
|
||||||
### Step 3: Create Prompt
|
### Step 3: Create Prompt
|
||||||
|
|
||||||
Save to `prompts/cover.md`:
|
Save to `prompts/cover.md`:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
Cover theme: [2-3 words]
|
# 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]
|
Type: [confirmed type]
|
||||||
Style: [confirmed style]
|
Style: [confirmed style]
|
||||||
|
Text level: [confirmed text level]
|
||||||
|
Mood: [confirmed mood]
|
||||||
Aspect ratio: [confirmed ratio]
|
Aspect ratio: [confirmed ratio]
|
||||||
Title text: [max 8 chars, or "none" if --no-title]
|
|
||||||
Language: [confirmed language]
|
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 composition:
|
||||||
- [Type-specific layout and structure]
|
- [Type-specific layout and structure]
|
||||||
|
|
||||||
Visual composition:
|
Visual composition:
|
||||||
- Main visual: [type + style appropriate metaphor]
|
- Main visual: [metaphor derived from content meaning]
|
||||||
- Layout: [positioning based on type and aspect ratio]
|
- Layout: [positioning based on type and aspect ratio]
|
||||||
- Decorative: [style elements]
|
- Decorative: [style elements that reinforce content theme]
|
||||||
|
|
||||||
Color scheme: [primary, background, accent from style]
|
Color scheme: [primary, background, accent from style, adjusted by mood]
|
||||||
Type notes: [key characteristics from type definition]
|
Type notes: [key characteristics from type definition]
|
||||||
Style notes: [key characteristics from style definition]
|
Style notes: [key characteristics from style definition]
|
||||||
|
|
||||||
[Watermark section if enabled]
|
[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-Specific Composition**:
|
||||||
|
|
||||||
| Type | Composition Guidelines |
|
| Type | Composition Guidelines |
|
||||||
@@ -419,7 +607,7 @@ Style notes: [key characteristics from style definition]
|
|||||||
| `scene` | Atmospheric environment, narrative elements, mood-setting lighting and colors |
|
| `scene` | Atmospheric environment, narrative elements, mood-setting lighting and colors |
|
||||||
| `minimal` | Single focal element, generous whitespace (60%+), essential shapes only |
|
| `minimal` | Single focal element, generous whitespace (60%+), essential shapes only |
|
||||||
|
|
||||||
**Title guidelines** (if included):
|
**Title guidelines** (when text level includes title):
|
||||||
- Max 8 characters, punchy headline
|
- Max 8 characters, punchy headline
|
||||||
- Use hooks: numbers, questions, contrasts
|
- Use hooks: numbers, questions, contrasts
|
||||||
- Match confirmed language
|
- Match confirmed language
|
||||||
@@ -427,14 +615,17 @@ Style notes: [key characteristics from style definition]
|
|||||||
**Watermark Application** (if enabled in preferences):
|
**Watermark Application** (if enabled in preferences):
|
||||||
Add to prompt:
|
Add to 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`
|
||||||
|
|
||||||
### Step 4: Generate Image
|
### Step 4: Generate Image
|
||||||
|
|
||||||
|
**Backup Existing Cover** (if regenerating):
|
||||||
|
If `cover.png` already exists in the output directory:
|
||||||
|
- Rename to `cover-backup-YYYYMMDD-HHMMSS.png`
|
||||||
|
|
||||||
**Image Generation Skill Selection**:
|
**Image Generation Skill Selection**:
|
||||||
1. Check available image generation skills
|
1. Check available image generation skills
|
||||||
2. If multiple skills available, ask user preference
|
2. If multiple skills available, ask user preference
|
||||||
@@ -453,8 +644,10 @@ Cover Generated!
|
|||||||
Topic: [topic]
|
Topic: [topic]
|
||||||
Type: [type name]
|
Type: [type name]
|
||||||
Style: [style name]
|
Style: [style name]
|
||||||
|
Text: [text level]
|
||||||
|
Mood: [mood level]
|
||||||
Aspect: [ratio]
|
Aspect: [ratio]
|
||||||
Title: [title or "visual only"]
|
Title: [title text or "visual only"]
|
||||||
Language: [lang]
|
Language: [lang]
|
||||||
Watermark: [enabled/disabled]
|
Watermark: [enabled/disabled]
|
||||||
Location: [directory path]
|
Location: [directory path]
|
||||||
@@ -463,29 +656,39 @@ 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 type** | Backup existing → Confirm new type → Update prompt → Regenerate |
|
||||||
| **Change style** | Confirm new style → Update prompt → Regenerate |
|
| **Change style** | Backup existing → Confirm new style → Update prompt → Regenerate |
|
||||||
| **Change aspect** | Confirm new aspect → Update prompt → Regenerate |
|
| **Change text** | Backup existing → Confirm new text level → Update prompt → Regenerate |
|
||||||
|
| **Change mood** | Backup existing → Confirm new mood → Update prompt → Regenerate |
|
||||||
|
| **Change aspect** | Backup existing → Confirm new aspect → Update prompt → Regenerate |
|
||||||
|
|
||||||
|
All modifications automatically backup the 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 if no EXTEND.md) + Step 2 (options) - can 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 preserved as alias for `--text none`
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
|
**Dimensions**:
|
||||||
|
- `references/dimensions/text.md` - Text density dimension
|
||||||
|
- `references/dimensions/mood.md` - Mood intensity dimension
|
||||||
|
|
||||||
**Styles**: `references/styles/<name>.md` - Style definitions
|
**Styles**: `references/styles/<name>.md` - Style definitions
|
||||||
|
|
||||||
**Config**:
|
**Config**:
|
||||||
|
|||||||
@@ -13,14 +13,49 @@ Create a WeChat article cover image following these guidelines:
|
|||||||
- 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)
|
||||||
|
|
||||||
|
## Four 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%+)
|
||||||
|
|
||||||
|
### Style (Visual Aesthetics)
|
||||||
|
Apply the specified style's color palette, visual elements, and typography characteristics.
|
||||||
|
|
||||||
|
### 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**
|
- **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)
|
||||||
|
- Tags: 2-4 keyword badges (if text-rich)
|
||||||
- Font style harmonizes with illustration style
|
- Font style harmonizes with illustration style
|
||||||
- **DO NOT use realistic or computer-generated fonts**
|
- **DO NOT use realistic or computer-generated fonts**
|
||||||
|
|
||||||
|
## Mood Application
|
||||||
|
|
||||||
|
Apply mood adjustments to the base style:
|
||||||
|
|
||||||
|
| 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
|
||||||
|
|
||||||
- Use the same language as the content provided below for any text elements
|
- Use the same language as the content provided below for any text elements
|
||||||
|
|||||||
@@ -93,7 +93,19 @@ options:
|
|||||||
description: "Square, social media friendly"
|
description: "Square, social media friendly"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Question 5: Save Location
|
### Question 5: Quick Mode
|
||||||
|
|
||||||
|
```
|
||||||
|
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 6: Save Location
|
||||||
|
|
||||||
```
|
```
|
||||||
header: "Save"
|
header: "Save"
|
||||||
@@ -123,7 +135,7 @@ options:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
version: 1
|
version: 2
|
||||||
watermark:
|
watermark:
|
||||||
enabled: [true/false]
|
enabled: [true/false]
|
||||||
content: "[user input or empty]"
|
content: "[user input or empty]"
|
||||||
@@ -131,12 +143,25 @@ watermark:
|
|||||||
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_style: [selected style or null]
|
||||||
|
preferred_text: title-only
|
||||||
|
preferred_mood: balanced
|
||||||
default_aspect: [2.35:1/16:9/1:1]
|
default_aspect: [2.35:1/16:9/1:1]
|
||||||
|
quick_mode: [true/false]
|
||||||
language: null
|
language: null
|
||||||
custom_styles: []
|
custom_styles: []
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## New Fields in v2
|
||||||
|
|
||||||
|
| Field | Default | Description |
|
||||||
|
|-------|---------|-------------|
|
||||||
|
| `preferred_text` | title-only | Text density (none, title-only, title-subtitle, text-rich) |
|
||||||
|
| `preferred_mood` | balanced | Mood intensity (subtle, balanced, bold) |
|
||||||
|
| `quick_mode` | false | Skip confirmation step when true |
|
||||||
|
|
||||||
|
Note: Text and Mood preferences use sensible defaults (title-only, balanced) and don't require setup questions. Users can modify these in EXTEND.md directly.
|
||||||
|
|
||||||
## Modifying Preferences Later
|
## Modifying Preferences Later
|
||||||
|
|
||||||
Users can edit EXTEND.md directly or run setup again:
|
Users can edit EXTEND.md directly or run setup again:
|
||||||
|
|||||||
@@ -9,20 +9,25 @@ description: EXTEND.md YAML schema for baoyu-cover-image user preferences
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
version: 1
|
version: 2
|
||||||
|
|
||||||
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_style: null # Built-in style name 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_styles:
|
||||||
@@ -42,14 +47,16 @@ custom_styles:
|
|||||||
|
|
||||||
| Field | Type | Default | Description |
|
| Field | Type | Default | Description |
|
||||||
|-------|------|---------|-------------|
|
|-------|------|---------|-------------|
|
||||||
| `version` | int | 1 | Schema version |
|
| `version` | int | 2 | 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_style` | string | null | Style 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_styles` | array | [] | User-defined styles |
|
||||||
|
|
||||||
@@ -64,6 +71,23 @@ custom_styles:
|
|||||||
| `scene` | Atmospheric scene, narrative feel |
|
| `scene` | Atmospheric scene, narrative feel |
|
||||||
| `minimal` | Minimalist composition, generous whitespace |
|
| `minimal` | Minimalist composition, generous whitespace |
|
||||||
|
|
||||||
|
## 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 |
|
||||||
@@ -98,12 +122,15 @@ custom_styles:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
version: 1
|
version: 2
|
||||||
watermark:
|
watermark:
|
||||||
enabled: true
|
enabled: true
|
||||||
content: "@myhandle"
|
content: "@myhandle"
|
||||||
preferred_type: null
|
preferred_type: null
|
||||||
preferred_style: elegant
|
preferred_style: elegant
|
||||||
|
preferred_text: title-only
|
||||||
|
preferred_mood: balanced
|
||||||
|
quick_mode: false
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -111,19 +138,24 @@ preferred_style: elegant
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
version: 1
|
version: 2
|
||||||
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_style: blueprint
|
||||||
|
|
||||||
|
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_styles:
|
||||||
@@ -138,3 +170,16 @@ custom_styles:
|
|||||||
best_for: "SaaS, enterprise, technical"
|
best_for: "SaaS, enterprise, technical"
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Migration from v1
|
||||||
|
|
||||||
|
When loading v1 schema, auto-upgrade:
|
||||||
|
|
||||||
|
| v1 Field | v2 Field | Default Value |
|
||||||
|
|----------|----------|---------------|
|
||||||
|
| (missing) | `version` | 2 |
|
||||||
|
| (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,125 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
|
||||||
|
## Style Interaction
|
||||||
|
|
||||||
|
Mood modifies the base style characteristics:
|
||||||
|
|
||||||
|
| Style Category | subtle | balanced | bold |
|
||||||
|
|----------------|--------|----------|------|
|
||||||
|
| Technical (blueprint, notion) | Lighter lines, softer colors | Standard rendering | Stronger contrast, sharper edges |
|
||||||
|
| Artistic (watercolor, sketch-notes) | More whitespace, lighter strokes | Standard rendering | Deeper colors, heavier strokes |
|
||||||
|
| Editorial (bold-editorial, dark-atmospheric) | Reduced contrast, softer tones | Standard rendering | Maximum impact, vivid colors |
|
||||||
|
|
||||||
|
## 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,122 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
- Numbers, questions, contrasts work well
|
||||||
|
- Match content language
|
||||||
|
|
||||||
|
### 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
|
||||||
|
|
||||||
|
**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
|
||||||
|
|
||||||
|
**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`
|
||||||
@@ -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.
|
|
||||||
|
|||||||
@@ -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
@@ -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.
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -1,84 +1,94 @@
|
|||||||
---
|
---
|
||||||
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
|
```bash
|
||||||
# From markdown file and image directory
|
# Check project-level first
|
||||||
npx -y bun ${SKILL_DIR}/scripts/wechat-browser.ts --markdown article.md --images ./images/
|
test -f .baoyu-skills/baoyu-post-to-wechat/EXTEND.md && echo "project"
|
||||||
|
|
||||||
# With explicit parameters
|
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||||
npx -y bun ${SKILL_DIR}/scripts/wechat-browser.ts --title "标题" --content "内容" --image img1.png --image img2.png --submit
|
test -f "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md" && echo "user"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Article (文章) - Full markdown with formatting
|
┌────────────────────────────────────────────────────────┬───────────────────┐
|
||||||
|
│ 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
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
### Article (文章)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Post markdown article
|
|
||||||
npx -y bun ${SKILL_DIR}/scripts/wechat-article.ts --markdown article.md --theme grace
|
npx -y bun ${SKILL_DIR}/scripts/wechat-article.ts --markdown article.md --theme grace
|
||||||
```
|
```
|
||||||
|
|
||||||
> **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.
|
|
||||||
|
|||||||
@@ -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');
|
||||||
@@ -168,13 +163,16 @@ async function parseMarkdownForWechat(
|
|||||||
|
|
||||||
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,
|
||||||
@@ -227,7 +225,7 @@ Output JSON format:
|
|||||||
"contentImages": [
|
"contentImages": [
|
||||||
{
|
{
|
||||||
"placeholder": "[[IMAGE_PLACEHOLDER_1]]",
|
"placeholder": "[[IMAGE_PLACEHOLDER_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}`);
|
||||||
}
|
}
|
||||||
@@ -108,30 +110,54 @@ 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 with CDP keyboard event...');
|
||||||
if (process.platform === 'darwin') {
|
const modifiers = process.platform === 'darwin' ? 4 : 2;
|
||||||
spawnSync('osascript', ['-e', 'tell application "System Events" to keystroke "c" using command down']);
|
await cdp.send('Input.dispatchKeyEvent', {
|
||||||
} else {
|
type: 'keyDown',
|
||||||
spawnSync('xdotool', ['key', 'ctrl+c']);
|
key: 'c',
|
||||||
}
|
code: 'KeyC',
|
||||||
|
modifiers,
|
||||||
|
windowsVirtualKeyCode: 67
|
||||||
|
}, { sessionId });
|
||||||
|
await sleep(50);
|
||||||
|
await cdp.send('Input.dispatchKeyEvent', {
|
||||||
|
type: 'keyUp',
|
||||||
|
key: 'c',
|
||||||
|
code: 'KeyC',
|
||||||
|
modifiers,
|
||||||
|
windowsVirtualKeyCode: 67
|
||||||
|
}, { sessionId });
|
||||||
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 with CDP keyboard event...');
|
||||||
spawnSync('osascript', ['-e', 'tell application "System Events" to keystroke "v" using command down']);
|
const modifiers = process.platform === 'darwin' ? 4 : 2;
|
||||||
} else {
|
await session.cdp.send('Input.dispatchKeyEvent', {
|
||||||
spawnSync('xdotool', ['key', 'ctrl+v']);
|
type: 'keyDown',
|
||||||
}
|
key: 'v',
|
||||||
|
code: 'KeyV',
|
||||||
|
modifiers,
|
||||||
|
windowsVirtualKeyCode: 86
|
||||||
|
}, { sessionId: session.sessionId });
|
||||||
|
await sleep(50);
|
||||||
|
await session.cdp.send('Input.dispatchKeyEvent', {
|
||||||
|
type: 'keyUp',
|
||||||
|
key: 'v',
|
||||||
|
code: 'KeyV',
|
||||||
|
modifiers,
|
||||||
|
windowsVirtualKeyCode: 86
|
||||||
|
}, { sessionId: session.sessionId });
|
||||||
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 +321,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 +332,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 +358,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.');
|
||||||
|
|||||||
@@ -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.
|
|
||||||
|
|||||||
+558
-376
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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
Reference in New Issue
Block a user