feat: improve skill review scores across 11 skills
Hullo @JimLiu 👋 I ran your skills through `tessl skill review` at work and found some targeted improvements. Here's the before/after: | Skill | Before | After | Change | |-------|--------|-------|--------| | baoyu-url-to-markdown | 79% | 100% | +21% | | baoyu-post-to-x | 86% | 100% | +14% | | baoyu-format-markdown | 89% | 100% | +11% | | baoyu-slide-deck | 89% | 100% | +11% | | baoyu-image-gen | 86% | 96% | +10% | | baoyu-article-illustrator | 93% | 100% | +7% | | baoyu-danger-x-to-markdown | 93% | 100% | +7% | | baoyu-markdown-to-html | 89% | 96% | +7% | | baoyu-post-to-wechat | 93% | 100% | +7% | | baoyu-compress-image | 94% | 100% | +6% | | baoyu-danger-gemini-web | 90% | 96% | +6% | | baoyu-xhs-images | 93% | 93% | — | | baoyu-comic | 100% | 100% | — | | baoyu-cover-image | 100% | 100% | — | | baoyu-infographic | 100% | 100% | — | <details><summary>Summary of changes</summary> Key changes: - Expanded description fields with more specific trigger terms and action verbs (url-to-markdown, slide-deck) - Replaced verbose ASCII art tables with compact markdown tables across multiple skills - Consolidated redundant EXTEND.md preference sections into concise inline descriptions - Added post-generation validation steps with explicit verification commands (compress-image, danger-gemini-web, image-gen, markdown-to-html) - Added structured troubleshooting tables with concrete error/fix pairs (url-to-markdown, danger-gemini-web, image-gen) - Removed duplicate content: repeated "Note: Script opens browser..." in post-to-x, duplicate theme tables in markdown-to-html - Condensed verbose AskUserQuestion examples to summary tables (slide-deck) - Consolidated workflow checklist + flow diagram into single representations (slide-deck, xhs-images) - Added inline prompt examples for better actionability (article-illustrator) - Moved detailed style × layout matrix to prose summary (xhs-images) - Net improvement: 11 of 12 improvable skills increased, average score rose from 91% to 98% </details> Honest disclosure — I work at @tesslio where we build tooling around skills like these. Not a pitch, just saw room for improvement and wanted to contribute. If you want to run evals yourself, click [here](https://tessl.io/registry/skills/submit). Thanks in advance 🙏 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e736707628
commit
fbe7b7847f
|
|
@ -0,0 +1,44 @@
|
|||
Hullo @JimLiu 👋
|
||||
|
||||
I ran your skills through `tessl skill review` at work and found some targeted improvements. Here's the before/after:
|
||||
|
||||
| Skill | Before | After | Change |
|
||||
|-------|--------|-------|--------|
|
||||
| baoyu-url-to-markdown | 79% | 100% | +21% |
|
||||
| baoyu-post-to-x | 86% | 100% | +14% |
|
||||
| baoyu-format-markdown | 89% | 100% | +11% |
|
||||
| baoyu-slide-deck | 89% | 100% | +11% |
|
||||
| baoyu-image-gen | 86% | 96% | +10% |
|
||||
| baoyu-article-illustrator | 93% | 100% | +7% |
|
||||
| baoyu-danger-x-to-markdown | 93% | 100% | +7% |
|
||||
| baoyu-markdown-to-html | 89% | 96% | +7% |
|
||||
| baoyu-post-to-wechat | 93% | 100% | +7% |
|
||||
| baoyu-compress-image | 94% | 100% | +6% |
|
||||
| baoyu-danger-gemini-web | 90% | 96% | +6% |
|
||||
| baoyu-xhs-images | 93% | 93% | — |
|
||||
| baoyu-comic | 100% | 100% | — |
|
||||
| baoyu-cover-image | 100% | 100% | — |
|
||||
| baoyu-infographic | 100% | 100% | — |
|
||||
|
||||
<details><summary>Summary of changes</summary>
|
||||
|
||||
Key changes:
|
||||
- Expanded description fields with more specific trigger terms and action verbs (url-to-markdown, slide-deck)
|
||||
- Replaced verbose ASCII art tables with compact markdown tables across multiple skills
|
||||
- Consolidated redundant EXTEND.md preference sections into concise inline descriptions
|
||||
- Added post-generation validation steps with explicit verification commands (compress-image, danger-gemini-web, image-gen, markdown-to-html)
|
||||
- Added structured troubleshooting tables with concrete error/fix pairs (url-to-markdown, danger-gemini-web, image-gen)
|
||||
- Removed duplicate content: repeated "Note: Script opens browser..." in post-to-x, duplicate theme tables in markdown-to-html
|
||||
- Condensed verbose AskUserQuestion examples to summary tables (slide-deck)
|
||||
- Consolidated workflow checklist + flow diagram into single representations (slide-deck, xhs-images)
|
||||
- Added inline prompt examples for better actionability (article-illustrator)
|
||||
- Moved detailed style × layout matrix to prose summary (xhs-images)
|
||||
- Net improvement: 11 of 12 improvable skills increased, average score rose from 91% to 98%
|
||||
|
||||
</details>
|
||||
|
||||
Honest disclosure — I work at @tesslio where we build tooling around skills like these. Not a pitch, just saw room for improvement and wanted to contribute.
|
||||
|
||||
If you want to run evals yourself, click [here](https://tessl.io/registry/skills/submit).
|
||||
|
||||
Thanks in advance 🙏
|
||||
|
|
@ -111,6 +111,20 @@ Full template: [references/workflow.md](references/workflow.md#step-4-generate-o
|
|||
7. Apply watermark if EXTEND.md enabled
|
||||
8. Generate from saved prompt files; retry once on failure
|
||||
|
||||
**Example prompt file** (`prompts/01-infographic-performance-gains.md`):
|
||||
```yaml
|
||||
---
|
||||
type: infographic
|
||||
style: blueprint
|
||||
aspect: 16:9
|
||||
---
|
||||
ZONES: Header banner top 15% | Data grid center 60% | Source footer bottom 10%
|
||||
LABELS: "Response Time: 120ms → 45ms" | "Throughput: 1.2K → 4.8K req/s" | "Memory: 512MB → 128MB"
|
||||
COLORS: Deep navy #1a1a3e background, electric blue #00d4ff data highlights, white text
|
||||
STYLE: Technical blueprint with subtle grid overlay, clean sans-serif typography
|
||||
ASPECT: 16:9 landscape
|
||||
```
|
||||
|
||||
Full procedures: [references/workflow.md](references/workflow.md#step-5-generate-images)
|
||||
|
||||
### Step 6: Finalize
|
||||
|
|
|
|||
|
|
@ -17,33 +17,19 @@ Scripts in `scripts/` subdirectory. Replace `${SKILL_DIR}` with this SKILL.md's
|
|||
|
||||
## Preferences (EXTEND.md)
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-compress-image/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md`):
|
||||
|
||||
```bash
|
||||
# Check project-level first
|
||||
test -f .baoyu-skills/baoyu-compress-image/EXTEND.md && echo "project"
|
||||
|
||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||
test -f "$HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
┌────────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ .baoyu-skills/baoyu-compress-image/EXTEND.md │ Project directory │
|
||||
├────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ $HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md │ User home │
|
||||
└────────────────────────────────────────────────────────┴───────────────────┘
|
||||
| Result | Action |
|
||||
|--------|--------|
|
||||
| Found | Read, parse, apply settings. If parsing fails, warn user and use defaults |
|
||||
| Not found | Use defaults (webp format, quality 80) |
|
||||
|
||||
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
|
||||
│ Result │ Action │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Found │ Read, parse, apply settings │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Not found │ Use defaults │
|
||||
└───────────┴───────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
**EXTEND.md Supports**: Default format | Default quality | Keep original preference
|
||||
**Supports**: Default format | Default quality | Keep original preference
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
@ -84,6 +70,17 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts image.png --json
|
|||
image.png → image.webp (245KB → 89KB, 64% reduction)
|
||||
```
|
||||
|
||||
## Post-Compression Verification
|
||||
|
||||
After compression, verify the output:
|
||||
|
||||
```bash
|
||||
# Verify output exists and is non-empty
|
||||
test -s output.webp && echo "OK" || echo "FAIL: output missing or empty"
|
||||
```
|
||||
|
||||
When using `--json`, parse the JSON output to confirm success and check reported file size reduction. If output is missing, check for error messages and retry. **Tip**: Use `--keep` flag to preserve originals when compressing important files.
|
||||
|
||||
## Extension Support
|
||||
|
||||
Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
|
||||
|
|
|
|||
|
|
@ -142,6 +142,29 @@ Session files stored in data directory under `sessions/<id>.json`.
|
|||
|
||||
Contains: `id`, `metadata` (Gemini chat state), `messages` array, timestamps.
|
||||
|
||||
## Post-Generation Validation
|
||||
|
||||
After image generation:
|
||||
1. Verify output file exists: `test -f <output-path>`
|
||||
2. Check file is non-empty: `test -s <output-path>`
|
||||
3. If missing or empty, auto-retry once before reporting error
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error | Cause | Fix |
|
||||
|-------|-------|-----|
|
||||
| Authentication failed | Cookies expired or invalid | Run with `--login` to refresh browser auth |
|
||||
| No image output | Generation blocked or failed | Check prompt content; retry once automatically |
|
||||
| Connection error | Network or proxy issue | Verify `HTTP_PROXY`/`HTTPS_PROXY` settings |
|
||||
| Model not available | Invalid model name | Use `gemini-3-pro` (default), `gemini-2.5-pro`, or `gemini-2.5-flash` |
|
||||
|
||||
## EXTEND.md Example
|
||||
|
||||
```md
|
||||
default_model: gemini-3-pro
|
||||
data_dir: /custom/path/to/data
|
||||
```
|
||||
|
||||
## Extension Support
|
||||
|
||||
Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
|
||||
|
|
|
|||
|
|
@ -21,116 +21,32 @@ Scripts located in `scripts/` subdirectory.
|
|||
|
||||
**Before any conversion**, check and obtain consent.
|
||||
|
||||
### Consent Flow
|
||||
|
||||
**Step 1**: Check consent file
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
cat ~/Library/Application\ Support/baoyu-skills/x-to-markdown/consent.json
|
||||
|
||||
# Linux
|
||||
cat ~/.local/share/baoyu-skills/x-to-markdown/consent.json
|
||||
```
|
||||
|
||||
**Step 2**: If `accepted: true` and `disclaimerVersion: "1.0"` → print warning and proceed:
|
||||
```
|
||||
Warning: Using reverse-engineered X API. Accepted on: <acceptedAt>
|
||||
```
|
||||
|
||||
**Step 3**: If missing or version mismatch → display disclaimer:
|
||||
```
|
||||
DISCLAIMER
|
||||
|
||||
This tool uses a reverse-engineered X API, NOT official.
|
||||
|
||||
Risks:
|
||||
- May break if X changes API
|
||||
- No guarantees or support
|
||||
- Possible account restrictions
|
||||
- Use at your own risk
|
||||
|
||||
Accept terms and continue?
|
||||
```
|
||||
|
||||
Use `AskUserQuestion` with options: "Yes, I accept" | "No, I decline"
|
||||
|
||||
**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.
|
||||
1. Check consent file: `~/Library/Application Support/baoyu-skills/x-to-markdown/consent.json` (macOS) or `~/.local/share/baoyu-skills/x-to-markdown/consent.json` (Linux)
|
||||
2. If `accepted: true` and `disclaimerVersion: "1.0"` → print warning and proceed
|
||||
3. If missing or version mismatch → display disclaimer about reverse-engineered API risks, use AskUserQuestion ("Yes, I accept" / "No, I decline")
|
||||
4. On accept → create consent JSON. On decline → stop.
|
||||
|
||||
## Preferences (EXTEND.md)
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
|
||||
```bash
|
||||
# Check project-level first
|
||||
test -f .baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md && echo "project"
|
||||
|
||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||
test -f "$HOME/.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
┌────────────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├────────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ .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 │ **MUST** run first-time setup (see below) — do NOT silently create defaults │
|
||||
└───────────┴───────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
**EXTEND.md Supports**: Download media by default | Default output directory
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md`). If found, read and apply. If not found, run first-time setup (BLOCKING).
|
||||
|
||||
### First-Time Setup (BLOCKING)
|
||||
|
||||
**CRITICAL**: When EXTEND.md is not found, you **MUST use `AskUserQuestion`** to ask the user for their preferences before creating EXTEND.md. **NEVER** create EXTEND.md with defaults without asking. This is a **BLOCKING** operation — do NOT proceed with any conversion until setup is complete.
|
||||
|
||||
Use `AskUserQuestion` with ALL questions in ONE call:
|
||||
|
||||
**Question 1** — header: "Media", question: "How to handle images and videos in tweets?"
|
||||
- "Ask each time (Recommended)" — After saving markdown, ask whether to download media
|
||||
- "Always download" — Always download media to local imgs/ and videos/ directories
|
||||
- "Never download" — Keep original remote URLs in markdown
|
||||
|
||||
**Question 2** — header: "Output", question: "Default output directory?"
|
||||
- "x-to-markdown (Recommended)" — Save to ./x-to-markdown/{username}/{tweet-id}.md
|
||||
- (User may choose "Other" to type a custom path)
|
||||
|
||||
**Question 3** — header: "Save", question: "Where to save preferences?"
|
||||
- "User (Recommended)" — ~/.baoyu-skills/ (all projects)
|
||||
- "Project" — .baoyu-skills/ (this project only)
|
||||
|
||||
After user answers, create EXTEND.md at the chosen location, confirm "Preferences saved to [path]", then continue.
|
||||
Use AskUserQuestion with ALL questions in ONE call:
|
||||
1. **Media** — How to handle images/videos: Ask each time (Recommended) / Always download / Never download
|
||||
2. **Output** — Default output directory: `x-to-markdown` (Recommended) / custom path
|
||||
3. **Save** — Where to save preferences: User home (Recommended) / Project only
|
||||
|
||||
Full reference: [references/config/first-time-setup.md](references/config/first-time-setup.md)
|
||||
|
||||
### Supported Keys
|
||||
|
||||
| Key | Default | Values | Description |
|
||||
|-----|---------|--------|-------------|
|
||||
| `download_media` | `ask` | `ask` / `1` / `0` | `ask` = prompt each time, `1` = always download, `0` = never |
|
||||
| `default_output_dir` | empty | path or empty | Default output directory (empty = `./x-to-markdown/`) |
|
||||
| Key | Default | Description |
|
||||
|-----|---------|-------------|
|
||||
| `download_media` | `ask` | `ask` = prompt each time, `1` = always, `0` = never |
|
||||
| `default_output_dir` | empty | Default output directory (empty = `./x-to-markdown/`) |
|
||||
|
||||
**Value priority**:
|
||||
1. CLI arguments (`--download-media`, `-o`)
|
||||
2. EXTEND.md
|
||||
3. Skill defaults
|
||||
**Priority**: CLI arguments > EXTEND.md > Skill defaults
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
@ -141,14 +57,12 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts <url> --download-media
|
|||
npx -y bun ${SKILL_DIR}/scripts/main.ts <url> --json
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `<url>` | Tweet or article URL |
|
||||
| `-o <path>` | Output path |
|
||||
| `--json` | JSON output |
|
||||
| `--download-media` | Download image/video assets to local `imgs/` and `videos/`, and rewrite markdown links to local relative paths |
|
||||
| `--download-media` | Download image/video assets locally, rewrite links |
|
||||
| `--login` | Refresh cookies only |
|
||||
|
||||
## Supported URLs
|
||||
|
|
@ -172,31 +86,11 @@ Content...
|
|||
|
||||
**File structure**: `x-to-markdown/{username}/{tweet-id}.md`
|
||||
|
||||
When `--download-media` is enabled:
|
||||
- Images are saved to `imgs/` next to the markdown file
|
||||
- Videos are saved to `videos/` next to the markdown file
|
||||
- Markdown media links are rewritten to local relative paths
|
||||
With `--download-media`: images saved to `imgs/`, videos to `videos/`, links rewritten to local paths.
|
||||
|
||||
## Media Download Workflow
|
||||
|
||||
Based on `download_media` setting in EXTEND.md:
|
||||
|
||||
| Setting | Behavior |
|
||||
|---------|----------|
|
||||
| `1` (always) | Run script with `--download-media` flag |
|
||||
| `0` (never) | Run script without `--download-media` flag |
|
||||
| `ask` (default) | Follow the ask-each-time flow below |
|
||||
|
||||
### Ask-Each-Time Flow
|
||||
|
||||
1. Run script **without** `--download-media` → markdown saved
|
||||
2. Check saved markdown for remote media URLs (`https://` in image/video links)
|
||||
3. **If no remote media found** → done, no prompt needed
|
||||
4. **If remote media found** → use `AskUserQuestion`:
|
||||
- header: "Media", question: "Download N images/videos to local files?"
|
||||
- "Yes" — Download to local directories
|
||||
- "No" — Keep remote URLs
|
||||
5. If user confirms → run script **again** with `--download-media` (overwrites markdown with localized links)
|
||||
Based on `download_media` setting: `1` → run with `--download-media`, `0` → run without, `ask` → run without first, then check for remote media URLs in output. If found, use AskUserQuestion to offer download. If confirmed, re-run with `--download-media`.
|
||||
|
||||
## Authentication
|
||||
|
||||
|
|
|
|||
|
|
@ -19,33 +19,9 @@ Scripts in `scripts/` subdirectory. Replace `${SKILL_DIR}` with this SKILL.md's
|
|||
|
||||
## Preferences (EXTEND.md)
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-format-markdown/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-format-markdown/EXTEND.md`). If found, read and apply settings. If not found, use defaults.
|
||||
|
||||
```bash
|
||||
# Check project-level first
|
||||
test -f .baoyu-skills/baoyu-format-markdown/EXTEND.md && echo "project"
|
||||
|
||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||
test -f "$HOME/.baoyu-skills/baoyu-format-markdown/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
┌──────────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├──────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ .baoyu-skills/baoyu-format-markdown/EXTEND.md │ Project directory │
|
||||
├──────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ $HOME/.baoyu-skills/baoyu-format-markdown/EXTEND.md │ User home │
|
||||
└──────────────────────────────────────────────────────────┴───────────────────┘
|
||||
|
||||
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
|
||||
│ Result │ Action │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Found │ Read, parse, apply settings │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Not found │ Use defaults │
|
||||
└───────────┴───────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
**EXTEND.md Supports**: Default formatting options | Summary length preferences
|
||||
**Supports**: Default formatting options | Summary length preferences
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
@ -59,151 +35,48 @@ Read the user-specified markdown or plain text file.
|
|||
|
||||
### Step 1.5: Detect Content Type & Confirm
|
||||
|
||||
**Content Type Detection:**
|
||||
Detect if input is plain text (no markdown syntax) or markdown (has frontmatter, headings, bold, lists, code blocks, or blockquotes).
|
||||
|
||||
| Indicator | Classification |
|
||||
|-----------|----------------|
|
||||
| Has `---` YAML frontmatter | Markdown |
|
||||
| Has `#`, `##`, `###` headings | Markdown |
|
||||
| Has `**bold**`, `*italic*` | Markdown |
|
||||
| Has `- ` or `1. ` lists | Markdown |
|
||||
| Has ``` code blocks | Markdown |
|
||||
| Has `> ` blockquotes | Markdown |
|
||||
| None of above | Plain text |
|
||||
|
||||
**Decision Flow:**
|
||||
|
||||
┌─────────────────┬────────────────────────────────────────────────┐
|
||||
│ Content Type │ Action │
|
||||
├─────────────────┼────────────────────────────────────────────────┤
|
||||
│ Plain text │ Proceed to Step 2 (format to markdown) │
|
||||
├─────────────────┼────────────────────────────────────────────────┤
|
||||
│ Markdown │ Use AskUserQuestion to confirm optimization │
|
||||
└─────────────────┴────────────────────────────────────────────────┘
|
||||
|
||||
**If Markdown detected, ask user:**
|
||||
|
||||
```
|
||||
Detected existing markdown formatting. What would you like to do?
|
||||
|
||||
1. Optimize formatting (Recommended)
|
||||
- Add/improve frontmatter, headings, bold, lists
|
||||
- Run typography script (spacing, emphasis fixes)
|
||||
- Output: {filename}-formatted.md
|
||||
|
||||
2. Keep original formatting
|
||||
- Preserve existing markdown structure
|
||||
- Run typography script (spacing, emphasis fixes)
|
||||
- Output: {filename}-formatted.md
|
||||
|
||||
3. Typography fixes only
|
||||
- Run typography script on original file in-place
|
||||
- No copy created, modifies original file directly
|
||||
```
|
||||
|
||||
**Based on user choice:**
|
||||
- **Optimize**: Continue to Step 2-8 (full workflow)
|
||||
- **Keep original**: Skip Steps 2-5, copy file → Step 6-8 (run script on copy)
|
||||
- **Typography only**: Skip Steps 2-6, run Step 7 on original file directly
|
||||
- **Plain text** → Proceed to Step 2 (full formatting)
|
||||
- **Markdown detected** → Use AskUserQuestion with 3 options:
|
||||
1. **Optimize formatting** (Recommended): Full workflow Steps 2-8
|
||||
2. **Keep original formatting**: Skip Steps 2-5, copy file → Steps 6-8
|
||||
3. **Typography fixes only**: Skip Steps 2-6, run Step 7 on original file directly
|
||||
|
||||
### Step 2: Analyze Content Structure
|
||||
|
||||
Identify:
|
||||
- Existing title (H1 `#`)
|
||||
- Paragraph separations
|
||||
- Keywords suitable for **bold**
|
||||
- Parallel content convertible to lists
|
||||
- Code snippets
|
||||
- Quotations
|
||||
Identify: existing title (H1), paragraph separations, keywords suitable for **bold**, parallel content convertible to lists, code snippets, and quotations.
|
||||
|
||||
### Step 3: Check/Create Frontmatter
|
||||
|
||||
Check for YAML frontmatter (`---` block). Create if missing.
|
||||
|
||||
**Meta field handling:**
|
||||
|
||||
| Field | Processing |
|
||||
|-------|------------|
|
||||
| `title` | See Step 4 |
|
||||
| `slug` | Infer from file path (e.g., `posts/2026/01/10/vibe-coding/` → `vibe-coding`) or generate from title |
|
||||
| `slug` | Infer from file path or generate from title |
|
||||
| `summary` | Generate engaging summary (100-150 characters) |
|
||||
| `coverImage` | Check if `imgs/cover.png` exists in same directory; if so, use relative path (also accepted: `featureImage`) |
|
||||
| `coverImage` | Check if `imgs/cover.png` exists in same directory (also accepted: `featureImage`) |
|
||||
|
||||
### Step 4: Title Handling
|
||||
|
||||
**Logic:**
|
||||
1. If frontmatter already has `title` → use it, no H1 in body
|
||||
2. If first line is H1 → extract to frontmatter `title`, remove H1 from body
|
||||
3. If neither exists → generate candidate titles
|
||||
3. If neither exists → generate 3 candidate titles, use AskUserQuestion to let user choose
|
||||
|
||||
**Title generation flow:**
|
||||
|
||||
1. Generate 3 candidate titles based on content
|
||||
2. Use `AskUserQuestion` tool:
|
||||
|
||||
```
|
||||
Select a title:
|
||||
|
||||
1. [Title A] (Recommended)
|
||||
2. [Title B]
|
||||
3. [Title C]
|
||||
```
|
||||
|
||||
3. If no selection within a few seconds, use recommended (option 1)
|
||||
|
||||
**Title principles:**
|
||||
- Concise, max 20 characters
|
||||
- Captures core message
|
||||
- Engaging, sparks reading interest
|
||||
- Accurate, avoids clickbait
|
||||
|
||||
**Important:** Once title is in frontmatter, body should NOT have H1 (avoid duplication)
|
||||
**Title principles**: Concise (max 20 chars), captures core message, engaging, accurate. Once title is in frontmatter, body should NOT have H1.
|
||||
|
||||
### Step 5: Format Processing
|
||||
|
||||
**Formatting rules:**
|
||||
Apply formatting: heading hierarchy (`#`, `##`, `###`), **bold** for key points, lists for parallel items, code blocks/inline code, blockquotes, and `---` separators.
|
||||
|
||||
| Element | Format |
|
||||
|---------|--------|
|
||||
| Titles | Use `#`, `##`, `###` hierarchy |
|
||||
| Key points | Use `**bold**` |
|
||||
| Parallel items | Convert to `-` unordered or `1.` ordered lists |
|
||||
| Code/commands | Use `` `inline` `` or ` ```block``` ` |
|
||||
| Quotes/sayings | Use `>` blockquote |
|
||||
| Separators | Use `---` where appropriate |
|
||||
|
||||
**Formatting principles:**
|
||||
- Preserve original content and viewpoints
|
||||
- Add formatting only, do not modify text
|
||||
- Formatting serves readability
|
||||
- Avoid over-formatting
|
||||
**Principles**: Preserve original content, add formatting only, serve readability, avoid over-formatting.
|
||||
|
||||
### Step 6: Save Formatted File
|
||||
|
||||
Save as `{original-filename}-formatted.md`
|
||||
Save as `{original-filename}-formatted.md`. If file exists, backup to `{filename}-formatted.backup-YYYYMMDD-HHMMSS.md` first.
|
||||
|
||||
Examples:
|
||||
- `final.md` → `final-formatted.md`
|
||||
- `draft-v1.md` → `draft-v1-formatted.md`
|
||||
|
||||
**If user chose "Keep original formatting" (from Step 1.5):**
|
||||
- Copy original file to `{filename}-formatted.md` without modifications
|
||||
- Proceed to Step 7 for typography fixes only
|
||||
|
||||
**Backup existing file:**
|
||||
|
||||
If `{filename}-formatted.md` already exists, backup before overwriting:
|
||||
|
||||
```bash
|
||||
# Check if formatted file exists
|
||||
if [ -f "{filename}-formatted.md" ]; then
|
||||
# Backup with timestamp
|
||||
mv "{filename}-formatted.md" "{filename}-formatted.backup-$(date +%Y%m%d-%H%M%S).md"
|
||||
fi
|
||||
```
|
||||
|
||||
Example:
|
||||
- `final-formatted.md` exists → backup to `final-formatted.backup-20260128-143052.md`
|
||||
If user chose "Keep original formatting", copy original to `{filename}-formatted.md` without modifications.
|
||||
|
||||
### Step 7: Execute Text Formatting Script
|
||||
|
||||
|
|
@ -213,39 +86,13 @@ After saving, **must** run the formatting script:
|
|||
npx -y bun ${SKILL_DIR}/scripts/main.ts {output-file-path} [options]
|
||||
```
|
||||
|
||||
**Script Options:**
|
||||
| Option | Description | Default |
|
||||
|--------|-------------|---------|
|
||||
| `--quotes` / `-q` | Replace ASCII quotes with fullwidth quotes | false |
|
||||
| `--spacing` / `-s` | Add CJK/English spacing via autocorrect | true |
|
||||
| `--emphasis` / `-e` | Fix CJK emphasis punctuation issues | true |
|
||||
|
||||
| Option | Short | Description | Default |
|
||||
|--------|-------|-------------|---------|
|
||||
| `--quotes` | `-q` | Replace ASCII quotes with fullwidth quotes `"..."` | false |
|
||||
| `--no-quotes` | | Do not replace quotes | |
|
||||
| `--spacing` | `-s` | Add CJK/English spacing via autocorrect | true |
|
||||
| `--no-spacing` | | Do not add CJK/English spacing | |
|
||||
| `--emphasis` | `-e` | Fix CJK emphasis punctuation issues | true |
|
||||
| `--no-emphasis` | | Do not fix CJK emphasis issues | |
|
||||
| `--help` | `-h` | Show help message | |
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Default: spacing + emphasis enabled, quotes disabled
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts article.md
|
||||
|
||||
# Enable all features including quote replacement
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts article.md --quotes
|
||||
|
||||
# Only fix emphasis issues, skip spacing
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts article.md --no-spacing
|
||||
|
||||
# Disable all processing except frontmatter formatting
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts article.md --no-spacing --no-emphasis
|
||||
```
|
||||
|
||||
**Script performs (based on options):**
|
||||
1. Fix CJK emphasis/bold punctuation issues (default: enabled)
|
||||
2. Add CJK/English mixed text spacing via autocorrect (default: enabled)
|
||||
3. Replace ASCII quotes `"..."` with fullwidth quotes `"..."` (default: disabled)
|
||||
4. Format frontmatter YAML (always enabled)
|
||||
Use `--no-quotes`, `--no-spacing`, `--no-emphasis` to disable individual features.
|
||||
|
||||
### Step 8: Display Results
|
||||
|
||||
|
|
|
|||
|
|
@ -117,27 +117,9 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provi
|
|||
|
||||
## Replicate Model Configuration
|
||||
|
||||
When using `--provider replicate`, the model can be configured in the following ways (highest priority first):
|
||||
Model priority: CLI `--model` > EXTEND.md `default_model.replicate` > env `REPLICATE_IMAGE_MODEL` > default `google/nano-banana-pro`.
|
||||
|
||||
1. CLI flag: `--model <owner/name>`
|
||||
2. EXTEND.md: `default_model.replicate`
|
||||
3. Env var: `REPLICATE_IMAGE_MODEL`
|
||||
4. Built-in default: `google/nano-banana-pro`
|
||||
|
||||
Supported model formats:
|
||||
|
||||
- `owner/name` (recommended for official models), e.g. `google/nano-banana-pro`
|
||||
- `owner/name:version` (community models by version), e.g. `stability-ai/sdxl:<version>`
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
# Use Replicate default model
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate
|
||||
|
||||
# Override model explicitly
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate --model google/nano-banana
|
||||
```
|
||||
Model formats: `owner/name` (official) or `owner/name:version` (community).
|
||||
|
||||
## Provider Selection
|
||||
|
||||
|
|
@ -189,12 +171,21 @@ Supported: `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `2.35:1`
|
|||
# Collect results via TaskOutput when all complete
|
||||
```
|
||||
|
||||
## Post-Generation Validation
|
||||
|
||||
After each image generation:
|
||||
1. Verify output file exists: `test -f <output-path>`
|
||||
2. Check file is non-empty: `test -s <output-path>`
|
||||
3. If missing or empty, auto-retry once before reporting error
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Missing API key → error with setup instructions
|
||||
- Generation failure → auto-retry once
|
||||
- Invalid aspect ratio → warning, proceed with default
|
||||
- Reference images with unsupported provider/model → error with fix hint (switch to Google multimodal or OpenAI GPT Image edits)
|
||||
| Error | Cause | Fix |
|
||||
|-------|-------|-----|
|
||||
| Missing API key | No key for selected provider | Set the appropriate env var (e.g., `GOOGLE_API_KEY`) |
|
||||
| Generation failure | API error or timeout | Auto-retries once; if persistent, try different provider |
|
||||
| Invalid aspect ratio | Unsupported ratio for provider | Falls back to default; use supported ratios |
|
||||
| Reference image error | Provider doesn't support `--ref` | Switch to Google multimodal or OpenAI GPT Image edits |
|
||||
|
||||
## Extension Support
|
||||
|
||||
|
|
|
|||
|
|
@ -17,81 +17,23 @@ Converts Markdown files to beautifully styled HTML with inline CSS, optimized fo
|
|||
|
||||
## Preferences (EXTEND.md)
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-markdown-to-html/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-markdown-to-html/EXTEND.md`). If found, read and apply settings. If not found, use defaults.
|
||||
|
||||
```bash
|
||||
# Check project-level first
|
||||
test -f .baoyu-skills/baoyu-markdown-to-html/EXTEND.md && echo "project"
|
||||
|
||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||
test -f "$HOME/.baoyu-skills/baoyu-markdown-to-html/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
┌──────────────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├──────────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ .baoyu-skills/baoyu-markdown-to-html/EXTEND.md │ Project directory │
|
||||
├──────────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ $HOME/.baoyu-skills/baoyu-markdown-to-html/EXTEND.md │ User home │
|
||||
└──────────────────────────────────────────────────────────────┴───────────────────┘
|
||||
|
||||
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
|
||||
│ Result │ Action │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Found │ Read, parse, apply settings │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Not found │ Use defaults │
|
||||
└───────────┴───────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
**EXTEND.md Supports**: Default theme | Custom CSS variables | Code block style
|
||||
**Supports**: Default theme | Custom CSS variables | Code block style
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 0: Pre-check (Chinese Content)
|
||||
|
||||
**Condition**: Only execute if input file contains Chinese text.
|
||||
|
||||
**Detection**:
|
||||
1. Read input markdown file
|
||||
2. Check if content contains CJK characters (Chinese/Japanese/Korean)
|
||||
3. If no CJK content → skip to Step 1
|
||||
|
||||
**Format Suggestion**:
|
||||
|
||||
If CJK content detected AND `baoyu-format-markdown` skill is available:
|
||||
|
||||
Use `AskUserQuestion` to ask whether to format first. Formatting can fix:
|
||||
- Bold markers with punctuation inside causing `**` parse failures
|
||||
- CJK/English spacing issues
|
||||
|
||||
**If user agrees**: Invoke `baoyu-format-markdown` skill to format the file, then use formatted file as input.
|
||||
|
||||
**If user declines**: Continue with original file.
|
||||
Only if input contains CJK characters: suggest running `baoyu-format-markdown` first to fix bold/emphasis parsing and CJK/English spacing. Use AskUserQuestion to confirm. Skip if no CJK content.
|
||||
|
||||
### Step 1: Determine Theme
|
||||
|
||||
**Theme resolution order** (first match wins):
|
||||
1. User explicitly specified theme (CLI `--theme` or conversation)
|
||||
2. EXTEND.md `default_theme` (this skill's own EXTEND.md, checked in Step 0)
|
||||
3. `baoyu-post-to-wechat` EXTEND.md `default_theme` (cross-skill fallback)
|
||||
4. If none found → use AskUserQuestion to confirm
|
||||
|
||||
**Cross-skill EXTEND.md check** (only if this skill's EXTEND.md has no `default_theme`):
|
||||
|
||||
```bash
|
||||
# Check baoyu-post-to-wechat EXTEND.md for default_theme
|
||||
test -f "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md" && grep -o 'default_theme:.*' "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md"
|
||||
```
|
||||
|
||||
**If theme is resolved from EXTEND.md**: Use it directly, do NOT ask the user.
|
||||
|
||||
**If no default found**: Use AskUserQuestion to confirm:
|
||||
|
||||
| Theme | Description |
|
||||
|-------|-------------|
|
||||
| `default` (Recommended) | 经典主题 - 传统排版,标题居中带底边,二级标题白字彩底 |
|
||||
| `grace` | 优雅主题 - 文字阴影,圆角卡片,精致引用块 |
|
||||
| `simple` | 简洁主题 - 现代极简风,不对称圆角,清爽留白 |
|
||||
2. EXTEND.md `default_theme` (this skill's own EXTEND.md)
|
||||
3. `baoyu-post-to-wechat` EXTEND.md `default_theme` (cross-skill fallback via `grep -o 'default_theme:.*' "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md"`)
|
||||
4. If none found → use AskUserQuestion to confirm (see Themes section below)
|
||||
|
||||
### Step 2: Convert
|
||||
|
||||
|
|
@ -99,9 +41,12 @@ test -f "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md" && grep -o 'default
|
|||
npx -y bun ${SKILL_DIR}/scripts/main.ts <markdown_file> --theme <theme>
|
||||
```
|
||||
|
||||
### Step 3: Report Result
|
||||
### Step 3: Validate & Report Result
|
||||
|
||||
Display the output path from JSON result. If backup was created, mention it.
|
||||
1. Parse JSON output from the script
|
||||
2. Verify `htmlPath` exists and is non-empty: `test -s <htmlPath>`
|
||||
3. If conversion failed or output is empty, report the error from JSON output
|
||||
4. Display the output path. If backup was created, mention it.
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
@ -109,14 +54,11 @@ Display the output path from JSON result. If backup was created, mention it.
|
|||
npx -y bun ${SKILL_DIR}/scripts/main.ts <markdown_file> [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
|
||||
| Option | Description | Default |
|
||||
|--------|-------------|---------|
|
||||
| `--theme <name>` | Theme name (default, grace, simple) | default |
|
||||
| `--title <title>` | Override title from frontmatter | |
|
||||
| `--keep-title` | Keep the first heading in content | false (removed) |
|
||||
| `--help` | Show help | |
|
||||
|
||||
**Examples:**
|
||||
|
||||
|
|
@ -129,38 +71,15 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts article.md --theme grace
|
|||
|
||||
# Keep the first heading in content
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts article.md --keep-title
|
||||
|
||||
# Override title
|
||||
npx -y bun ${SKILL_DIR}/scripts/main.ts article.md --title "My Article"
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
**File location**: Same directory as input markdown file.
|
||||
- Input: `/path/to/article.md`
|
||||
- Output: `/path/to/article.html`
|
||||
**File location**: Same directory as input (e.g., `/path/to/article.md` → `/path/to/article.html`).
|
||||
|
||||
**Conflict handling**: If HTML file already exists, it will be backed up first:
|
||||
- Backup: `/path/to/article.html.bak-YYYYMMDDHHMMSS`
|
||||
**Conflict handling**: Existing HTML file backed up to `article.html.bak-YYYYMMDDHHMMSS`.
|
||||
|
||||
**JSON output to stdout:**
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "Article Title",
|
||||
"author": "Author Name",
|
||||
"summary": "Article summary...",
|
||||
"htmlPath": "/path/to/article.html",
|
||||
"backupPath": "/path/to/article.html.bak-20260128180000",
|
||||
"contentImages": [
|
||||
{
|
||||
"placeholder": "MDTOHTMLIMGPH_1",
|
||||
"localPath": "/path/to/img.png",
|
||||
"originalPath": "imgs/image.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
**JSON output to stdout** includes: `title`, `author`, `summary`, `htmlPath`, `backupPath`, `contentImages` array.
|
||||
|
||||
## Themes
|
||||
|
||||
|
|
@ -170,38 +89,11 @@ npx -y bun ${SKILL_DIR}/scripts/main.ts article.md --title "My Article"
|
|||
| `grace` | 优雅主题 - 文字阴影,圆角卡片,精致引用块 (by @brzhang) |
|
||||
| `simple` | 简洁主题 - 现代极简风,不对称圆角,清爽留白 (by @okooo5km) |
|
||||
|
||||
## Supported Markdown Features
|
||||
## Supported Features
|
||||
|
||||
| Feature | Syntax |
|
||||
|---------|--------|
|
||||
| Headings | `# H1` to `###### H6` |
|
||||
| Bold/Italic | `**bold**`, `*italic*` |
|
||||
| Code blocks | ` ```lang ` with syntax highlighting |
|
||||
| Inline code | `` `code` `` |
|
||||
| Tables | GitHub-flavored markdown tables |
|
||||
| Images | `` |
|
||||
| Links | `[text](url)` with footnote references |
|
||||
| Blockquotes | `> quote` |
|
||||
| Lists | `-` unordered, `1.` ordered |
|
||||
| Alerts | `> [!NOTE]`, `> [!WARNING]`, etc. |
|
||||
| Footnotes | `[^1]` references |
|
||||
| Ruby text | `{base|annotation}` |
|
||||
| Mermaid | ` ```mermaid ` diagrams |
|
||||
| PlantUML | ` ```plantuml ` diagrams |
|
||||
Standard GitHub-flavored markdown plus: alerts (`> [!NOTE]`), footnotes, ruby text (`{base|annotation}`), Mermaid diagrams, and PlantUML diagrams.
|
||||
|
||||
## Frontmatter
|
||||
|
||||
Supports YAML frontmatter for metadata:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: Article Title
|
||||
author: Author Name
|
||||
description: Article summary
|
||||
---
|
||||
```
|
||||
|
||||
If no title is found, extracts from first H1/H2 heading or uses filename.
|
||||
Supports YAML frontmatter (`title`, `author`, `description`). If no title is found, extracts from first H1/H2 heading or uses filename.
|
||||
|
||||
## Extension Support
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ description: Posts content to WeChat Official Account (微信公众号) via API
|
|||
|
||||
## Language
|
||||
|
||||
**Match user's language**: Respond in the same language the user uses. If user writes in Chinese, respond in Chinese. If user writes in English, respond in English.
|
||||
**Match user's language**: Respond in the same language the user uses.
|
||||
|
||||
## Script Directory
|
||||
|
||||
|
|
@ -22,84 +22,28 @@ description: Posts content to WeChat Official Account (微信公众号) via API
|
|||
|
||||
## Preferences (EXTEND.md)
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-post-to-wechat/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md`). If found, read and apply. If not found, run first-time setup ([references/config/first-time-setup.md](references/config/first-time-setup.md)).
|
||||
|
||||
```bash
|
||||
# Check project-level first
|
||||
test -f .baoyu-skills/baoyu-post-to-wechat/EXTEND.md && echo "project"
|
||||
**Supports**: Default theme | Publishing method (api/browser) | Default author | Comment settings | Chrome profile path
|
||||
|
||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||
test -f "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md" && echo "user"
|
||||
```
|
||||
**Minimum supported keys**:
|
||||
|
||||
┌────────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ .baoyu-skills/baoyu-post-to-wechat/EXTEND.md │ Project directory │
|
||||
├────────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ $HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md │ User home │
|
||||
└────────────────────────────────────────────────────────┴───────────────────┘
|
||||
| Key | Default | Description |
|
||||
|-----|---------|-------------|
|
||||
| `default_author` | empty | Fallback author |
|
||||
| `need_open_comment` | `1` | Enable comments |
|
||||
| `only_fans_can_comment` | `0` | Restrict to fans |
|
||||
|
||||
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
|
||||
│ Result │ Action │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Found │ Read, parse, apply settings │
|
||||
├───────────┼───────────────────────────────────────────────────────────────────────────┤
|
||||
│ Not found │ Run first-time setup ([references/config/first-time-setup.md](references/config/first-time-setup.md)) → Save → Continue │
|
||||
└───────────┴───────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
**EXTEND.md Supports**: Default theme | Default publishing method (api/browser) | Default author | Default open-comment switch | Default fans-only-comment switch | Chrome profile path
|
||||
|
||||
First-time setup: [references/config/first-time-setup.md](references/config/first-time-setup.md)
|
||||
|
||||
**Minimum supported keys** (case-insensitive, accept `1/0` or `true/false`):
|
||||
|
||||
| Key | Default | Mapping |
|
||||
|-----|---------|---------|
|
||||
| `default_author` | empty | Fallback for `author` when CLI/frontmatter not provided |
|
||||
| `need_open_comment` | `1` | `articles[].need_open_comment` in `draft/add` request |
|
||||
| `only_fans_can_comment` | `0` | `articles[].only_fans_can_comment` in `draft/add` request |
|
||||
|
||||
**Recommended EXTEND.md example**:
|
||||
|
||||
```md
|
||||
default_theme: default
|
||||
default_publish_method: api
|
||||
default_author: 宝玉
|
||||
need_open_comment: 1
|
||||
only_fans_can_comment: 0
|
||||
chrome_profile_path: /path/to/chrome/profile
|
||||
```
|
||||
|
||||
**Value priority**:
|
||||
1. CLI arguments
|
||||
2. Frontmatter
|
||||
3. EXTEND.md
|
||||
4. Skill defaults
|
||||
**Priority**: CLI > Frontmatter > EXTEND.md > Defaults
|
||||
|
||||
## Pre-flight Check (Optional)
|
||||
|
||||
Before first use, suggest running the environment check. User can skip if they prefer.
|
||||
|
||||
```bash
|
||||
npx -y bun ${SKILL_DIR}/scripts/check-permissions.ts
|
||||
```
|
||||
|
||||
Checks: Chrome, profile isolation, Bun, Accessibility, clipboard, paste keystroke, API credentials, Chrome conflicts.
|
||||
|
||||
**If any check fails**, provide fix guidance per item:
|
||||
|
||||
| Check | Fix |
|
||||
|-------|-----|
|
||||
| Chrome | Install Chrome or set `WECHAT_BROWSER_CHROME_PATH` env var |
|
||||
| Profile dir | Ensure `~/.local/share/wechat-browser-profile` is writable |
|
||||
| Bun runtime | `curl -fsSL https://bun.sh/install \| bash` |
|
||||
| Accessibility (macOS) | System Settings → Privacy & Security → Accessibility → enable terminal app |
|
||||
| Clipboard copy | Ensure Swift/AppKit available (macOS Xcode CLI tools: `xcode-select --install`) |
|
||||
| Paste keystroke (macOS) | Same as Accessibility fix above |
|
||||
| Paste keystroke (Linux) | Install `xdotool` (X11) or `ydotool` (Wayland) |
|
||||
| API credentials | Follow guided setup in Step 5, or manually set in `.baoyu-skills/.env` |
|
||||
|
||||
## Image-Text Posting (图文)
|
||||
|
||||
For short posts with multiple images (up to 9):
|
||||
|
|
@ -113,298 +57,86 @@ See [references/image-text-posting.md](references/image-text-posting.md) for det
|
|||
|
||||
## Article Posting Workflow (文章)
|
||||
|
||||
Copy this checklist and check off items as you complete them:
|
||||
|
||||
```
|
||||
Publishing Progress:
|
||||
- [ ] Step 0: Load preferences (EXTEND.md)
|
||||
- [ ] Step 1: Determine input type
|
||||
- [ ] Step 2: Check markdown-to-html skill
|
||||
- [ ] Step 3: Convert to HTML
|
||||
- [ ] Step 4: Validate metadata (title, summary, cover)
|
||||
- [ ] Step 5: Select method and configure credentials
|
||||
- [ ] Step 6: Publish to WeChat
|
||||
- [ ] Step 7: Report completion
|
||||
Step 0: Load preferences → Step 1: Determine input type → Step 2: Check md-to-html skill → Step 3: Convert to HTML → Step 4: Validate metadata → Step 5: Select method & credentials → Step 6: Publish → Step 7: Report
|
||||
```
|
||||
|
||||
### Step 0: Load Preferences
|
||||
|
||||
Check and load EXTEND.md settings (see Preferences section above).
|
||||
|
||||
**CRITICAL**: If not found, complete first-time setup BEFORE any other steps or questions.
|
||||
|
||||
Resolve and store these defaults for later steps:
|
||||
- `default_author`
|
||||
- `need_open_comment` (default `1`)
|
||||
- `only_fans_can_comment` (default `0`)
|
||||
Check and load EXTEND.md settings. If not found, complete first-time setup BEFORE any other steps.
|
||||
|
||||
### Step 1: Determine Input Type
|
||||
|
||||
| Input Type | Detection | Action |
|
||||
|------------|-----------|--------|
|
||||
| HTML file | Path ends with `.html`, file exists | Skip to Step 4 |
|
||||
| Markdown file | Path ends with `.md`, file exists | Continue to Step 2 |
|
||||
| Plain text | Not a file path, or file doesn't exist | Save to markdown, then Step 2 |
|
||||
|
||||
**Plain Text Handling**:
|
||||
|
||||
1. Generate slug from content (first 2-4 meaningful words, kebab-case)
|
||||
2. Create directory and save file:
|
||||
|
||||
```bash
|
||||
mkdir -p "$(pwd)/post-to-wechat/$(date +%Y-%m-%d)"
|
||||
# Save content to: post-to-wechat/yyyy-MM-dd/[slug].md
|
||||
```
|
||||
|
||||
3. Continue processing as markdown file
|
||||
|
||||
**Slug Examples**:
|
||||
- "Understanding AI Models" → `understanding-ai-models`
|
||||
- "人工智能的未来" → `ai-future` (translate to English for slug)
|
||||
| Input | Detection | Action |
|
||||
|-------|-----------|--------|
|
||||
| HTML file | `.html` extension | Skip to Step 4 |
|
||||
| Markdown file | `.md` extension | Continue to Step 2 |
|
||||
| Plain text | No file path | Save to `post-to-wechat/YYYY-MM-DD/{slug}.md`, then Step 2 |
|
||||
|
||||
### Step 2: Check Markdown-to-HTML Skill
|
||||
|
||||
**Skip if**: Input is `.html` file
|
||||
|
||||
**Skill Discovery**:
|
||||
|
||||
```bash
|
||||
# Check if baoyu-markdown-to-html exists
|
||||
test -f skills/baoyu-markdown-to-html/SKILL.md && echo "found"
|
||||
```
|
||||
|
||||
| Result | Action |
|
||||
|--------|--------|
|
||||
| Found | Read its SKILL.md, continue to Step 3 |
|
||||
| Multiple skills | AskUserQuestion to choose |
|
||||
| Not found | Show installation suggestion |
|
||||
|
||||
**When Not Found**:
|
||||
|
||||
```
|
||||
No markdown-to-html skill found.
|
||||
|
||||
Suggested installation:
|
||||
https://github.com/JimLiu/baoyu-skills/blob/main/skills/baoyu-markdown-to-html/SKILL.md
|
||||
|
||||
Options:
|
||||
A) Cancel - install the skill first
|
||||
B) Continue - provide HTML file manually
|
||||
```
|
||||
Skip if input is HTML. Check `skills/baoyu-markdown-to-html/SKILL.md` exists. If not found, suggest installation.
|
||||
|
||||
### Step 3: Convert Markdown to HTML
|
||||
|
||||
**Skip if**: Input is `.html` file
|
||||
|
||||
1. **Resolve theme** (first match wins, do NOT ask user if resolved):
|
||||
- CLI `--theme` argument
|
||||
- EXTEND.md `default_theme` (loaded in Step 0)
|
||||
- Fallback: `default`
|
||||
|
||||
2. **Execute conversion** (using the discovered skill), **always pass `--theme`**:
|
||||
Theme resolution (first match, do NOT ask if resolved): CLI `--theme` → EXTEND.md `default_theme` → `default`.
|
||||
|
||||
```bash
|
||||
npx -y bun ${MD_TO_HTML_SKILL_DIR}/scripts/main.ts <markdown_file> --theme <theme>
|
||||
```
|
||||
|
||||
**CRITICAL**: Always include `--theme` parameter. Never omit it, even if using `default`.
|
||||
|
||||
3. **Parse JSON output** to get: `htmlPath`, `title`, `author`, `summary`, `contentImages`
|
||||
**CRITICAL**: Always include `--theme`. Parse JSON output for `htmlPath`, `title`, `author`, `summary`, `contentImages`.
|
||||
|
||||
### Step 4: Validate Metadata
|
||||
|
||||
Check extracted metadata from Step 3 (or HTML meta tags if direct HTML input).
|
||||
|
||||
| Field | If Missing |
|
||||
|-------|------------|
|
||||
| Title | Prompt: "Enter title, or press Enter to auto-generate from content" |
|
||||
| Summary | Prompt: "Enter summary, or press Enter to auto-generate (recommended for SEO)" |
|
||||
| Author | Use fallback chain: CLI `--author` → frontmatter `author` → EXTEND.md `default_author` |
|
||||
|
||||
**Auto-Generation Logic**:
|
||||
- **Title**: First H1/H2 heading, or first sentence
|
||||
- **Summary**: First paragraph, truncated to 120 characters
|
||||
|
||||
**Cover Image Check** (required for `article_type=news`):
|
||||
1. Use CLI `--cover` if provided.
|
||||
2. Else use frontmatter (`coverImage`, `featureImage`, `cover`, `image`).
|
||||
3. Else check article directory default path: `imgs/cover.png`.
|
||||
4. Else fallback to first inline content image.
|
||||
5. If still missing, stop and request a cover image before publishing.
|
||||
| Title | Prompt or auto-generate from first heading |
|
||||
| Summary | Prompt or auto-generate (first paragraph, 120 chars) |
|
||||
| Author | Fallback chain: CLI → frontmatter → EXTEND.md `default_author` |
|
||||
| Cover | CLI `--cover` → frontmatter → `imgs/cover.png` → first inline image → stop and request |
|
||||
|
||||
### Step 5: Select Publishing Method and Configure
|
||||
|
||||
**Ask publishing method** (unless specified in EXTEND.md or CLI):
|
||||
|
||||
| Method | Speed | Requirements |
|
||||
|--------|-------|--------------|
|
||||
| `api` (Recommended) | Fast | API credentials |
|
||||
| `api` (Recommended) | Fast | API credentials (WECHAT_APP_ID, WECHAT_APP_SECRET in `.baoyu-skills/.env`) |
|
||||
| `browser` | Slow | Chrome, login session |
|
||||
|
||||
**If API Selected - Check Credentials**:
|
||||
|
||||
```bash
|
||||
# Check project-level
|
||||
test -f .baoyu-skills/.env && grep -q "WECHAT_APP_ID" .baoyu-skills/.env && echo "project"
|
||||
|
||||
# Check user-level
|
||||
test -f "$HOME/.baoyu-skills/.env" && grep -q "WECHAT_APP_ID" "$HOME/.baoyu-skills/.env" && echo "user"
|
||||
```
|
||||
|
||||
**If Credentials Missing - Guide Setup**:
|
||||
|
||||
```
|
||||
WeChat API credentials not found.
|
||||
|
||||
To obtain credentials:
|
||||
1. Visit https://mp.weixin.qq.com
|
||||
2. Go to: 开发 → 基本配置
|
||||
3. Copy AppID and AppSecret
|
||||
|
||||
Where to save?
|
||||
A) Project-level: .baoyu-skills/.env (this project only)
|
||||
B) User-level: ~/.baoyu-skills/.env (all projects)
|
||||
```
|
||||
|
||||
After location choice, prompt for values and write to `.env`:
|
||||
|
||||
```
|
||||
WECHAT_APP_ID=<user_input>
|
||||
WECHAT_APP_SECRET=<user_input>
|
||||
```
|
||||
If API selected and credentials missing, guide setup via `mp.weixin.qq.com` → 开发 → 基本配置.
|
||||
|
||||
### Step 6: Publish to WeChat
|
||||
|
||||
**API method**:
|
||||
**API**: `npx -y bun ${SKILL_DIR}/scripts/wechat-api.ts <html_file> [--title <title>] [--summary <summary>] [--author <author>] [--cover <cover_path>]`
|
||||
|
||||
```bash
|
||||
npx -y bun ${SKILL_DIR}/scripts/wechat-api.ts <html_file> [--title <title>] [--summary <summary>] [--author <author>] [--cover <cover_path>]
|
||||
```
|
||||
Always resolve and include `need_open_comment` and `only_fans_can_comment` in the draft/add request.
|
||||
|
||||
**`draft/add` payload rules**:
|
||||
- Use endpoint: `POST https://api.weixin.qq.com/cgi-bin/draft/add?access_token=ACCESS_TOKEN`
|
||||
- `article_type`: `news` (default) or `newspic`
|
||||
- For `news`, include `thumb_media_id` (cover is required)
|
||||
- Always resolve and send:
|
||||
- `need_open_comment` (default `1`)
|
||||
- `only_fans_can_comment` (default `0`)
|
||||
- `author` resolution: CLI `--author` → frontmatter `author` → EXTEND.md `default_author`
|
||||
|
||||
If script parameters do not expose the two comment fields, still ensure final API request body includes resolved values.
|
||||
|
||||
**Browser method**:
|
||||
|
||||
```bash
|
||||
npx -y bun ${SKILL_DIR}/scripts/wechat-article.ts --html <html_file>
|
||||
```
|
||||
**Browser**: `npx -y bun ${SKILL_DIR}/scripts/wechat-article.ts --html <html_file>`
|
||||
|
||||
### Step 7: Completion Report
|
||||
|
||||
**For API method**, include draft management link:
|
||||
|
||||
```
|
||||
WeChat Publishing Complete!
|
||||
|
||||
Input: [type] - [path]
|
||||
Method: API
|
||||
Theme: [theme name]
|
||||
|
||||
Article:
|
||||
• Title: [title]
|
||||
• Summary: [summary]
|
||||
• Images: [N] inline images
|
||||
• Comments: [open/closed], [fans-only/all users]
|
||||
|
||||
Result:
|
||||
✓ Draft saved to WeChat Official Account
|
||||
• media_id: [media_id]
|
||||
|
||||
Next Steps:
|
||||
→ Manage drafts: https://mp.weixin.qq.com (登录后进入「内容管理」→「草稿箱」)
|
||||
|
||||
Files created:
|
||||
[• post-to-wechat/yyyy-MM-dd/slug.md (if plain text)]
|
||||
[• slug.html (converted)]
|
||||
```
|
||||
|
||||
**For Browser method**:
|
||||
|
||||
```
|
||||
WeChat Publishing Complete!
|
||||
|
||||
Input: [type] - [path]
|
||||
Method: Browser
|
||||
Theme: [theme name]
|
||||
|
||||
Article:
|
||||
• Title: [title]
|
||||
• Summary: [summary]
|
||||
• Images: [N] inline images
|
||||
|
||||
Result:
|
||||
✓ Draft saved to WeChat Official Account
|
||||
|
||||
Files created:
|
||||
[• post-to-wechat/yyyy-MM-dd/slug.md (if plain text)]
|
||||
[• slug.html (converted)]
|
||||
```
|
||||
|
||||
## Detailed 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) |
|
||||
Report: input type, method, theme, article details (title, summary, image count, comment settings), result (media_id for API), and next steps (manage drafts link for API method).
|
||||
|
||||
## Feature Comparison
|
||||
|
||||
| Feature | Image-Text | Article (API) | Article (Browser) |
|
||||
|---------|------------|---------------|-------------------|
|
||||
| Plain text input | ✗ | ✓ | ✓ |
|
||||
| HTML input | ✗ | ✓ | ✓ |
|
||||
| Markdown input | Title/content | ✓ (via skill) | ✓ (via skill) |
|
||||
| Multiple images | ✓ (up to 9) | ✓ (inline) | ✓ (inline) |
|
||||
| Themes | ✗ | ✓ | ✓ |
|
||||
| Auto-generate metadata | ✗ | ✓ | ✓ |
|
||||
| Default cover fallback (`imgs/cover.png`) | ✗ | ✓ | ✗ |
|
||||
| Comment control (`need_open_comment`, `only_fans_can_comment`) | ✗ | ✓ | ✗ |
|
||||
| Comment control | ✗ | ✓ | ✗ |
|
||||
| Requires Chrome | ✓ | ✗ | ✓ |
|
||||
| Requires API credentials | ✗ | ✓ | ✗ |
|
||||
| Speed | Medium | Fast | Slow |
|
||||
|
||||
## Prerequisites
|
||||
|
||||
**For API method**:
|
||||
- WeChat Official Account API credentials
|
||||
- Guided setup in Step 5, or manually set in `.baoyu-skills/.env`
|
||||
|
||||
**For Browser method**:
|
||||
- Google Chrome
|
||||
- First run: log in to WeChat Official Account (session preserved)
|
||||
|
||||
**For Markdown conversion**:
|
||||
- A markdown-to-html skill (e.g., `baoyu-markdown-to-html`)
|
||||
- If not installed, the workflow will suggest installation
|
||||
|
||||
**Config File Locations** (priority order):
|
||||
1. Environment variables
|
||||
2. `<cwd>/.baoyu-skills/.env`
|
||||
3. `~/.baoyu-skills/.env`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| No markdown-to-html skill | Install `baoyu-markdown-to-html` from suggested URL |
|
||||
| No markdown-to-html skill | Install `baoyu-markdown-to-html` |
|
||||
| Missing API credentials | Follow guided setup in Step 5 |
|
||||
| Access token error | Check if API credentials are valid and not expired |
|
||||
| Not logged in (browser) | First run opens browser - scan QR to log in |
|
||||
| Chrome not found | Set `WECHAT_BROWSER_CHROME_PATH` env var |
|
||||
| Title/summary missing | Use auto-generation or provide manually |
|
||||
| No cover image | Add frontmatter cover or place `imgs/cover.png` in article directory |
|
||||
| Wrong comment defaults | Check `EXTEND.md` keys `need_open_comment` and `only_fans_can_comment` |
|
||||
| Paste fails | Check system clipboard permissions |
|
||||
|
||||
## Extension Support
|
||||
|
||||
Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
|
||||
Custom configurations via EXTEND.md. See **Preferences** section for supported options.
|
||||
|
|
|
|||
|
|
@ -30,33 +30,9 @@ Posts text, images, videos, and long-form articles to X via real Chrome browser
|
|||
|
||||
## Preferences (EXTEND.md)
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-post-to-x/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-post-to-x/EXTEND.md`). If found, read and apply settings. If not found, use defaults.
|
||||
|
||||
```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
|
||||
**Supports**: Default Chrome profile
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
|
@ -108,7 +84,7 @@ npx -y bun ${SKILL_DIR}/scripts/x-browser.ts "Hello!" --image ./photo.png
|
|||
| `--image <path>` | Image file (repeatable, max 4) |
|
||||
| `--profile <dir>` | Custom Chrome profile |
|
||||
|
||||
**Note**: Script opens browser with content filled in. User reviews and publishes manually.
|
||||
**Verify**: After script completes, confirm browser opens with compose dialog showing your content. User reviews and publishes manually.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -127,10 +103,10 @@ npx -y bun ${SKILL_DIR}/scripts/x-video.ts "Check this out!" --video ./clip.mp4
|
|||
| `--video <path>` | Video file (MP4, MOV, WebM) |
|
||||
| `--profile <dir>` | Custom Chrome profile |
|
||||
|
||||
**Note**: Script opens browser with content filled in. User reviews and publishes manually.
|
||||
|
||||
**Limits**: Regular 140s max, Premium 60min. Processing: 30-60s.
|
||||
|
||||
**Verify**: Confirm browser opens with video attached in compose dialog.
|
||||
|
||||
---
|
||||
|
||||
## Quote Tweets
|
||||
|
|
@ -148,7 +124,7 @@ npx -y bun ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123 "Great
|
|||
| `<comment>` | Comment text (positional, optional) |
|
||||
| `--profile <dir>` | Custom Chrome profile |
|
||||
|
||||
**Note**: Script opens browser with content filled in. User reviews and publishes manually.
|
||||
**Verify**: Confirm browser opens with quoted tweet and comment in compose dialog.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -170,7 +146,7 @@ npx -y bun ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg
|
|||
|
||||
**Frontmatter**: `title`, `cover_image` supported in YAML front matter.
|
||||
|
||||
**Note**: Script opens browser with article filled in. User reviews and publishes manually.
|
||||
**Verify**: Confirm article editor opens with content and cover image loaded.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -189,9 +165,5 @@ pkill -f "Chrome.*remote-debugging-port" 2>/dev/null; pkill -f "Chromium.*remote
|
|||
## Notes
|
||||
|
||||
- First run: manual login required (session persists)
|
||||
- All scripts only fill content into the browser, user must review and publish manually
|
||||
- All scripts fill content into browser — user reviews and publishes manually
|
||||
- Cross-platform: macOS, Linux, Windows
|
||||
|
||||
## Extension Support
|
||||
|
||||
Custom configurations via EXTEND.md. See **Preferences** section for paths and supported options.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: baoyu-slide-deck
|
||||
description: Generates professional slide deck images from content. Creates outlines with style instructions, then generates individual slide images. Use when user asks to "create slides", "make a presentation", "generate deck", "slide deck", or "PPT".
|
||||
description: Generates professional slide deck images from content with 16 visual style presets and 4 style dimensions. Creates outlines, generates individual slide images, and merges to PPTX/PDF. Use when user asks to "create slides", "make a presentation", "generate deck", "slide deck", "PPT", "make slides", or "演示文稿".
|
||||
---
|
||||
|
||||
# Slide Deck Generator
|
||||
|
|
@ -43,69 +43,36 @@ Transform content into professional slide deck images.
|
|||
| `--images-only` | Generate images from existing prompts directory |
|
||||
| `--regenerate <N>` | Regenerate specific slide(s): `--regenerate 3` or `--regenerate 2,5,8` |
|
||||
|
||||
**Slide Count by Content Length**:
|
||||
| Content | Slides |
|
||||
|---------|--------|
|
||||
| < 1000 words | 5-10 |
|
||||
| 1000-3000 words | 10-18 |
|
||||
| 3000-5000 words | 15-25 |
|
||||
| > 5000 words | 20-30 (consider splitting) |
|
||||
**Slide Count**: Scale by content length — short (<1K words): 5-10, medium (1-3K): 10-18, long (3-5K): 15-25, very long (>5K): 20-30 (consider splitting).
|
||||
|
||||
## Style System
|
||||
|
||||
### Presets
|
||||
### Presets & Auto Selection
|
||||
|
||||
| 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 |
|
||||
16 presets, auto-selected by content signals (default: `blueprint`):
|
||||
|
||||
### Style Dimensions
|
||||
| Preset | Best For | Content Signals |
|
||||
|--------|----------|-----------------|
|
||||
| `blueprint` (Default) | Architecture, system design | architecture, system, data, technical |
|
||||
| `chalkboard` | Education, tutorials | classroom, teaching, school |
|
||||
| `corporate` | Investor decks, proposals | investor, quarterly, business |
|
||||
| `minimal` | Executive briefings | executive, minimal, clean |
|
||||
| `sketch-notes` | Educational, tutorials | tutorial, learn, guide, beginner |
|
||||
| `watercolor` | Lifestyle, wellness | lifestyle, wellness, travel |
|
||||
| `dark-atmospheric` | Entertainment, gaming | entertainment, music, gaming |
|
||||
| `notion` | Product demos, SaaS | saas, product, dashboard |
|
||||
| `bold-editorial` | Product launches, keynotes | launch, marketing, keynote |
|
||||
| `editorial-infographic` | Tech explainers, research | explainer, journalism |
|
||||
| `fantasy-animation` | Educational storytelling | story, fantasy, animation |
|
||||
| `intuition-machine` | Technical docs, academic | briefing, academic, research |
|
||||
| `pixel-art` | Gaming, developer talks | gaming, retro, pixel |
|
||||
| `scientific` | Biology, chemistry, medical | biology, chemistry, medical |
|
||||
| `vector-illustration` | Creative, children's content | creative, children, kids |
|
||||
| `vintage` | Historical, heritage | history, heritage, vintage |
|
||||
|
||||
| Dimension | Options | Description |
|
||||
|-----------|---------|-------------|
|
||||
| **Texture** | clean, grid, organic, pixel, paper | Visual texture and background treatment |
|
||||
| **Mood** | professional, warm, cool, vibrant, dark, neutral | Color temperature and palette style |
|
||||
| **Typography** | geometric, humanist, handwritten, editorial, technical | Headline and body text styling |
|
||||
| **Density** | minimal, balanced, dense | Information density per slide |
|
||||
### Custom Style Dimensions
|
||||
|
||||
Full specs: `references/dimensions/*.md`
|
||||
|
||||
### Auto Style Selection
|
||||
|
||||
| Content Signals | Preset |
|
||||
|-----------------|--------|
|
||||
| tutorial, learn, education, guide, beginner | `sketch-notes` |
|
||||
| classroom, teaching, school, chalkboard | `chalkboard` |
|
||||
| architecture, system, data, analysis, technical | `blueprint` |
|
||||
| creative, children, kids, cute | `vector-illustration` |
|
||||
| briefing, academic, research, bilingual | `intuition-machine` |
|
||||
| executive, minimal, clean, simple | `minimal` |
|
||||
| saas, product, dashboard, metrics | `notion` |
|
||||
| investor, quarterly, business, corporate | `corporate` |
|
||||
| launch, marketing, keynote, magazine | `bold-editorial` |
|
||||
| entertainment, music, gaming, atmospheric | `dark-atmospheric` |
|
||||
| explainer, journalism, science communication | `editorial-infographic` |
|
||||
| story, fantasy, animation, magical | `fantasy-animation` |
|
||||
| gaming, retro, pixel, developer | `pixel-art` |
|
||||
| biology, chemistry, medical, scientific | `scientific` |
|
||||
| history, heritage, vintage, expedition | `vintage` |
|
||||
| lifestyle, wellness, travel, artistic | `watercolor` |
|
||||
| Default | `blueprint` |
|
||||
4 dimensions: **Texture** (clean/grid/organic/pixel/paper), **Mood** (professional/warm/cool/vibrant/dark/neutral), **Typography** (geometric/humanist/handwritten/editorial/technical), **Density** (minimal/balanced/dense). Full specs: `references/dimensions/*.md`
|
||||
|
||||
## Design Philosophy
|
||||
|
||||
|
|
@ -145,83 +112,21 @@ slide-deck/{topic-slug}/
|
|||
|
||||
## Language Handling
|
||||
|
||||
**Detection Priority**:
|
||||
1. `--lang` flag (explicit)
|
||||
2. EXTEND.md `language` setting
|
||||
3. User's conversation language (input language)
|
||||
4. Source content language
|
||||
|
||||
**Rule**: ALL responses use user's preferred language:
|
||||
- Questions and confirmations
|
||||
- Progress reports
|
||||
- Error messages
|
||||
- Completion summaries
|
||||
|
||||
Technical terms (style names, file paths, code) remain in English.
|
||||
Language priority: `--lang` flag > EXTEND.md > conversation language > source content language. All responses use detected language; technical terms remain in English.
|
||||
|
||||
## Workflow
|
||||
|
||||
Copy this checklist and check off items as you complete them:
|
||||
|
||||
```
|
||||
Slide Deck Progress:
|
||||
- [ ] Step 1: Setup & Analyze
|
||||
- [ ] 1.1 Load preferences
|
||||
- [ ] 1.2 Analyze content
|
||||
- [ ] 1.3 Check existing ⚠️ REQUIRED
|
||||
- [ ] Step 2: Confirmation ⚠️ REQUIRED (Round 1, optional Round 2)
|
||||
- [ ] Step 3: Generate outline
|
||||
- [ ] Step 4: Review outline (conditional)
|
||||
- [ ] Step 5: Generate prompts
|
||||
- [ ] Step 6: Review prompts (conditional)
|
||||
- [ ] Step 7: Generate images
|
||||
- [ ] Step 8: Merge to PPTX/PDF
|
||||
- [ ] Step 9: Output summary
|
||||
```
|
||||
|
||||
### Flow
|
||||
|
||||
```
|
||||
Input → Preferences → Analyze → [Check Existing?] → Confirm (1-2 rounds) → Outline → [Review Outline?] → Prompts → [Review Prompts?] → Images → Merge → Complete
|
||||
Input → 1. Setup (preferences + analyze + check existing) → 2. Confirm (style, audience, slides, reviews) → 3. Outline → 4. Review outline? → 5. Prompts → 6. Review prompts? → 7. Images → 8. Merge PPTX/PDF → 9. Summary
|
||||
```
|
||||
|
||||
### Step 1: Setup & Analyze
|
||||
|
||||
**1.1 Load Preferences (EXTEND.md)**
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-slide-deck/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-slide-deck/EXTEND.md`). If found, read and display summary (style, audience, language, review preferences). If not found, proceed with defaults or run first-time setup.
|
||||
|
||||
```bash
|
||||
# Check project-level first
|
||||
test -f .baoyu-skills/baoyu-slide-deck/EXTEND.md && echo "project"
|
||||
|
||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||
test -f "$HOME/.baoyu-skills/baoyu-slide-deck/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
┌──────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├──────────────────────────────────────────────────┼───────────────────┤
|
||||
│ .baoyu-skills/baoyu-slide-deck/EXTEND.md │ Project directory │
|
||||
├──────────────────────────────────────────────────┼───────────────────┤
|
||||
│ $HOME/.baoyu-skills/baoyu-slide-deck/EXTEND.md │ User home │
|
||||
└──────────────────────────────────────────────────┴───────────────────┘
|
||||
|
||||
**When EXTEND.md Found** → Read, parse, **output summary to user**:
|
||||
|
||||
```
|
||||
📋 Loaded preferences from [full path]
|
||||
├─ Style: [preset/custom name]
|
||||
├─ Audience: [audience or "auto-detect"]
|
||||
├─ Language: [language or "auto-detect"]
|
||||
└─ Review: [enabled/disabled]
|
||||
```
|
||||
|
||||
**When EXTEND.md Not Found** → First-time setup using AskUserQuestion or proceed with defaults.
|
||||
|
||||
**EXTEND.md Supports**: Preferred style | Custom dimensions | Default audience | Language preference | Review preference
|
||||
|
||||
Schema: `references/config/preferences-schema.md`
|
||||
**Supports**: Preferred style | Custom dimensions | Default audience | Language preference | Review preference. Schema: `references/config/preferences-schema.md`
|
||||
|
||||
**1.2 Analyze Content**
|
||||
|
||||
|
|
@ -279,143 +184,21 @@ options:
|
|||
|
||||
#### Round 1 (Always)
|
||||
|
||||
**Use AskUserQuestion** for all 5 questions:
|
||||
Use AskUserQuestion for all 5 questions in one call:
|
||||
|
||||
**Question 1: Style**
|
||||
```
|
||||
header: "Style"
|
||||
question: "Which visual style for this deck?"
|
||||
options:
|
||||
- label: "{recommended_preset} (Recommended)"
|
||||
description: "Best match based on content analysis"
|
||||
- label: "{alternative_preset}"
|
||||
description: "[alternative style description]"
|
||||
- label: "Custom dimensions"
|
||||
description: "Choose texture, mood, typography, density separately"
|
||||
```
|
||||
|
||||
**Question 2: Audience**
|
||||
```
|
||||
header: "Audience"
|
||||
question: "Who is the primary reader?"
|
||||
options:
|
||||
- label: "General readers (Recommended)"
|
||||
description: "Broad appeal, accessible content"
|
||||
- label: "Beginners/learners"
|
||||
description: "Educational focus, clear explanations"
|
||||
- label: "Experts/professionals"
|
||||
description: "Technical depth, domain knowledge"
|
||||
- label: "Executives"
|
||||
description: "High-level insights, minimal detail"
|
||||
```
|
||||
|
||||
**Question 3: Slide Count**
|
||||
```
|
||||
header: "Slides"
|
||||
question: "How many slides?"
|
||||
options:
|
||||
- label: "{N} slides (Recommended)"
|
||||
description: "Based on content length"
|
||||
- label: "Fewer ({N-3} slides)"
|
||||
description: "More condensed, less detail"
|
||||
- label: "More ({N+3} slides)"
|
||||
description: "More detailed breakdown"
|
||||
```
|
||||
|
||||
**Question 4: Review Outline**
|
||||
```
|
||||
header: "Outline"
|
||||
question: "Review outline before generating prompts?"
|
||||
options:
|
||||
- label: "Yes, review outline (Recommended)"
|
||||
description: "Review slide titles and structure"
|
||||
- label: "No, skip outline review"
|
||||
description: "Proceed directly to prompt generation"
|
||||
```
|
||||
|
||||
**Question 5: Review Prompts**
|
||||
```
|
||||
header: "Prompts"
|
||||
question: "Review prompts before generating images?"
|
||||
options:
|
||||
- label: "Yes, review prompts (Recommended)"
|
||||
description: "Review image generation prompts"
|
||||
- label: "No, skip prompt review"
|
||||
description: "Proceed directly to image generation"
|
||||
```
|
||||
| # | Header | Question | Options |
|
||||
|---|--------|----------|---------|
|
||||
| 1 | Style | Which visual style? | {recommended_preset} (Recommended), {alternative}, Custom dimensions |
|
||||
| 2 | Audience | Primary reader? | General (Recommended), Beginners, Experts, Executives |
|
||||
| 3 | Slides | How many slides? | {N} (Recommended), Fewer ({N-3}), More ({N+3}) |
|
||||
| 4 | Outline | Review outline before prompts? | Yes (Recommended), No |
|
||||
| 5 | Prompts | Review prompts before images? | Yes (Recommended), No |
|
||||
|
||||
#### Round 2 (Only if "Custom dimensions" selected)
|
||||
|
||||
**Use AskUserQuestion** for all 4 dimensions:
|
||||
Use AskUserQuestion for all 4 dimensions: Texture (clean/grid/organic/pixel), Mood (professional/warm/cool/vibrant), Typography (geometric/humanist/handwritten/editorial), Density (balanced/minimal/dense).
|
||||
|
||||
**Question 1: Texture**
|
||||
```
|
||||
header: "Texture"
|
||||
question: "Which visual texture?"
|
||||
options:
|
||||
- label: "clean"
|
||||
description: "Pure solid color, no texture"
|
||||
- label: "grid"
|
||||
description: "Subtle grid overlay, technical"
|
||||
- label: "organic"
|
||||
description: "Soft textures, hand-drawn feel"
|
||||
- label: "pixel"
|
||||
description: "Chunky pixels, 8-bit aesthetic"
|
||||
```
|
||||
(Note: "paper" available via Other)
|
||||
|
||||
**Question 2: Mood**
|
||||
```
|
||||
header: "Mood"
|
||||
question: "Which color mood?"
|
||||
options:
|
||||
- label: "professional"
|
||||
description: "Cool-neutral, navy/gold"
|
||||
- label: "warm"
|
||||
description: "Earth tones, friendly"
|
||||
- label: "cool"
|
||||
description: "Blues, grays, analytical"
|
||||
- label: "vibrant"
|
||||
description: "High saturation, bold"
|
||||
```
|
||||
(Note: "dark", "neutral" available via Other)
|
||||
|
||||
**Question 3: Typography**
|
||||
```
|
||||
header: "Typography"
|
||||
question: "Which typography style?"
|
||||
options:
|
||||
- label: "geometric"
|
||||
description: "Modern sans-serif, clean"
|
||||
- label: "humanist"
|
||||
description: "Friendly, readable"
|
||||
- label: "handwritten"
|
||||
description: "Marker/brush, organic"
|
||||
- label: "editorial"
|
||||
description: "Magazine style, dramatic"
|
||||
```
|
||||
(Note: "technical" available via Other)
|
||||
|
||||
**Question 4: Density**
|
||||
```
|
||||
header: "Density"
|
||||
question: "Information density?"
|
||||
options:
|
||||
- label: "balanced (Recommended)"
|
||||
description: "2-3 key points per slide"
|
||||
- label: "minimal"
|
||||
description: "One focus point, maximum whitespace"
|
||||
- label: "dense"
|
||||
description: "Multiple data points, compact"
|
||||
```
|
||||
|
||||
**After Round 2**: Store custom dimensions as the style configuration.
|
||||
|
||||
**After Confirmation**:
|
||||
1. Update `analysis.md` with confirmed preferences
|
||||
2. Store `skip_outline_review` flag from Question 4
|
||||
3. Store `skip_prompt_review` flag from Question 5
|
||||
4. → Step 3
|
||||
**After Confirmation**: Update `analysis.md`, store `skip_outline_review` and `skip_prompt_review` flags → Step 3
|
||||
|
||||
### Step 3: Generate Outline
|
||||
|
||||
|
|
@ -438,43 +221,7 @@ Create outline using the confirmed style from Step 2.
|
|||
|
||||
### Step 4: Review Outline (Conditional)
|
||||
|
||||
**Skip this step** if user selected "No, skip outline review" in Step 2.
|
||||
|
||||
**Purpose**: Review outline structure before prompt generation.
|
||||
|
||||
**Language**: Use user's input language or saved language preference.
|
||||
|
||||
**Display**:
|
||||
- Total slides: N
|
||||
- Style: [preset name or "custom: texture+mood+typography+density"]
|
||||
- Slide-by-slide summary table:
|
||||
|
||||
```
|
||||
| # | Title | Type | Layout |
|
||||
|---|-------|------|--------|
|
||||
| 1 | [title] | Cover | title-hero |
|
||||
| 2 | [title] | Content | [layout] |
|
||||
| 3 | [title] | Content | [layout] |
|
||||
| ... | ... | ... | ... |
|
||||
```
|
||||
|
||||
**Use AskUserQuestion**:
|
||||
```
|
||||
header: "Confirm"
|
||||
question: "Ready to generate prompts?"
|
||||
options:
|
||||
- label: "Yes, proceed (Recommended)"
|
||||
description: "Generate image prompts"
|
||||
- label: "Edit outline first"
|
||||
description: "I'll modify outline.md before continuing"
|
||||
- label: "Regenerate outline"
|
||||
description: "Create new outline with different approach"
|
||||
```
|
||||
|
||||
**After response**:
|
||||
1. If "Edit outline first" → Inform user to edit `outline.md`, ask again when ready
|
||||
2. If "Regenerate outline" → Back to Step 3
|
||||
3. If "Yes, proceed" → Continue to Step 5
|
||||
Skip if user opted out in Step 2. Display slide summary table (number, title, type, layout), then AskUserQuestion: proceed / edit first / regenerate.
|
||||
|
||||
### Step 5: Generate Prompts
|
||||
|
||||
|
|
@ -483,8 +230,7 @@ options:
|
|||
- Extract STYLE_INSTRUCTIONS from outline (not from style file again)
|
||||
- Add slide-specific content
|
||||
- If `Layout:` specified, include layout guidance from `references/layouts.md`
|
||||
3. Save to `prompts/` directory
|
||||
- **Backup rule**: If prompt file exists, rename to `prompts/NN-slide-{slug}-backup-YYYYMMDD-HHMMSS.md`
|
||||
3. Save to `prompts/` directory (backup existing files before overwriting)
|
||||
|
||||
**After generation**:
|
||||
- If `--prompts-only`, stop here and output prompt summary
|
||||
|
|
@ -493,59 +239,13 @@ options:
|
|||
|
||||
### Step 6: Review Prompts (Conditional)
|
||||
|
||||
**Skip this step** if user selected "No, skip prompt review" in Step 2.
|
||||
|
||||
**Purpose**: Review prompts before image generation.
|
||||
|
||||
**Language**: Use user's input language or saved language preference.
|
||||
|
||||
**Display**:
|
||||
- Total prompts: N
|
||||
- Style: [preset name or custom dimensions]
|
||||
- Prompt list:
|
||||
|
||||
```
|
||||
| # | Filename | Slide Title |
|
||||
|---|----------|-------------|
|
||||
| 1 | 01-slide-cover.md | [title] |
|
||||
| 2 | 02-slide-xxx.md | [title] |
|
||||
| ... | ... | ... |
|
||||
```
|
||||
|
||||
- Path to prompts directory: `prompts/`
|
||||
|
||||
**Use AskUserQuestion**:
|
||||
```
|
||||
header: "Confirm"
|
||||
question: "Ready to generate slide images?"
|
||||
options:
|
||||
- label: "Yes, proceed (Recommended)"
|
||||
description: "Generate all slide images"
|
||||
- label: "Edit prompts first"
|
||||
description: "I'll modify prompts before continuing"
|
||||
- label: "Regenerate prompts"
|
||||
description: "Create new prompts with different approach"
|
||||
```
|
||||
|
||||
**After response**:
|
||||
1. If "Edit prompts first" → Inform user to edit prompts, ask again when ready
|
||||
2. If "Regenerate prompts" → Back to Step 5
|
||||
3. If "Yes, proceed" → Continue to Step 7
|
||||
Skip if user opted out in Step 2. Display prompt list table, then AskUserQuestion: proceed / edit first / regenerate.
|
||||
|
||||
### Step 7: Generate Images
|
||||
|
||||
**For `--images-only`**: Start here with existing prompts.
|
||||
**Backup rule** (applies to all steps): If file exists, rename to `{name}-backup-YYYYMMDD-HHMMSS.{ext}`.
|
||||
|
||||
**For `--regenerate N`**: Only regenerate specified slide(s).
|
||||
|
||||
**Standard flow**:
|
||||
1. Select available image generation skill
|
||||
2. Generate session ID: `slides-{topic-slug}-{timestamp}`
|
||||
3. For each slide:
|
||||
- **Backup rule**: If image file exists, rename to `NN-slide-{slug}-backup-YYYYMMDD-HHMMSS.png`
|
||||
- Generate image sequentially with same session ID
|
||||
4. Report progress: "Generated X/N" (in user's language)
|
||||
5. Auto-retry once on failure before reporting error
|
||||
Generate images sequentially with same session ID (`slides-{topic-slug}-{timestamp}`). Report progress after each. Auto-retry once on failure.
|
||||
|
||||
### Step 8: Merge to PPTX and PDF
|
||||
|
||||
|
|
@ -576,96 +276,18 @@ PPTX: {topic-slug}.pptx
|
|||
PDF: {topic-slug}.pdf
|
||||
```
|
||||
|
||||
## Partial Workflows
|
||||
## Partial Workflows & Modification
|
||||
|
||||
| Option | Workflow |
|
||||
|--------|----------|
|
||||
| `--outline-only` | Steps 1-3 only (stop after outline) |
|
||||
| `--prompts-only` | Steps 1-5 (generate prompts, skip images) |
|
||||
| `--images-only` | Skip to Step 7 (requires existing prompts/) |
|
||||
| `--regenerate N` | Regenerate specific slide(s) only |
|
||||
| `--outline-only` | Steps 1-3 only |
|
||||
| `--prompts-only` | Steps 1-5 (skip images) |
|
||||
| `--images-only` | Step 7 only (requires existing `prompts/` and `outline.md`) |
|
||||
| `--regenerate N` | Regenerate specific slide(s) only (e.g., `3` or `2,5,8`) |
|
||||
|
||||
### Using `--prompts-only`
|
||||
**Slide Modification**: Always update the prompt file FIRST before regenerating. See `references/modification-guide.md` for edit/add/delete workflows.
|
||||
|
||||
Generate outline and prompts without images:
|
||||
|
||||
```bash
|
||||
/baoyu-slide-deck content.md --prompts-only
|
||||
```
|
||||
|
||||
Output: `outline.md` + `prompts/*.md` ready for review/editing.
|
||||
|
||||
### Using `--images-only`
|
||||
|
||||
Generate images from existing prompts (starts at Step 7):
|
||||
|
||||
```bash
|
||||
/baoyu-slide-deck slide-deck/topic-slug/ --images-only
|
||||
```
|
||||
|
||||
Prerequisites:
|
||||
- `prompts/` directory with slide prompt files
|
||||
- `outline.md` with style information
|
||||
|
||||
### Using `--regenerate`
|
||||
|
||||
Regenerate specific slides:
|
||||
|
||||
```bash
|
||||
# Single slide
|
||||
/baoyu-slide-deck slide-deck/topic-slug/ --regenerate 3
|
||||
|
||||
# Multiple slides
|
||||
/baoyu-slide-deck slide-deck/topic-slug/ --regenerate 2,5,8
|
||||
```
|
||||
|
||||
Flow:
|
||||
1. Read existing prompts for specified slides
|
||||
2. Regenerate images only for those slides
|
||||
3. Regenerate PPTX/PDF
|
||||
|
||||
## Slide Modification
|
||||
|
||||
### Quick Reference
|
||||
|
||||
| Action | Command | Manual Steps |
|
||||
|--------|---------|--------------|
|
||||
| **Edit** | `--regenerate N` | **Update prompt file FIRST** → Regenerate image → Regenerate PDF |
|
||||
| **Add** | Manual | Create prompt → Generate image → Renumber subsequent → Update outline → Regenerate PDF |
|
||||
| **Delete** | Manual | Remove files → Renumber subsequent → Update outline → Regenerate PDF |
|
||||
|
||||
### Edit Single Slide
|
||||
|
||||
1. **Update prompt file FIRST** in `prompts/NN-slide-{slug}.md`
|
||||
2. Run: `/baoyu-slide-deck <dir> --regenerate N`
|
||||
3. Or manually regenerate image + PDF
|
||||
|
||||
**IMPORTANT**: When updating slides, ALWAYS update the prompt file (`prompts/NN-slide-{slug}.md`) FIRST before regenerating. This ensures changes are documented and reproducible.
|
||||
|
||||
### Add New Slide
|
||||
|
||||
1. Create prompt at position: `prompts/NN-slide-{new-slug}.md`
|
||||
2. Generate image using same session ID
|
||||
3. **Renumber**: Subsequent files NN+1 (slugs unchanged)
|
||||
4. Update `outline.md`
|
||||
5. Regenerate PPTX/PDF
|
||||
|
||||
### Delete Slide
|
||||
|
||||
1. Remove `NN-slide-{slug}.png` and `prompts/NN-slide-{slug}.md`
|
||||
2. **Renumber**: Subsequent files NN-1 (slugs unchanged)
|
||||
3. Update `outline.md`
|
||||
4. Regenerate PPTX/PDF
|
||||
|
||||
### File Naming
|
||||
|
||||
Format: `NN-slide-[slug].png`
|
||||
- `NN`: Two-digit sequence (01, 02, ...)
|
||||
- `slug`: Kebab-case from content (2-5 words, unique)
|
||||
|
||||
**Renumbering Rule**: Only NN changes, slugs remain unchanged.
|
||||
|
||||
See `references/modification-guide.md` for complete details.
|
||||
**File Naming**: `NN-slide-[slug].png` — NN is two-digit sequence, slug is kebab-case (2-5 words). When renumbering, only NN changes, slugs remain.
|
||||
|
||||
## References
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: baoyu-url-to-markdown
|
||||
description: Fetch any URL and convert to markdown using Chrome CDP. Supports two modes - auto-capture on page load, or wait for user signal (for pages requiring login). Use when user wants to save a webpage as markdown.
|
||||
description: Fetches any URL and converts HTML to clean markdown using Chrome CDP with full JavaScript rendering. Supports auto-capture and wait-for-user modes for login-required pages. Use when user asks to "save webpage", "scrape page", "download page as markdown", "capture website", "web page to markdown", or "convert URL to markdown".
|
||||
---
|
||||
|
||||
# URL to Markdown
|
||||
|
|
@ -23,33 +23,9 @@ Fetches any URL via Chrome CDP and converts HTML to clean markdown.
|
|||
|
||||
## Preferences (EXTEND.md)
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-url-to-markdown/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-url-to-markdown/EXTEND.md`). If found, read and apply settings. If not found, use defaults.
|
||||
|
||||
```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
|
||||
**Supports**: Default output directory | Default capture mode | Timeout settings
|
||||
|
||||
## Features
|
||||
|
||||
|
|
@ -113,7 +89,22 @@ url-to-markdown/<domain>/<slug>.md
|
|||
| `URL_DATA_DIR` | Custom data 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.
|
||||
## Workflow
|
||||
|
||||
1. Check EXTEND.md preferences (see Preferences section)
|
||||
2. Run script with URL and options
|
||||
3. **Verify output**: Check that output file exists and contains valid markdown with YAML front matter
|
||||
4. If capture fails or output is empty, retry with `--wait` mode for dynamic content
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| Chrome not found | Set `URL_CHROME_PATH` to Chrome executable path |
|
||||
| Timeout on slow pages | Increase `--timeout` value (e.g., `--timeout 60000`) |
|
||||
| Dynamic/JS-heavy content | Use `--wait` mode to control capture timing |
|
||||
| Login-required page | Use `--wait`, log in manually, then signal capture |
|
||||
| Empty output | Page may need longer load time; try `--wait` or increase `--timeout` |
|
||||
|
||||
## Extension Support
|
||||
|
||||
|
|
|
|||
|
|
@ -38,46 +38,13 @@ Break down complex content into eye-catching infographic series for Xiaohongshu
|
|||
| `--style <name>` | Visual style (see Style Gallery) |
|
||||
| `--layout <name>` | Information layout (see Layout Gallery) |
|
||||
|
||||
## Two Dimensions
|
||||
## Style & Layout
|
||||
|
||||
| Dimension | Controls | Options |
|
||||
|-----------|----------|---------|
|
||||
| **Style** | Visual aesthetics: colors, lines, decorations | cute, fresh, warm, bold, minimal, retro, pop, notion, chalkboard, study-notes |
|
||||
| **Layout** | Information structure: density, arrangement | sparse, balanced, dense, list, comparison, flow, mindmap, quadrant |
|
||||
Two independently combinable dimensions. Example: `--style notion --layout dense`.
|
||||
|
||||
Style × Layout can be freely combined. Example: `--style notion --layout dense` creates an intellectual-looking knowledge card with high information density.
|
||||
**Styles** (10): cute (default), fresh, warm, bold, minimal, retro, pop, notion, chalkboard, study-notes. Detailed definitions: `references/presets/<style>.md`
|
||||
|
||||
## Style Gallery
|
||||
|
||||
| Style | Description |
|
||||
|-------|-------------|
|
||||
| `cute` (Default) | Sweet, adorable, girly - classic Xiaohongshu aesthetic |
|
||||
| `fresh` | Clean, refreshing, natural |
|
||||
| `warm` | Cozy, friendly, approachable |
|
||||
| `bold` | High impact, attention-grabbing |
|
||||
| `minimal` | Ultra-clean, sophisticated |
|
||||
| `retro` | Vintage, nostalgic, trendy |
|
||||
| `pop` | Vibrant, energetic, eye-catching |
|
||||
| `notion` | Minimalist hand-drawn line art, intellectual |
|
||||
| `chalkboard` | Colorful chalk on black board, educational |
|
||||
| `study-notes` | Realistic handwritten photo style, blue pen + red annotations + yellow highlighter |
|
||||
|
||||
Detailed style definitions: `references/presets/<style>.md`
|
||||
|
||||
## Layout Gallery
|
||||
|
||||
| Layout | Description |
|
||||
|--------|-------------|
|
||||
| `sparse` (Default) | Minimal information, maximum impact (1-2 points) |
|
||||
| `balanced` | Standard content layout (3-4 points) |
|
||||
| `dense` | High information density, knowledge card style (5-8 points) |
|
||||
| `list` | Enumeration and ranking format (4-7 items) |
|
||||
| `comparison` | Side-by-side contrast layout |
|
||||
| `flow` | Process and timeline layout (3-6 steps) |
|
||||
| `mindmap` | Center radial mind map layout (4-8 branches) |
|
||||
| `quadrant` | Four-quadrant / circular section layout |
|
||||
|
||||
Detailed layout definitions: `references/elements/canvas.md`
|
||||
**Layouts** (8): sparse (default, 1-2 points), balanced (3-4), dense (5-8), list (4-7 items), comparison, flow (3-6 steps), mindmap (4-8 branches), quadrant. Detailed definitions: `references/elements/canvas.md`
|
||||
|
||||
## Auto Selection
|
||||
|
||||
|
|
@ -127,113 +94,23 @@ Three differentiated outline strategies for different content goals:
|
|||
|
||||
## File Structure
|
||||
|
||||
Each session creates an independent directory named by content slug:
|
||||
Output directory: `xhs-images/{topic-slug}/` containing `source-*.{ext}`, `analysis.md`, `outline-strategy-{a,b,c}.md`, `outline.md`, `prompts/NN-{type}-[slug].md`, and `NN-{type}-[slug].png`.
|
||||
|
||||
```
|
||||
xhs-images/{topic-slug}/
|
||||
├── source-{slug}.{ext} # Source files (text, images, etc.)
|
||||
├── analysis.md # Deep analysis + questions asked
|
||||
├── outline-strategy-a.md # Strategy A: Story-driven
|
||||
├── outline-strategy-b.md # Strategy B: Information-dense
|
||||
├── outline-strategy-c.md # Strategy C: Visual-first
|
||||
├── outline.md # Final selected/merged outline
|
||||
├── prompts/
|
||||
│ ├── 01-cover-[slug].md
|
||||
│ ├── 02-content-[slug].md
|
||||
│ └── ...
|
||||
├── 01-cover-[slug].png
|
||||
├── 02-content-[slug].png
|
||||
└── NN-ending-[slug].png
|
||||
```
|
||||
|
||||
**Slug Generation**:
|
||||
1. Extract main topic from content (2-4 words, kebab-case)
|
||||
2. Example: "AI工具推荐" → `ai-tools-recommend`
|
||||
|
||||
**Conflict Resolution**:
|
||||
If `xhs-images/{topic-slug}/` already exists:
|
||||
- Append timestamp: `{topic-slug}-YYYYMMDD-HHMMSS`
|
||||
- Example: `ai-tools` exists → `ai-tools-20260118-143052`
|
||||
|
||||
**Source Files**:
|
||||
Copy all sources with naming `source-{slug}.{ext}`:
|
||||
- `source-article.md`, `source-photo.jpg`, etc.
|
||||
- Multiple sources supported: text, images, files from conversation
|
||||
**Slug**: 2-4 words kebab-case from topic (e.g., "AI工具推荐" → `ai-tools-recommend`). If directory exists, append timestamp.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Progress Checklist
|
||||
|
||||
Copy and track progress:
|
||||
|
||||
```
|
||||
XHS Infographic Progress:
|
||||
- [ ] Step 0: Check preferences (EXTEND.md) ⛔ BLOCKING
|
||||
- [ ] Found → load preferences → continue
|
||||
- [ ] Not found → run first-time setup → MUST complete before Step 1
|
||||
- [ ] Step 1: Analyze content → analysis.md
|
||||
- [ ] Step 2: Confirmation 1 - Content understanding ⚠️ REQUIRED
|
||||
- [ ] Step 3: Generate 3 outline + style variants
|
||||
- [ ] Step 4: Confirmation 2 - Outline & style & elements selection ⚠️ REQUIRED
|
||||
- [ ] Step 5: Generate images (sequential)
|
||||
- [ ] Step 6: Completion report
|
||||
```
|
||||
|
||||
### Flow
|
||||
|
||||
```
|
||||
Input → [Step 0: Preferences] ─┬─ Found → Continue
|
||||
│
|
||||
└─ Not found → First-Time Setup ⛔ BLOCKING
|
||||
│
|
||||
└─ Complete setup → Save EXTEND.md → Continue
|
||||
│
|
||||
┌───────────────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
Analyze → [Confirm 1] → 3 Outlines → [Confirm 2: Outline + Style + Elements] → Generate → Complete
|
||||
0. Preferences (⛔ BLOCKING) → 1. Analyze → 2. Confirm content (⚠️ REQUIRED) → 3. Generate 3 outline variants → 4. Confirm outline + style (⚠️ REQUIRED) → 5. Generate images → 6. Report
|
||||
```
|
||||
|
||||
### Step 0: Load Preferences (EXTEND.md) ⛔ BLOCKING
|
||||
|
||||
**Purpose**: Load user preferences or run first-time setup.
|
||||
Check EXTEND.md existence (project-level `.baoyu-skills/baoyu-xhs-images/EXTEND.md`, then user-level `$HOME/.baoyu-skills/baoyu-xhs-images/EXTEND.md`). If found, read and display summary. If not found, MUST complete first-time setup before ANY other steps — do NOT proceed to content analysis.
|
||||
|
||||
**CRITICAL**: If EXTEND.md not found, MUST complete first-time setup before ANY other questions or steps. Do NOT proceed to content analysis, do NOT ask about style, do NOT ask about layout — ONLY complete the preferences setup first.
|
||||
**First-Time Setup**: Use AskUserQuestion with ALL questions in ONE call. See `references/config/first-time-setup.md`.
|
||||
|
||||
Use Bash to check EXTEND.md existence (priority order):
|
||||
|
||||
```bash
|
||||
# Check project-level first
|
||||
test -f .baoyu-skills/baoyu-xhs-images/EXTEND.md && echo "project"
|
||||
|
||||
# Then user-level (cross-platform: $HOME works on macOS/Linux/WSL)
|
||||
test -f "$HOME/.baoyu-skills/baoyu-xhs-images/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
┌────────────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ .baoyu-skills/baoyu-xhs-images/EXTEND.md │ Project directory │
|
||||
├────────────────────────────────────────────────────┼───────────────────┤
|
||||
│ $HOME/.baoyu-skills/baoyu-xhs-images/EXTEND.md │ User home │
|
||||
└────────────────────────────────────────────────────┴───────────────────┘
|
||||
|
||||
┌───────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Result │ Action │
|
||||
├───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ Found │ Read, parse, display summary → Continue to Step 1 │
|
||||
├───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ Not found │ ⛔ BLOCKING: Run first-time setup ONLY (see below) → Complete and save EXTEND.md → Then Step 1 │
|
||||
└───────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
**First-Time Setup** (when EXTEND.md not found):
|
||||
|
||||
**Language**: Use user's input language or saved language preference.
|
||||
|
||||
Use AskUserQuestion with ALL questions in ONE call. See `references/config/first-time-setup.md` for question details.
|
||||
|
||||
**EXTEND.md Supports**: Watermark | Preferred style/layout | Custom style definitions | Language preference
|
||||
|
||||
Schema: `references/config/preferences-schema.md`
|
||||
**Supports**: Watermark | Preferred style/layout | Custom style definitions | Language preference. Schema: `references/config/preferences-schema.md`
|
||||
|
||||
### Step 1: Analyze Content → `analysis.md`
|
||||
|
||||
|
|
@ -366,43 +243,13 @@ Display the selected style's default elements from preset, then ask:
|
|||
|
||||
### Step 5: Generate Images
|
||||
|
||||
With confirmed outline + style + layout:
|
||||
With confirmed outline + style + layout. **Backup rule** (applies to all files): If file exists, rename to `{name}-backup-YYYYMMDD-HHMMSS.{ext}` before writing.
|
||||
|
||||
**Visual Consistency — Reference Image Chain**:
|
||||
To ensure character/style consistency across all images in a series:
|
||||
1. **Generate image 1 (cover) FIRST** — without `--ref`
|
||||
2. **Use image 1 as `--ref` for ALL remaining images** (2, 3, ..., N)
|
||||
- This anchors the character design, color rendering, and illustration style
|
||||
- Command pattern: `--ref <path-to-image-01.png>` added to every subsequent generation
|
||||
**Visual Consistency**: Generate image 1 (cover) first without `--ref`, then use image 1 as `--ref` for ALL subsequent images to anchor character/style consistency.
|
||||
|
||||
This is critical for styles that use recurring characters, mascots, or illustration elements. Image 1 becomes the visual anchor for the entire series.
|
||||
**For each image**: Save prompt to `prompts/NN-{type}-[slug].md` → Generate image → Report progress. Apply watermark if enabled in preferences (see `references/config/watermark-guide.md`).
|
||||
|
||||
**For each image (cover + content + ending)**:
|
||||
1. Save prompt to `prompts/NN-{type}-[slug].md` (in user's preferred language)
|
||||
- **Backup rule**: If prompt file exists, rename to `prompts/NN-{type}-[slug]-backup-YYYYMMDD-HHMMSS.md`
|
||||
2. Generate image:
|
||||
- **Image 1**: Generate without `--ref` (this establishes the visual anchor)
|
||||
- **Images 2+**: Generate with `--ref <image-01-path>` for consistency
|
||||
- **Backup rule**: If image file exists, rename to `NN-{type}-[slug]-backup-YYYYMMDD-HHMMSS.png`
|
||||
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].
|
||||
The watermark should be legible but not distracting from the main content.
|
||||
```
|
||||
Reference: `references/config/watermark-guide.md`
|
||||
|
||||
**Image Generation Skill Selection**:
|
||||
- Check available image generation skills
|
||||
- If multiple skills available, ask user preference
|
||||
|
||||
**Session Management**:
|
||||
If image generation skill supports `--sessionId`:
|
||||
1. Generate unique session ID: `xhs-{topic-slug}-{timestamp}`
|
||||
2. Use same session ID for all images
|
||||
3. Combined with reference image chain, ensures maximum visual consistency
|
||||
**Session Management**: Use same session ID (`xhs-{topic-slug}-{timestamp}`) for all images to maintain consistency.
|
||||
|
||||
### Step 6: Completion Report
|
||||
|
||||
|
|
@ -441,47 +288,16 @@ Files:
|
|||
|
||||
## Content Breakdown Principles
|
||||
|
||||
1. **Cover (Image 1)**: Hook + visual impact → `sparse` layout
|
||||
2. **Content (Middle)**: Core value per image → `balanced`/`dense`/`list`/`comparison`/`flow`
|
||||
3. **Ending (Last)**: CTA / summary → `sparse` or `balanced`
|
||||
|
||||
**Style × Layout Matrix** (✓✓ = highly recommended, ✓ = works well):
|
||||
|
||||
| | sparse | balanced | dense | list | comparison | flow | mindmap | quadrant |
|
||||
|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
| cute | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| fresh | ✓✓ | ✓✓ | ✓ | ✓ | ✓ | ✓✓ | ✓ | ✓ |
|
||||
| warm | ✓✓ | ✓✓ | ✓ | ✓ | ✓✓ | ✓ | ✓ | ✓ |
|
||||
| bold | ✓✓ | ✓ | ✓ | ✓✓ | ✓✓ | ✓ | ✓ | ✓✓ |
|
||||
| minimal | ✓✓ | ✓✓ | ✓✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| retro | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| pop | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓ | ✓ | ✓ |
|
||||
| notion | ✓✓ | ✓✓ | ✓✓ | ✓✓ | ✓✓ | ✓✓ | ✓✓ | ✓✓ |
|
||||
| chalkboard | ✓✓ | ✓✓ | ✓✓ | ✓✓ | ✓ | ✓✓ | ✓✓ | ✓ |
|
||||
| study-notes | ✗ | ✓ | ✓✓ | ✓✓ | ✓ | ✓ | ✓✓ | ✓ |
|
||||
Cover (image 1): hook + visual impact → `sparse`. Content (middle): core value per image → `balanced`/`dense`/`list`/`comparison`/`flow`. Ending (last): CTA/summary → `sparse` or `balanced`. All style × layout combinations work; `notion` is the most versatile across all layouts.
|
||||
|
||||
## References
|
||||
|
||||
Detailed templates in `references/` directory:
|
||||
|
||||
**Elements** (Visual building blocks):
|
||||
- `elements/canvas.md` - Aspect ratios, safe zones, grid layouts
|
||||
- `elements/image-effects.md` - Cutout, stroke, filters
|
||||
- `elements/typography.md` - Decorated text (花字), tags, text direction
|
||||
- `elements/decorations.md` - Emphasis marks, backgrounds, doodles, frames
|
||||
|
||||
**Presets** (Style presets):
|
||||
- `presets/<name>.md` - Element combination definitions (cute, notion, warm...)
|
||||
|
||||
**Workflows** (Process guides):
|
||||
- `workflows/analysis-framework.md` - Content analysis framework
|
||||
- `workflows/outline-template.md` - Outline template with layout guide
|
||||
- `workflows/prompt-assembly.md` - Prompt assembly guide
|
||||
|
||||
**Config** (Settings):
|
||||
- `config/preferences-schema.md` - EXTEND.md schema
|
||||
- `config/first-time-setup.md` - First-time setup flow
|
||||
- `config/watermark-guide.md` - Watermark configuration
|
||||
| Category | Files |
|
||||
|----------|-------|
|
||||
| Elements | `elements/canvas.md`, `elements/image-effects.md`, `elements/typography.md`, `elements/decorations.md` |
|
||||
| Presets | `presets/<name>.md` — style definitions |
|
||||
| Workflows | `workflows/analysis-framework.md`, `workflows/outline-template.md`, `workflows/prompt-assembly.md` |
|
||||
| Config | `config/preferences-schema.md`, `config/first-time-setup.md`, `config/watermark-guide.md` |
|
||||
|
||||
## Notes
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue