mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-10 21:21:30 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e4d4ec8334 | |||
| 4935dc8b1a | |||
| c43ed57ffc | |||
| d96368492e | |||
| cfc647fd38 | |||
| 5144335916 | |||
| fa82c3d910 | |||
| 90730bc551 | |||
| 154ccfe3ff | |||
| 93efa5aeb1 | |||
| 40ccbed74a | |||
| fbf2bc02c5 | |||
| a37c80e142 | |||
| 2e68aa64a4 | |||
| a702513487 | |||
| 059ebc759c | |||
| 6b2b28b421 | |||
| 0df63c3a0b | |||
| 7834d632e0 | |||
| ca9a0a1404 | |||
| 366e7b5403 | |||
| 709e026be1 |
@@ -6,7 +6,7 @@
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Skills shared by Baoyu for improving daily work efficiency",
|
||||
"version": "1.56.0"
|
||||
"version": "1.58.0"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
|
||||
@@ -161,3 +161,6 @@ posts/
|
||||
*.ipr
|
||||
|
||||
.claude/skills/baoyu-skill-evolution
|
||||
# ClawHub local state (current and legacy directory names from the official CLI)
|
||||
.clawhub/
|
||||
.clawdhub/
|
||||
|
||||
@@ -2,6 +2,37 @@
|
||||
|
||||
English | [中文](./CHANGELOG.zh.md)
|
||||
|
||||
## 1.58.0 - 2026-03-08
|
||||
|
||||
### Features
|
||||
- Add XDG config path support for EXTEND.md (by @liby)
|
||||
|
||||
### Fixes
|
||||
- `baoyu-post-to-wechat`: surface agent-browser startup errors
|
||||
- `baoyu-post-to-wechat`: harden agent-browser command and eval handling (by @luojiyin1987)
|
||||
- `baoyu-image-gen`: use execFileSync for google curl requests (by @luojiyin1987)
|
||||
- `baoyu-format-markdown`: use spawnSync for autocorrect command (by @luojiyin1987)
|
||||
|
||||
### Documentation
|
||||
- Fix CLAUDE dependency statement (by @luojiyin1987)
|
||||
- Add markdown-to-html to README utility skills (by @luojiyin1987)
|
||||
|
||||
## 1.57.0 - 2026-03-08
|
||||
|
||||
### Features
|
||||
- Add ClawHub/OpenClaw publishing support with sync script and README documentation
|
||||
|
||||
### Refactor
|
||||
- Add openclaw metadata to all skill frontmatter for ClawHub registry compatibility
|
||||
- Rename `SKILL_DIR` to `baseDir` across all skills for consistency
|
||||
- `baoyu-danger-gemini-web`, `baoyu-danger-x-to-markdown`: dynamic script path in usage display
|
||||
- `baoyu-comic`, `baoyu-xhs-images`: use skill interface instead of direct script invocation for image generation
|
||||
|
||||
## 1.56.1 - 2026-03-08
|
||||
|
||||
### Fixes
|
||||
- `baoyu-post-to-weibo`: simplify article image insertion with Backspace-based placeholder deletion for ProseMirror compatibility
|
||||
|
||||
## 1.56.0 - 2026-03-08
|
||||
|
||||
### Features
|
||||
|
||||
@@ -2,6 +2,37 @@
|
||||
|
||||
[English](./CHANGELOG.md) | 中文
|
||||
|
||||
## 1.58.0 - 2026-03-08
|
||||
|
||||
### 新功能
|
||||
- 新增 EXTEND.md 的 XDG 配置路径支持 (by @liby)
|
||||
|
||||
### 修复
|
||||
- `baoyu-post-to-wechat`:暴露 agent-browser 启动错误信息
|
||||
- `baoyu-post-to-wechat`:加固 agent-browser 命令和 eval 处理 (by @luojiyin1987)
|
||||
- `baoyu-image-gen`:使用 execFileSync 替代 shell 执行 Google curl 请求 (by @luojiyin1987)
|
||||
- `baoyu-format-markdown`:使用 spawnSync 替代 shell 执行 autocorrect 命令 (by @luojiyin1987)
|
||||
|
||||
### 文档
|
||||
- 修正 CLAUDE 依赖说明 (by @luojiyin1987)
|
||||
- 将 markdown-to-html 添加到 README 工具技能列表 (by @luojiyin1987)
|
||||
|
||||
## 1.57.0 - 2026-03-08
|
||||
|
||||
### 新功能
|
||||
- 新增 ClawHub/OpenClaw 发布支持,包含同步脚本和 README 文档
|
||||
|
||||
### 重构
|
||||
- 为所有 skill 前言添加 openclaw 元数据,兼容 ClawHub 注册表
|
||||
- 全部 skill 中将 `SKILL_DIR` 统一重命名为 `baseDir`
|
||||
- `baoyu-danger-gemini-web`、`baoyu-danger-x-to-markdown`:使用动态脚本路径显示用法
|
||||
- `baoyu-comic`、`baoyu-xhs-images`:通过 skill 接口调用图片生成,不再直接调用脚本
|
||||
|
||||
## 1.56.1 - 2026-03-08
|
||||
|
||||
### 修复
|
||||
- `baoyu-post-to-weibo`:简化头条文章图片插入逻辑,使用 Backspace 按键替代复杂的 deleteContents 方案,兼容 ProseMirror 编辑器
|
||||
|
||||
## 1.56.0 - 2026-03-08
|
||||
|
||||
### 新功能
|
||||
|
||||
@@ -89,7 +89,7 @@ ${BUN_X} skills/baoyu-danger-gemini-web/scripts/main.ts --promptfiles system.md
|
||||
|
||||
- **Bun**: TypeScript runtime (native `bun` preferred, fallback `npx -y bun`)
|
||||
- **Chrome**: Required for `baoyu-danger-gemini-web` auth and `baoyu-post-to-x` automation
|
||||
- **No npm packages**: Self-contained TypeScript, no external dependencies
|
||||
- **npm packages (per skill)**: Some skill subprojects include `package.json`/lockfiles and require dependency installation in their own `scripts/` directories
|
||||
|
||||
## Chrome Profile (Unified)
|
||||
|
||||
@@ -472,22 +472,27 @@ Check EXTEND.md existence (priority order):
|
||||
\`\`\`bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/<skill-name>/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/<skill-name>/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/<skill-name>/EXTEND.md" && echo "user"
|
||||
\`\`\`
|
||||
|
||||
\`\`\`powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/<skill-name>/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/<skill-name>/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/<skill-name>/EXTEND.md") { "user" }
|
||||
\`\`\`
|
||||
|
||||
┌────────────────────────────────────────────┬───────────────────┐
|
||||
│ Path │ Location │
|
||||
├────────────────────────────────────────────┼───────────────────┤
|
||||
│ .baoyu-skills/<skill-name>/EXTEND.md │ Project directory │
|
||||
├────────────────────────────────────────────┼───────────────────┤
|
||||
│ $HOME/.baoyu-skills/<skill-name>/EXTEND.md │ User home │
|
||||
└────────────────────────────────────────────┴───────────────────┘
|
||||
┌────────────────────────────────────────────────────────┬──────────────────────────┐
|
||||
│ Path │ Location │
|
||||
├────────────────────────────────────────────────────────┼──────────────────────────┤
|
||||
│ .baoyu-skills/<skill-name>/EXTEND.md │ Project directory │
|
||||
├────────────────────────────────────────────────────────┼──────────────────────────┤
|
||||
│ $XDG_CONFIG_HOME/baoyu-skills/<skill-name>/EXTEND.md │ XDG config (~/.config) │
|
||||
├────────────────────────────────────────────────────────┼──────────────────────────┤
|
||||
│ $HOME/.baoyu-skills/<skill-name>/EXTEND.md │ User home (legacy) │
|
||||
└────────────────────────────────────────────────────────┴──────────────────────────┘
|
||||
|
||||
┌───────────┬───────────────────────────────────────────────────────────────────────────┐
|
||||
│ Result │ Action │
|
||||
@@ -523,5 +528,6 @@ Custom configurations via EXTEND.md. See **Preferences** section for paths and s
|
||||
**Notes**:
|
||||
- Replace `<skill-name>` with actual skill name (e.g., `baoyu-cover-image`)
|
||||
- Use `$HOME` instead of `~` for cross-platform compatibility (macOS/Linux/WSL/PowerShell)
|
||||
- `$XDG_CONFIG_HOME` defaults to `~/.config` when unset
|
||||
- Use `test -f` (Bash) or `Test-Path` (PowerShell) for explicit file existence check
|
||||
- ASCII tables for clear visual formatting
|
||||
|
||||
@@ -17,6 +17,27 @@ Skills shared by Baoyu for improving daily work efficiency with Claude Code.
|
||||
npx skills add jimliu/baoyu-skills
|
||||
```
|
||||
|
||||
### Publish to ClawHub / OpenClaw
|
||||
|
||||
This repository now supports publishing each `skills/baoyu-*` directory as an individual ClawHub skill.
|
||||
|
||||
```bash
|
||||
# Preview what would be published
|
||||
./scripts/sync-clawhub.sh --dry-run
|
||||
|
||||
# Publish all changed skills from ./skills
|
||||
./scripts/sync-clawhub.sh --all
|
||||
```
|
||||
|
||||
ClawHub installs skills individually, not as one marketplace bundle. After publishing, users can install specific skills such as:
|
||||
|
||||
```bash
|
||||
clawhub install baoyu-image-gen
|
||||
clawhub install baoyu-markdown-to-html
|
||||
```
|
||||
|
||||
Publishing to ClawHub releases the published skill under `MIT-0`, per ClawHub's registry rules.
|
||||
|
||||
### Register as Plugin Marketplace
|
||||
|
||||
Run the following command in Claude Code:
|
||||
@@ -55,7 +76,7 @@ Simply tell Claude Code:
|
||||
|--------|-------------|--------|
|
||||
| **content-skills** | Content generation and publishing | [xhs-images](#baoyu-xhs-images), [infographic](#baoyu-infographic), [cover-image](#baoyu-cover-image), [slide-deck](#baoyu-slide-deck), [comic](#baoyu-comic), [article-illustrator](#baoyu-article-illustrator), [post-to-x](#baoyu-post-to-x), [post-to-wechat](#baoyu-post-to-wechat), [post-to-weibo](#baoyu-post-to-weibo) |
|
||||
| **ai-generation-skills** | AI-powered generation backends | [image-gen](#baoyu-image-gen), [danger-gemini-web](#baoyu-danger-gemini-web) |
|
||||
| **utility-skills** | Utility tools for content processing | [url-to-markdown](#baoyu-url-to-markdown), [danger-x-to-markdown](#baoyu-danger-x-to-markdown), [compress-image](#baoyu-compress-image), [format-markdown](#baoyu-format-markdown), [translate](#baoyu-translate) |
|
||||
| **utility-skills** | Utility tools for content processing | [url-to-markdown](#baoyu-url-to-markdown), [danger-x-to-markdown](#baoyu-danger-x-to-markdown), [compress-image](#baoyu-compress-image), [format-markdown](#baoyu-format-markdown), [markdown-to-html](#baoyu-markdown-to-html), [translate](#baoyu-translate) |
|
||||
|
||||
## Update Skills
|
||||
|
||||
@@ -777,6 +798,21 @@ Format plain text or markdown files with proper frontmatter, titles, summaries,
|
||||
| Code/commands | `` `inline` `` or ` ```block``` ` |
|
||||
| Quotes | `>` blockquote |
|
||||
|
||||
#### baoyu-markdown-to-html
|
||||
|
||||
Convert markdown files into styled HTML with WeChat-compatible themes, syntax highlighting, and optional bottom citations for external links.
|
||||
|
||||
```bash
|
||||
# Basic conversion
|
||||
/baoyu-markdown-to-html article.md
|
||||
|
||||
# Theme + color
|
||||
/baoyu-markdown-to-html article.md --theme grace --color red
|
||||
|
||||
# Convert ordinary external links to bottom citations
|
||||
/baoyu-markdown-to-html article.md --cite
|
||||
```
|
||||
|
||||
#### baoyu-translate
|
||||
|
||||
Translate articles and documents between languages with three modes: quick (direct), normal (analysis-informed), and refined (full publication-quality workflow with review and polish).
|
||||
|
||||
+37
-1
@@ -17,6 +17,27 @@
|
||||
npx skills add jimliu/baoyu-skills
|
||||
```
|
||||
|
||||
### 发布到 ClawHub / OpenClaw
|
||||
|
||||
现在这个仓库支持把每个 `skills/baoyu-*` 目录作为独立 ClawHub skill 发布。
|
||||
|
||||
```bash
|
||||
# 预览将要发布的变更
|
||||
./scripts/sync-clawhub.sh --dry-run
|
||||
|
||||
# 发布 ./skills 下所有已变更的 skill
|
||||
./scripts/sync-clawhub.sh --all
|
||||
```
|
||||
|
||||
ClawHub 按“单个 skill”安装,不是把整个 marketplace 一次性装进去。发布后,用户可以按需安装:
|
||||
|
||||
```bash
|
||||
clawhub install baoyu-image-gen
|
||||
clawhub install baoyu-markdown-to-html
|
||||
```
|
||||
|
||||
根据 ClawHub 的 registry 规则,发布到 ClawHub 的 skill 会以 `MIT-0` 许可分发。
|
||||
|
||||
### 注册插件市场
|
||||
|
||||
在 Claude Code 中运行:
|
||||
@@ -55,7 +76,7 @@ npx skills add jimliu/baoyu-skills
|
||||
|------|------|----------|
|
||||
| **content-skills** | 内容生成和发布 | [xhs-images](#baoyu-xhs-images), [infographic](#baoyu-infographic), [cover-image](#baoyu-cover-image), [slide-deck](#baoyu-slide-deck), [comic](#baoyu-comic), [article-illustrator](#baoyu-article-illustrator), [post-to-x](#baoyu-post-to-x), [post-to-wechat](#baoyu-post-to-wechat), [post-to-weibo](#baoyu-post-to-weibo) |
|
||||
| **ai-generation-skills** | AI 生成后端 | [image-gen](#baoyu-image-gen), [danger-gemini-web](#baoyu-danger-gemini-web) |
|
||||
| **utility-skills** | 内容处理工具 | [url-to-markdown](#baoyu-url-to-markdown), [danger-x-to-markdown](#baoyu-danger-x-to-markdown), [compress-image](#baoyu-compress-image), [format-markdown](#baoyu-format-markdown), [translate](#baoyu-translate) |
|
||||
| **utility-skills** | 内容处理工具 | [url-to-markdown](#baoyu-url-to-markdown), [danger-x-to-markdown](#baoyu-danger-x-to-markdown), [compress-image](#baoyu-compress-image), [format-markdown](#baoyu-format-markdown), [markdown-to-html](#baoyu-markdown-to-html), [translate](#baoyu-translate) |
|
||||
|
||||
## 更新技能
|
||||
|
||||
@@ -777,6 +798,21 @@ AI 驱动的生成后端。
|
||||
| 代码/命令 | `` `行内` `` 或 ` ```代码块``` ` |
|
||||
| 引用 | `>` 引用块 |
|
||||
|
||||
#### baoyu-markdown-to-html
|
||||
|
||||
将 Markdown 文件转换为样式化 HTML,支持微信公众号兼容主题、代码高亮,以及可选的外链底部引用。
|
||||
|
||||
```bash
|
||||
# 基础转换
|
||||
/baoyu-markdown-to-html article.md
|
||||
|
||||
# 主题 + 颜色
|
||||
/baoyu-markdown-to-html article.md --theme grace --color red
|
||||
|
||||
# 将普通外链转换为文末引用
|
||||
/baoyu-markdown-to-html article.md --cite
|
||||
```
|
||||
|
||||
#### baoyu-translate
|
||||
|
||||
三模式翻译技能:快速(直接翻译)、标准(分析后翻译)、精翻(完整出版级工作流,含审校与润色)。
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
SKILLS_DIR="${ROOT_DIR}/skills"
|
||||
|
||||
if command -v clawhub >/dev/null 2>&1; then
|
||||
CLAWHUB_CMD=(clawhub)
|
||||
elif command -v npx >/dev/null 2>&1; then
|
||||
CLAWHUB_CMD=(npx -y clawhub)
|
||||
else
|
||||
echo "Error: neither clawhub nor npx is available."
|
||||
echo "See https://docs.openclaw.ai/zh-CN/tools/clawhub"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
set -- --all
|
||||
fi
|
||||
|
||||
exec "${CLAWHUB_CMD[@]}" sync --root "${SKILLS_DIR}" "$@"
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
name: baoyu-article-illustrator
|
||||
description: Analyzes article structure, identifies positions requiring visual aids, generates illustrations with Type × Style two-dimension approach. Use when user asks to "illustrate article", "add images", "generate images for article", or "为文章配图".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-article-illustrator
|
||||
---
|
||||
|
||||
# Article Illustrator
|
||||
@@ -51,12 +55,15 @@ See [references/styles.md](references/styles.md) for Core Styles, full gallery,
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-article-illustrator/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-article-illustrator/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-article-illustrator/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
|
||||
@@ -88,12 +88,15 @@ Check preferences and existing state, then ask ALL needed questions in ONE AskUs
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-article-illustrator/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-article-illustrator/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-article-illustrator/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-article-illustrator/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
|
||||
+21
-17
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-comic
|
||||
description: Knowledge comic creator supporting multiple art styles and tones. Creates original educational comics with detailed panel layouts and sequential image generation. Use when user asks to create "知识漫画", "教育漫画", "biography comic", "tutorial comic", or "Logicomix-style comic".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-comic
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Knowledge Comic Creator
|
||||
@@ -104,9 +112,9 @@ Details: [references/auto-selection.md](references/auto-selection.md)
|
||||
**Important**: All scripts are located in the `scripts/` subdirectory of this skill.
|
||||
|
||||
**Agent Execution Instructions**:
|
||||
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
|
||||
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
|
||||
3. Replace all `${SKILL_DIR}` in this document with the actual path
|
||||
1. Determine this SKILL.md file's directory path as `{baseDir}`
|
||||
2. Script path = `{baseDir}/scripts/<script-name>.ts`
|
||||
3. Replace all `{baseDir}` in this document with the actual path
|
||||
4. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
|
||||
**Script Reference**:
|
||||
@@ -208,12 +216,11 @@ Analyze → [Check Existing?] → [Confirm: Style + Reviews] → Storyboard →
|
||||
|
||||
**7.1 Generate character sheet first**:
|
||||
- **Backup rule**: If `characters/characters.png` exists, rename to `characters/characters-backup-YYYYMMDD-HHMMSS.png`
|
||||
```bash
|
||||
# Use Reference Sheet Prompt from characters/characters.md
|
||||
${BUN_X} ${SKILL_DIR}/../baoyu-image-gen/scripts/main.ts \
|
||||
--promptfiles characters/characters.md \
|
||||
--image characters/characters.png --ar 4:3
|
||||
```
|
||||
- Invoke an installed image generation skill such as `baoyu-image-gen`
|
||||
- Read that skill's `SKILL.md` and follow its documented interface rather than calling its scripts directly
|
||||
- Use `characters/characters.md` as the prompt-file input
|
||||
- Save output to `characters/characters.png`
|
||||
- Use aspect ratio `4:3`
|
||||
|
||||
**Compress character sheet** (recommended):
|
||||
Compress to reduce token usage when used as reference image:
|
||||
@@ -231,14 +238,11 @@ Compress to reduce token usage when used as reference image:
|
||||
**Backup rules for page generation**:
|
||||
- If prompt file exists: rename to `prompts/NN-{cover|page}-[slug]-backup-YYYYMMDD-HHMMSS.md`
|
||||
- If image file exists: rename to `NN-{cover|page}-[slug]-backup-YYYYMMDD-HHMMSS.png`
|
||||
|
||||
```bash
|
||||
# Example: ALWAYS include --ref for consistency
|
||||
${BUN_X} ${SKILL_DIR}/../baoyu-image-gen/scripts/main.ts \
|
||||
--promptfiles prompts/01-page-xxx.md \
|
||||
--image 01-page-xxx.png --ar 3:4 \
|
||||
--ref characters/characters.png
|
||||
```
|
||||
- Invoke the installed image generation skill for each page
|
||||
- Use `prompts/01-page-xxx.md` as the prompt-file input
|
||||
- Save output to `01-page-xxx.png`
|
||||
- Use aspect ratio `3:4`
|
||||
- If the chosen skill supports reference images, pass `characters/characters.png` as `--ref`
|
||||
|
||||
**Full workflow details**: [references/workflow.md](references/workflow.md)
|
||||
|
||||
|
||||
@@ -39,12 +39,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-comic/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-comic/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-comic/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-comic/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-comic/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-comic/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -433,14 +436,12 @@ With confirmed prompts from Step 5/6:
|
||||
|
||||
**Strategy A: Using `--ref` parameter** (e.g., baoyu-image-gen)
|
||||
|
||||
```bash
|
||||
# Each page generation MUST include --ref
|
||||
${BUN_X} ${SKILL_DIR}/../baoyu-image-gen/scripts/main.ts \
|
||||
--promptfiles prompts/01-page-xxx.md \
|
||||
--image 01-page-xxx.png \
|
||||
--ar 3:4 \
|
||||
--ref characters/characters.png
|
||||
```
|
||||
- Read the chosen image generation skill's `SKILL.md`
|
||||
- Invoke that installed skill via its documented interface, not by calling its scripts directly
|
||||
- For every page, use `prompts/01-page-xxx.md` as the prompt-file input
|
||||
- Save output to `01-page-xxx.png`
|
||||
- Use aspect ratio `3:4`
|
||||
- Pass `characters/characters.png` as `--ref` on every page generation
|
||||
|
||||
**Strategy B: Embedding character descriptions in prompt**
|
||||
|
||||
@@ -478,7 +479,7 @@ If image generation skill supports `--sessionId`:
|
||||
After all images generated:
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/merge-to-pdf.ts <comic-dir>
|
||||
${BUN_X} {baseDir}/scripts/merge-to-pdf.ts <comic-dir>
|
||||
```
|
||||
|
||||
Creates `{topic-slug}.pdf` with all pages as full-page images.
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-compress-image
|
||||
description: Compresses images to WebP (default) or PNG with automatic tool selection. Use when user asks to "compress image", "optimize image", "convert to webp", or reduce image file size.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-compress-image
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Image Compressor
|
||||
@@ -9,7 +17,7 @@ Compresses images using best available tool (sips → cwebp → ImageMagick →
|
||||
|
||||
## Script Directory
|
||||
|
||||
Scripts in `scripts/` subdirectory. `${SKILL_DIR}` = this SKILL.md's directory path. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `${SKILL_DIR}` and `${BUN_X}` with actual values.
|
||||
Scripts in `scripts/` subdirectory. `{baseDir}` = this SKILL.md's directory path. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `{baseDir}` and `${BUN_X}` with actual values.
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
@@ -22,12 +30,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-compress-image/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-compress-image/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-compress-image/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-compress-image/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -52,7 +63,7 @@ if (Test-Path "$HOME/.baoyu-skills/baoyu-compress-image/EXTEND.md") { "user" }
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <input> [options]
|
||||
${BUN_X} {baseDir}/scripts/main.ts <input> [options]
|
||||
```
|
||||
|
||||
## Options
|
||||
@@ -71,16 +82,16 @@ ${BUN_X} ${SKILL_DIR}/scripts/main.ts <input> [options]
|
||||
|
||||
```bash
|
||||
# Single file → WebP (replaces original)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts image.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts image.png
|
||||
|
||||
# Keep PNG format
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts image.png -f png --keep
|
||||
${BUN_X} {baseDir}/scripts/main.ts image.png -f png --keep
|
||||
|
||||
# Directory recursive
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts ./images/ -r -q 75
|
||||
${BUN_X} {baseDir}/scripts/main.ts ./images/ -r -q 75
|
||||
|
||||
# JSON output
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts image.png --json
|
||||
${BUN_X} {baseDir}/scripts/main.ts image.png --json
|
||||
```
|
||||
|
||||
**Output**:
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
name: baoyu-cover-image
|
||||
description: Generates article cover images with 5 dimensions (type, palette, rendering, text, mood) combining 10 color palettes and 7 rendering styles. Supports cinematic (2.35:1), widescreen (16:9), and square (1:1) aspects. Use when user asks to "generate cover image", "create article cover", or "make cover".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-cover-image
|
||||
---
|
||||
|
||||
# Cover Image Generator
|
||||
@@ -130,12 +134,15 @@ Check EXTEND.md existence (priority: project → user):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-cover-image/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-cover-image/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-cover-image/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-cover-image/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-cover-image/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-cover-image/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-danger-gemini-web
|
||||
description: Generates images and text via reverse-engineered Gemini Web API. Supports text generation, image generation from prompts, reference images for vision input, and multi-turn conversations. Use when other skills need image generation backend, or when user requests "generate image with Gemini", "Gemini text generation", or needs vision-capable AI generation.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-danger-gemini-web
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Gemini Web Client
|
||||
@@ -12,10 +20,10 @@ Text/image generation via Gemini Web API. Supports reference images and multi-tu
|
||||
**Important**: All scripts are located in the `scripts/` subdirectory of this skill.
|
||||
|
||||
**Agent Execution Instructions**:
|
||||
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
|
||||
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
|
||||
1. Determine this SKILL.md file's directory path as `{baseDir}`
|
||||
2. Script path = `{baseDir}/scripts/<script-name>.ts`
|
||||
3. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
4. Replace all `${SKILL_DIR}` and `${BUN_X}` in this document with actual values
|
||||
4. Replace all `{baseDir}` and `${BUN_X}` in this document with actual values
|
||||
|
||||
**Script Reference**:
|
||||
| Script | Purpose |
|
||||
@@ -49,12 +57,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-danger-gemini-web/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-danger-gemini-web/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-danger-gemini-web/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-danger-gemini-web/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-danger-gemini-web/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-danger-gemini-web/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -80,23 +91,23 @@ if (Test-Path "$HOME/.baoyu-skills/baoyu-danger-gemini-web/EXTEND.md") { "user"
|
||||
|
||||
```bash
|
||||
# Text generation
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts "Your prompt"
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "Your prompt" --model gemini-3-flash
|
||||
${BUN_X} {baseDir}/scripts/main.ts "Your prompt"
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "Your prompt" --model gemini-3-flash
|
||||
|
||||
# Image generation
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cute cat" --image cat.png
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --promptfiles system.md content.md --image out.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cute cat" --image cat.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --promptfiles system.md content.md --image out.png
|
||||
|
||||
# Vision input (reference images)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "Describe this" --reference image.png
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "Create variation" --reference a.png --image out.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "Describe this" --reference image.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "Create variation" --reference a.png --image out.png
|
||||
|
||||
# Multi-turn conversation
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts "Remember: 42" --sessionId session-abc
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts "What number?" --sessionId session-abc
|
||||
${BUN_X} {baseDir}/scripts/main.ts "Remember: 42" --sessionId session-abc
|
||||
${BUN_X} {baseDir}/scripts/main.ts "What number?" --sessionId session-abc
|
||||
|
||||
# JSON output
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts "Hello" --json
|
||||
${BUN_X} {baseDir}/scripts/main.ts "Hello" --json
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
@@ -59,16 +59,31 @@ function normalizeSessionMetadata(input: unknown): Array<string | null> {
|
||||
return [null, null, null];
|
||||
}
|
||||
|
||||
function formatScriptCommand(fallback: string): string {
|
||||
const raw = process.argv[1];
|
||||
const displayPath = raw
|
||||
? (() => {
|
||||
const relative = path.relative(process.cwd(), raw);
|
||||
return relative && !relative.startsWith("..") ? relative : raw;
|
||||
})()
|
||||
: fallback;
|
||||
const quotedPath = displayPath.includes(" ")
|
||||
? `"${displayPath.replace(/"/g, '\\"')}"`
|
||||
: displayPath;
|
||||
return `npx -y bun ${quotedPath}`;
|
||||
}
|
||||
|
||||
function printUsage(cookiePath: string, profileDir: string): void {
|
||||
const cmd = formatScriptCommand("scripts/main.ts");
|
||||
console.log(`Usage:
|
||||
npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts --prompt "Hello"
|
||||
npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts "Hello"
|
||||
npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts --prompt "A cute cat" --image generated.png
|
||||
npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts --promptfiles system.md content.md --image out.png
|
||||
${cmd} --prompt "Hello"
|
||||
${cmd} "Hello"
|
||||
${cmd} --prompt "A cute cat" --image generated.png
|
||||
${cmd} --promptfiles system.md content.md --image out.png
|
||||
|
||||
Multi-turn conversation (agent generates unique sessionId):
|
||||
npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts "Remember 42" --sessionId abc123
|
||||
npx -y bun skills/baoyu-danger-gemini-web/scripts/main.ts "What number?" --sessionId abc123
|
||||
${cmd} "Remember 42" --sessionId abc123
|
||||
${cmd} "What number?" --sessionId abc123
|
||||
|
||||
Options:
|
||||
-p, --prompt <text> Prompt text
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-danger-x-to-markdown
|
||||
description: Converts X (Twitter) tweets and articles to markdown with YAML front matter. Uses reverse-engineered API requiring user consent. Use when user mentions "X to markdown", "tweet to markdown", "save tweet", or provides x.com/twitter.com URLs for conversion.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-danger-x-to-markdown
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# X to Markdown
|
||||
@@ -14,8 +22,8 @@ Converts X content to markdown:
|
||||
Scripts located in `scripts/` subdirectory.
|
||||
|
||||
**Path Resolution**:
|
||||
1. `SKILL_DIR` = this SKILL.md's directory
|
||||
2. Script path = `${SKILL_DIR}/scripts/main.ts`
|
||||
1. `{baseDir}` = this SKILL.md's directory
|
||||
2. Script path = `{baseDir}/scripts/main.ts`
|
||||
3. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
|
||||
## Consent Requirement
|
||||
@@ -75,12 +83,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-danger-x-to-markdown/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -140,10 +151,10 @@ Full reference: [references/config/first-time-setup.md](references/config/first-
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url>
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url> -o output.md
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url> --download-media
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url> --json
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url>
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url> -o output.md
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url> --download-media
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url> --json
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
@@ -30,8 +30,22 @@ type ConsentRecord = {
|
||||
|
||||
const DISCLAIMER_VERSION = "1.0";
|
||||
|
||||
function formatScriptCommand(fallback: string): string {
|
||||
const raw = process.argv[1];
|
||||
const displayPath = raw
|
||||
? (() => {
|
||||
const relative = path.relative(process.cwd(), raw);
|
||||
return relative && !relative.startsWith("..") ? relative : raw;
|
||||
})()
|
||||
: fallback;
|
||||
const quotedPath = displayPath.includes(" ")
|
||||
? `"${displayPath.replace(/"/g, '\\"')}"`
|
||||
: displayPath;
|
||||
return `npx -y bun ${quotedPath}`;
|
||||
}
|
||||
|
||||
function printUsage(exitCode: number): never {
|
||||
const cmd = "npx -y bun skills/baoyu-danger-x-to-markdown/scripts/main.ts";
|
||||
const cmd = formatScriptCommand("scripts/main.ts");
|
||||
console.log(`X (Twitter) to Markdown
|
||||
|
||||
Usage:
|
||||
|
||||
@@ -36,6 +36,20 @@ function normalizeInputUrl(input: string): string {
|
||||
}
|
||||
}
|
||||
|
||||
function formatScriptCommand(fallback: string): string {
|
||||
const raw = process.argv[1];
|
||||
const displayPath = raw
|
||||
? (() => {
|
||||
const relative = path.relative(process.cwd(), raw);
|
||||
return relative && !relative.startsWith("..") ? relative : raw;
|
||||
})()
|
||||
: fallback;
|
||||
const quotedPath = displayPath.includes(" ")
|
||||
? `"${displayPath.replace(/"/g, '\\"')}"`
|
||||
: displayPath;
|
||||
return `npx -y bun ${quotedPath}`;
|
||||
}
|
||||
|
||||
function parseTweetId(input: string): string | null {
|
||||
const trimmed = input.trim();
|
||||
if (!trimmed) return null;
|
||||
@@ -179,7 +193,7 @@ async function main() {
|
||||
const { url } = parseArgs();
|
||||
if (!url) {
|
||||
console.error("Usage:");
|
||||
console.error(" npx -y bun skills/baoyu-danger-x-to-markdown/scripts/tweet-to-markdown.ts <tweet url>");
|
||||
console.error(` ${formatScriptCommand("scripts/tweet-to-markdown.ts")} <tweet url>`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-format-markdown
|
||||
description: Formats plain text or markdown files with frontmatter, titles, summaries, headings, bold, lists, and code blocks. Use when user asks to "format markdown", "beautify article", "add formatting", or improve article layout. Outputs to {filename}-formatted.md.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-format-markdown
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Markdown Formatter
|
||||
@@ -11,7 +19,7 @@ Transforms plain text or markdown into well-structured, reader-friendly markdown
|
||||
|
||||
## Script Directory
|
||||
|
||||
Scripts in `scripts/` subdirectory. `${SKILL_DIR}` = this SKILL.md's directory path. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `${SKILL_DIR}` and `${BUN_X}` with actual values.
|
||||
Scripts in `scripts/` subdirectory. `{baseDir}` = this SKILL.md's directory path. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `{baseDir}` and `${BUN_X}` with actual values.
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
@@ -26,12 +34,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-format-markdown/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-format-markdown/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-format-markdown/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-format-markdown/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-format-markdown/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-format-markdown/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -296,7 +307,7 @@ fi
|
||||
Run the formatting script on the output file:
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts {output-file-path} [options]
|
||||
${BUN_X} {baseDir}/scripts/main.ts {output-file-path} [options]
|
||||
```
|
||||
|
||||
**Script Options:**
|
||||
@@ -314,13 +325,13 @@ ${BUN_X} ${SKILL_DIR}/scripts/main.ts {output-file-path} [options]
|
||||
|
||||
```bash
|
||||
# Default: spacing + emphasis enabled, quotes disabled
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md
|
||||
|
||||
# Enable all features including quote replacement
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md --quotes
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md --quotes
|
||||
|
||||
# Only fix emphasis issues, skip spacing
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md --no-spacing
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md --no-spacing
|
||||
```
|
||||
|
||||
**Script performs (based on options):**
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { execSync } from "child_process";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import process from "node:process";
|
||||
|
||||
export function applyAutocorrect(filePath: string): boolean {
|
||||
try {
|
||||
execSync(`npx autocorrect-node --fix "${filePath}"`, { stdio: "inherit" });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx";
|
||||
const result = spawnSync(npxCmd, ["autocorrect-node", "--fix", filePath], {
|
||||
stdio: "inherit",
|
||||
});
|
||||
return result.status === 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-image-gen
|
||||
description: AI image generation with OpenAI, Google, DashScope and Replicate APIs. Supports text-to-image, reference images, aspect ratios. Sequential by default; parallel generation available on request. Use when user asks to generate, create, or draw images.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-image-gen
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Image Generation (AI SDK)
|
||||
@@ -10,8 +18,8 @@ Official API-based image generation. Supports OpenAI, Google, DashScope (阿里
|
||||
## Script Directory
|
||||
|
||||
**Agent Execution**:
|
||||
1. `SKILL_DIR` = this SKILL.md file's directory
|
||||
2. Script path = `${SKILL_DIR}/scripts/main.ts`
|
||||
1. `{baseDir}` = this SKILL.md file's directory
|
||||
2. Script path = `{baseDir}/scripts/main.ts`
|
||||
3. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
|
||||
## Step 0: Load Preferences ⛔ BLOCKING
|
||||
@@ -23,12 +31,15 @@ Check EXTEND.md existence (priority: project → user):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-image-gen/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-image-gen/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-image-gen/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-image-gen/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-image-gen/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-image-gen/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -52,34 +63,34 @@ Schema: `references/config/preferences-schema.md`
|
||||
|
||||
```bash
|
||||
# Basic
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image cat.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cat" --image cat.png
|
||||
|
||||
# With aspect ratio
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A landscape" --image out.png --ar 16:9
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A landscape" --image out.png --ar 16:9
|
||||
|
||||
# High quality
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --quality 2k
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cat" --image out.png --quality 2k
|
||||
|
||||
# From prompt files
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --promptfiles system.md content.md --image out.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --promptfiles system.md content.md --image out.png
|
||||
|
||||
# With reference images (Google multimodal or OpenAI edits)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "Make blue" --image out.png --ref source.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "Make blue" --image out.png --ref source.png
|
||||
|
||||
# With reference images (explicit provider/model)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "Make blue" --image out.png --provider google --model gemini-3-pro-image-preview --ref source.png
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "Make blue" --image out.png --provider google --model gemini-3-pro-image-preview --ref source.png
|
||||
|
||||
# Specific provider
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider openai
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cat" --image out.png --provider openai
|
||||
|
||||
# DashScope (阿里通义万象)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "一只可爱的猫" --image out.png --provider dashscope
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "一只可爱的猫" --image out.png --provider dashscope
|
||||
|
||||
# Replicate (google/nano-banana-pro)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate
|
||||
|
||||
# Replicate with specific model
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate --model google/nano-banana
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate --model google/nano-banana
|
||||
```
|
||||
|
||||
## Options
|
||||
@@ -144,10 +155,10 @@ Examples:
|
||||
|
||||
```bash
|
||||
# Use Replicate default model
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate
|
||||
|
||||
# Override model explicitly
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate --model google/nano-banana
|
||||
${BUN_X} {baseDir}/scripts/main.ts --prompt "A cat" --image out.png --provider replicate --model google/nano-banana
|
||||
```
|
||||
|
||||
## Provider Selection
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from "node:path";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { execSync } from "node:child_process";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import type { CliArgs } from "../types";
|
||||
|
||||
const GOOGLE_MULTIMODAL_MODELS = [
|
||||
@@ -76,14 +76,43 @@ async function postGoogleJsonViaCurl<T>(
|
||||
): Promise<T> {
|
||||
const proxy = getHttpProxy();
|
||||
const bodyStr = JSON.stringify(body);
|
||||
const proxyArgs = proxy ? `-x "${proxy}"` : "";
|
||||
const args = [
|
||||
"-s",
|
||||
"--connect-timeout",
|
||||
"30",
|
||||
"--max-time",
|
||||
"300",
|
||||
...(proxy ? ["-x", proxy] : []),
|
||||
url,
|
||||
"-H",
|
||||
"Content-Type: application/json",
|
||||
"-H",
|
||||
`x-goog-api-key: ${apiKey}`,
|
||||
"-d",
|
||||
"@-",
|
||||
];
|
||||
|
||||
const result = execSync(
|
||||
`curl -s --connect-timeout 30 --max-time 300 ${proxyArgs} "${url}" -H "Content-Type: application/json" -H "x-goog-api-key: ${apiKey}" -d @-`,
|
||||
{ input: bodyStr, maxBuffer: 100 * 1024 * 1024, timeout: 310000 },
|
||||
);
|
||||
let result = "";
|
||||
try {
|
||||
result = execFileSync("curl", args, {
|
||||
input: bodyStr,
|
||||
encoding: "utf8",
|
||||
maxBuffer: 100 * 1024 * 1024,
|
||||
timeout: 310000,
|
||||
});
|
||||
} catch (error) {
|
||||
const e = error as { message?: string; stderr?: string | Buffer };
|
||||
const stderrText =
|
||||
typeof e.stderr === "string"
|
||||
? e.stderr
|
||||
: e.stderr
|
||||
? e.stderr.toString("utf8")
|
||||
: "";
|
||||
const details = stderrText.trim() || e.message || "curl request failed";
|
||||
throw new Error(`Google API request failed via curl: ${details}`);
|
||||
}
|
||||
|
||||
const parsed = JSON.parse(result.toString()) as any;
|
||||
const parsed = JSON.parse(result) as any;
|
||||
if (parsed.error) {
|
||||
throw new Error(
|
||||
`Google API error (${parsed.error.code}): ${parsed.error.message}`,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
name: baoyu-infographic
|
||||
description: Generates professional infographics with 21 layout types and 20 visual styles. Analyzes content, recommends layout×style combinations, and generates publication-ready infographics. Use when user asks to create "infographic", "信息图", "visual summary", "可视化", or "高密度信息大图".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-infographic
|
||||
---
|
||||
|
||||
# Infographic Generator
|
||||
@@ -143,12 +147,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-infographic/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-infographic/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-infographic/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-infographic/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-infographic/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-infographic/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-markdown-to-html
|
||||
description: Converts Markdown to styled HTML with WeChat-compatible themes. Supports code highlighting, math, PlantUML, footnotes, alerts, infographics, and optional bottom citations for external links. Use when user asks for "markdown to html", "convert md to html", "md转html", "微信外链转底部引用", or needs styled HTML output from markdown.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-markdown-to-html
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Markdown to HTML Converter
|
||||
@@ -9,7 +17,7 @@ Converts Markdown files to beautifully styled HTML with inline CSS, optimized fo
|
||||
|
||||
## Script Directory
|
||||
|
||||
**Agent Execution**: Determine this SKILL.md directory as `SKILL_DIR`. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `${SKILL_DIR}` and `${BUN_X}` with actual values.
|
||||
**Agent Execution**: Determine this SKILL.md directory as `{baseDir}`. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `{baseDir}` and `${BUN_X}` with actual values.
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
@@ -22,12 +30,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-markdown-to-html/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-markdown-to-html/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-markdown-to-html/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-markdown-to-html/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-markdown-to-html/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-markdown-to-html/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -117,7 +128,7 @@ if (Test-Path "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md") { Select-Str
|
||||
### Step 2: Convert
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <markdown_file> --theme <theme> [--cite]
|
||||
${BUN_X} {baseDir}/scripts/main.ts <markdown_file> --theme <theme> [--cite]
|
||||
```
|
||||
|
||||
### Step 3: Report Result
|
||||
@@ -127,7 +138,7 @@ Display the output path from JSON result. If backup was created, mention it.
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <markdown_file> [options]
|
||||
${BUN_X} {baseDir}/scripts/main.ts <markdown_file> [options]
|
||||
```
|
||||
|
||||
**Options:**
|
||||
@@ -165,22 +176,22 @@ ${BUN_X} ${SKILL_DIR}/scripts/main.ts <markdown_file> [options]
|
||||
|
||||
```bash
|
||||
# Basic conversion (uses default theme, removes first heading)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md
|
||||
|
||||
# With specific theme
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md --theme grace
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md --theme grace
|
||||
|
||||
# Theme with custom color
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md --theme modern --color red
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md --theme modern --color red
|
||||
|
||||
# Enable bottom citations for ordinary external links
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md --cite
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md --cite
|
||||
|
||||
# Keep the first heading in content
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md --keep-title
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md --keep-title
|
||||
|
||||
# Override title
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts article.md --title "My Article"
|
||||
${BUN_X} {baseDir}/scripts/main.ts article.md --title "My Article"
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
@@ -37,6 +37,10 @@ function parseExtendYaml(yaml: string): Partial<ExtendConfig> {
|
||||
export function loadExtendConfig(): Partial<ExtendConfig> {
|
||||
const paths = [
|
||||
path.join(process.cwd(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"),
|
||||
path.join(
|
||||
process.env.XDG_CONFIG_HOME || path.join(homedir(), ".config"),
|
||||
"baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"
|
||||
),
|
||||
path.join(homedir(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"),
|
||||
];
|
||||
for (const p of paths) {
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-post-to-wechat
|
||||
description: Posts content to WeChat Official Account (微信公众号) via API or Chrome CDP. Supports article posting (文章) with HTML, markdown, or plain text input, and image-text posting (贴图, formerly 图文) with multiple images. Markdown article workflows default to converting ordinary external links into bottom citations for WeChat-friendly output. Use when user mentions "发布公众号", "post to wechat", "微信公众号", or "贴图/图文/文章".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-post-to-wechat
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Post to WeChat Official Account
|
||||
@@ -11,7 +19,7 @@ description: Posts content to WeChat Official Account (微信公众号) via API
|
||||
|
||||
## Script Directory
|
||||
|
||||
**Agent Execution**: Determine this SKILL.md directory as `SKILL_DIR`, then use `${SKILL_DIR}/scripts/<name>.ts`. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun.
|
||||
**Agent Execution**: Determine this SKILL.md directory as `{baseDir}`, then use `{baseDir}/scripts/<name>.ts`. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun.
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
@@ -28,12 +36,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-post-to-wechat/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-post-to-wechat/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-post-to-wechat/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-post-to-wechat/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-post-to-wechat/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -92,7 +103,7 @@ chrome_profile_path: /path/to/chrome/profile
|
||||
Before first use, suggest running the environment check. User can skip if they prefer.
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/check-permissions.ts
|
||||
${BUN_X} {baseDir}/scripts/check-permissions.ts
|
||||
```
|
||||
|
||||
Checks: Chrome, profile isolation, Bun, Accessibility, clipboard, paste keystroke, API credentials, Chrome conflicts.
|
||||
@@ -115,8 +126,8 @@ Checks: Chrome, profile isolation, Bun, Accessibility, clipboard, paste keystrok
|
||||
For short posts with multiple images (up to 9):
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/wechat-browser.ts --markdown article.md --images ./images/
|
||||
${BUN_X} ${SKILL_DIR}/scripts/wechat-browser.ts --title "标题" --content "内容" --image img.png --submit
|
||||
${BUN_X} {baseDir}/scripts/wechat-browser.ts --markdown article.md --images ./images/
|
||||
${BUN_X} {baseDir}/scripts/wechat-browser.ts --title "标题" --content "内容" --image img.png --submit
|
||||
```
|
||||
|
||||
See [references/image-text-posting.md](references/image-text-posting.md) for details.
|
||||
@@ -260,7 +271,7 @@ WECHAT_APP_SECRET=<user_input>
|
||||
**API method** (accepts `.md` or `.html`):
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/wechat-api.ts <file> --theme <theme> [--color <color>] [--title <title>] [--summary <summary>] [--author <author>] [--cover <cover_path>] [--no-cite]
|
||||
${BUN_X} {baseDir}/scripts/wechat-api.ts <file> --theme <theme> [--color <color>] [--title <title>] [--summary <summary>] [--author <author>] [--cover <cover_path>] [--no-cite]
|
||||
```
|
||||
|
||||
**CRITICAL**: Always include `--theme` parameter. Never omit it, even if using `default`. Only include `--color` if explicitly set by user or EXTEND.md.
|
||||
@@ -279,8 +290,8 @@ If script parameters do not expose the two comment fields, still ensure final AP
|
||||
**Browser method** (accepts `--markdown` or `--html`):
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/wechat-article.ts --markdown <markdown_file> --theme <theme> [--color <color>] [--no-cite]
|
||||
${BUN_X} ${SKILL_DIR}/scripts/wechat-article.ts --html <html_file>
|
||||
${BUN_X} {baseDir}/scripts/wechat-article.ts --markdown <markdown_file> --theme <theme> [--color <color>] [--no-cite]
|
||||
${BUN_X} {baseDir}/scripts/wechat-article.ts --html <html_file>
|
||||
```
|
||||
|
||||
### Step 5: Completion Report
|
||||
|
||||
@@ -37,6 +37,10 @@ function parseExtendYaml(yaml: string): Partial<ExtendConfig> {
|
||||
export function loadExtendConfig(): Partial<ExtendConfig> {
|
||||
const paths = [
|
||||
path.join(process.cwd(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"),
|
||||
path.join(
|
||||
process.env.XDG_CONFIG_HOME || path.join(homedir(), ".config"),
|
||||
"baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"
|
||||
),
|
||||
path.join(homedir(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"),
|
||||
];
|
||||
for (const p of paths) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { execSync, spawnSync } from 'node:child_process';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
@@ -10,30 +10,51 @@ function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function ab(cmd: string, json = false): string {
|
||||
const fullCmd = `agent-browser --session ${SESSION} ${cmd}${json ? ' --json' : ''}`;
|
||||
console.log(`[ab] ${fullCmd}`);
|
||||
try {
|
||||
const result = execSync(fullCmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
||||
return result.trim();
|
||||
} catch (e: unknown) {
|
||||
const err = e as { stdout?: string; stderr?: string; message?: string };
|
||||
console.error(`[ab] Error: ${err.stderr || err.message}`);
|
||||
return err.stdout || '';
|
||||
}
|
||||
function quoteForLog(arg: string): string {
|
||||
return /[\s"'\\]/.test(arg) ? JSON.stringify(arg) : arg;
|
||||
}
|
||||
|
||||
function abRaw(args: string[]): { success: boolean; output: string } {
|
||||
function toSafeJsStringLiteral(value: string): string {
|
||||
return JSON.stringify(value)
|
||||
.replace(/\u2028/g, '\\u2028')
|
||||
.replace(/\u2029/g, '\\u2029');
|
||||
}
|
||||
|
||||
function runAgentBrowser(args: string[]): {
|
||||
success: boolean;
|
||||
output: string;
|
||||
spawnError?: string;
|
||||
} {
|
||||
const result = spawnSync('agent-browser', ['--session', SESSION, ...args], {
|
||||
encoding: 'utf8',
|
||||
stdio: ['pipe', 'pipe', 'pipe']
|
||||
});
|
||||
const spawnError = result.error?.message?.trim();
|
||||
const output = result.stdout || result.stderr || '';
|
||||
return {
|
||||
success: result.status === 0,
|
||||
output: result.stdout || result.stderr || ''
|
||||
output: output || spawnError || '',
|
||||
spawnError
|
||||
};
|
||||
}
|
||||
|
||||
function ab(args: string[], json = false): string {
|
||||
const fullArgs = json ? [...args, '--json'] : args;
|
||||
console.log(`[ab] agent-browser --session ${SESSION} ${fullArgs.map(quoteForLog).join(' ')}`);
|
||||
const result = runAgentBrowser(fullArgs);
|
||||
if (result.spawnError) {
|
||||
throw new Error(`agent-browser failed to start: ${result.spawnError}`);
|
||||
}
|
||||
if (!result.success) {
|
||||
console.error(`[ab] Error: ${result.output.trim()}`);
|
||||
}
|
||||
return result.output.trim();
|
||||
}
|
||||
|
||||
function abRaw(args: string[]): { success: boolean; output: string } {
|
||||
return runAgentBrowser(args);
|
||||
}
|
||||
|
||||
interface SnapshotElement {
|
||||
ref: string;
|
||||
role: string;
|
||||
@@ -99,17 +120,17 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
}
|
||||
|
||||
console.log('[wechat] Opening WeChat Official Account...');
|
||||
ab(`open ${WECHAT_URL} --headed`);
|
||||
ab(['open', WECHAT_URL, '--headed']);
|
||||
await sleep(5000);
|
||||
|
||||
console.log('[wechat] Checking login status...');
|
||||
let url = ab('get url');
|
||||
let url = ab(['get', 'url']);
|
||||
console.log(`[wechat] Current URL: ${url}`);
|
||||
|
||||
const waitForLogin = async (timeoutMs = 120_000): Promise<boolean> => {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeoutMs) {
|
||||
url = ab('get url');
|
||||
url = ab(['get', 'url']);
|
||||
if (url.includes('/cgi-bin/home')) return true;
|
||||
console.log('[wechat] Waiting for login...');
|
||||
await sleep(3000);
|
||||
@@ -126,7 +147,7 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
await sleep(2000);
|
||||
|
||||
console.log('[wechat] Getting page snapshot...');
|
||||
let snapshot = ab('snapshot');
|
||||
let snapshot = ab(['snapshot']);
|
||||
console.log(snapshot);
|
||||
|
||||
console.log('[wechat] Looking for "图文" menu...');
|
||||
@@ -134,16 +155,16 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
|
||||
if (!tuWenRef) {
|
||||
console.log('[wechat] Using eval to find and click menu...');
|
||||
ab(`eval "document.querySelectorAll('.new-creation__menu .new-creation__menu-item')[2].click()"`);
|
||||
ab(['eval', "document.querySelectorAll('.new-creation__menu .new-creation__menu-item')[2].click()"]);
|
||||
} else {
|
||||
console.log(`[wechat] Clicking menu ref: ${tuWenRef}`);
|
||||
ab(`click ${tuWenRef}`);
|
||||
ab(['click', tuWenRef]);
|
||||
}
|
||||
|
||||
await sleep(4000);
|
||||
|
||||
console.log('[wechat] Checking for new tab...');
|
||||
const tabsOutput = ab('tab');
|
||||
const tabsOutput = ab(['tab']);
|
||||
console.log(`[wechat] Tabs: ${tabsOutput}`);
|
||||
|
||||
const tabLines = tabsOutput.split('\n');
|
||||
@@ -153,14 +174,14 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
const tabMatch = tabsOutput.match(/\[(\d+)\].*(?:appmsg|edit)/i);
|
||||
if (tabMatch) {
|
||||
console.log(`[wechat] Switching to editor tab ${tabMatch[1]}...`);
|
||||
ab(`tab ${tabMatch[1]}`);
|
||||
ab(['tab', tabMatch[1]]);
|
||||
} else {
|
||||
const lastTabMatch = tabsOutput.match(/\[(\d+)\]/g);
|
||||
if (lastTabMatch && lastTabMatch.length > 1) {
|
||||
const lastTab = lastTabMatch[lastTabMatch.length - 1].match(/\d+/)?.[0];
|
||||
if (lastTab) {
|
||||
console.log(`[wechat] Switching to last tab ${lastTab}...`);
|
||||
ab(`tab ${lastTab}`);
|
||||
ab(['tab', lastTab]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,38 +189,44 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
|
||||
await sleep(3000);
|
||||
|
||||
url = ab('get url');
|
||||
url = ab(['get', 'url']);
|
||||
console.log(`[wechat] Editor URL: ${url}`);
|
||||
|
||||
console.log('[wechat] Getting editor snapshot...');
|
||||
snapshot = ab('snapshot');
|
||||
snapshot = ab(['snapshot']);
|
||||
console.log(snapshot.substring(0, 2000));
|
||||
|
||||
console.log('[wechat] Uploading images...');
|
||||
const fileInputSelector = '.js_upload_btn_container input[type=file]';
|
||||
const fileInputSelectorJs = toSafeJsStringLiteral(fileInputSelector);
|
||||
|
||||
ab(`eval "document.querySelector('${fileInputSelector}').style.display = 'block'"`);
|
||||
ab(['eval', `{
|
||||
const input = document.querySelector(${fileInputSelectorJs});
|
||||
if (input) input.style.display = 'block';
|
||||
}`]);
|
||||
await sleep(500);
|
||||
|
||||
const uploadResult = abRaw(['upload', `"${fileInputSelector}"`, ...absoluteImages]);
|
||||
const uploadResult = abRaw(['upload', fileInputSelector, ...absoluteImages]);
|
||||
console.log(`[wechat] Upload result: ${uploadResult.output}`);
|
||||
|
||||
if (!uploadResult.success) {
|
||||
console.log('[wechat] Using alternative upload method...');
|
||||
for (const img of absoluteImages) {
|
||||
console.log(`[wechat] Uploading: ${img}`);
|
||||
ab(`eval "
|
||||
const input = document.querySelector('${fileInputSelector}');
|
||||
const imgUrlJs = toSafeJsStringLiteral(`file://${img}`);
|
||||
const imgFileNameJs = toSafeJsStringLiteral(path.basename(img));
|
||||
ab(['eval', `
|
||||
const input = document.querySelector(${fileInputSelectorJs});
|
||||
if (input) {
|
||||
const dt = new DataTransfer();
|
||||
fetch('file://${img}').then(r => r.blob()).then(b => {
|
||||
const file = new File([b], '${path.basename(img)}', { type: 'image/png' });
|
||||
fetch(${imgUrlJs}).then(r => r.blob()).then(b => {
|
||||
const file = new File([b], ${imgFileNameJs}, { type: 'image/png' });
|
||||
dt.items.add(file);
|
||||
input.files = dt.files;
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
});
|
||||
}
|
||||
"`);
|
||||
`]);
|
||||
await sleep(2000);
|
||||
}
|
||||
}
|
||||
@@ -208,13 +235,14 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
await sleep(10000);
|
||||
|
||||
console.log('[wechat] Filling title...');
|
||||
snapshot = ab('snapshot -i');
|
||||
snapshot = ab(['snapshot', '-i']);
|
||||
const titleRef = findElementByText(snapshot, 'title') || findElementByText(snapshot, '标题');
|
||||
|
||||
if (titleRef) {
|
||||
ab(`fill ${titleRef} "${title.replace(/"/g, '\\"')}"`);
|
||||
ab(['fill', titleRef, title]);
|
||||
} else {
|
||||
ab(`eval "const t = document.querySelector('#title'); if(t) { t.value = '${title.replace(/'/g, "\\'")}'; t.dispatchEvent(new Event('input', {bubbles: true})); }"`);
|
||||
const titleJs = toSafeJsStringLiteral(title);
|
||||
ab(['eval', `const t = document.querySelector('#title'); if(t) { t.value = ${titleJs}; t.dispatchEvent(new Event('input', {bubbles: true})); }`]);
|
||||
}
|
||||
await sleep(500);
|
||||
|
||||
@@ -222,9 +250,9 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
const editorRef = findElementByText(snapshot, 'js_pmEditorArea') || findElementByText(snapshot, 'textbox');
|
||||
|
||||
if (editorRef) {
|
||||
ab(`click ${editorRef}`);
|
||||
ab(['click', editorRef]);
|
||||
} else {
|
||||
ab(`eval "document.querySelector('.js_pmEditorArea')?.click()"`);
|
||||
ab(['eval', "document.querySelector('.js_pmEditorArea')?.click()"]);
|
||||
}
|
||||
await sleep(500);
|
||||
|
||||
@@ -233,11 +261,11 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line.length > 0) {
|
||||
const escapedLine = line.replace(/"/g, '\\"').replace(/'/g, "\\'");
|
||||
ab(`eval "document.execCommand('insertText', false, '${escapedLine}')"`);
|
||||
const lineJs = toSafeJsStringLiteral(line);
|
||||
ab(['eval', `document.execCommand('insertText', false, ${lineJs})`]);
|
||||
}
|
||||
if (i < lines.length - 1) {
|
||||
ab('press Enter');
|
||||
ab(['press', 'Enter']);
|
||||
}
|
||||
await sleep(100);
|
||||
}
|
||||
@@ -249,9 +277,9 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
console.log('[wechat] Saving as draft...');
|
||||
const submitRef = findElementByText(snapshot, 'js_submit') || findElementByText(snapshot, '保存');
|
||||
if (submitRef) {
|
||||
ab(`click ${submitRef}`);
|
||||
ab(['click', submitRef]);
|
||||
} else {
|
||||
ab(`eval "document.querySelector('#js_submit')?.click()"`);
|
||||
ab(['eval', "document.querySelector('#js_submit')?.click()"]);
|
||||
}
|
||||
await sleep(3000);
|
||||
console.log('[wechat] Draft saved!');
|
||||
@@ -261,7 +289,7 @@ async function postToWeChat(options: WeChatOptions): Promise<void> {
|
||||
|
||||
if (!keepOpen) {
|
||||
console.log('[wechat] Closing browser...');
|
||||
ab('close');
|
||||
ab(['close']);
|
||||
} else {
|
||||
console.log('[wechat] Done. Browser window left open.');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-post-to-weibo
|
||||
description: Posts content to Weibo (微博). Supports regular posts with text, images, and videos, and headline articles (头条文章) with Markdown input via Chrome CDP. Use when user asks to "post to Weibo", "发微博", "发布微博", "publish to Weibo", "share on Weibo", "写微博", or "微博头条文章".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-post-to-weibo
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Post to Weibo
|
||||
@@ -12,9 +20,9 @@ Posts text, images, videos, and long-form articles to Weibo via real Chrome brow
|
||||
**Important**: All scripts are located in the `scripts/` subdirectory of this skill.
|
||||
|
||||
**Agent Execution Instructions**:
|
||||
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
|
||||
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
|
||||
3. Replace all `${SKILL_DIR}` in this document with the actual path
|
||||
1. Determine this SKILL.md file's directory path as `{baseDir}`
|
||||
2. Script path = `{baseDir}/scripts/<script-name>.ts`
|
||||
3. Replace all `{baseDir}` in this document with the actual path
|
||||
4. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
|
||||
**Script Reference**:
|
||||
@@ -32,12 +40,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-post-to-weibo/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-post-to-weibo/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-post-to-weibo/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-post-to-weibo/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-post-to-weibo/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-post-to-weibo/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -72,8 +83,8 @@ if (Test-Path "$HOME/.baoyu-skills/baoyu-post-to-weibo/EXTEND.md") { "user" }
|
||||
Text + images/videos (max 18 files total). Posted on Weibo homepage.
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/weibo-post.ts "Hello Weibo!" --image ./photo.png
|
||||
${BUN_X} ${SKILL_DIR}/scripts/weibo-post.ts "Watch this" --video ./clip.mp4
|
||||
${BUN_X} {baseDir}/scripts/weibo-post.ts "Hello Weibo!" --image ./photo.png
|
||||
${BUN_X} {baseDir}/scripts/weibo-post.ts "Watch this" --video ./clip.mp4
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
@@ -93,8 +104,8 @@ ${BUN_X} ${SKILL_DIR}/scripts/weibo-post.ts "Watch this" --video ./clip.mp4
|
||||
Long-form Markdown articles published at `https://card.weibo.com/article/v3/editor`.
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/weibo-article.ts article.md
|
||||
${BUN_X} ${SKILL_DIR}/scripts/weibo-article.ts article.md --cover ./cover.jpg
|
||||
${BUN_X} {baseDir}/scripts/weibo-article.ts article.md
|
||||
${BUN_X} {baseDir}/scripts/weibo-article.ts article.md --cover ./cover.jpg
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
|
||||
@@ -459,7 +459,7 @@ export async function publishArticle(options: ArticleOptions): Promise<void> {
|
||||
if (charAfter === undefined || !/\\d/.test(charAfter)) {
|
||||
const parentElement = node.parentElement;
|
||||
if (parentElement) {
|
||||
parentElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
parentElement.scrollIntoView({ behavior: 'instant', block: 'center' });
|
||||
}
|
||||
|
||||
const range = document.createRange();
|
||||
@@ -500,112 +500,56 @@ export async function publishArticle(options: ArticleOptions): Promise<void> {
|
||||
return false;
|
||||
};
|
||||
|
||||
// Step A: Copy image to clipboard first (slow due to Swift compilation)
|
||||
console.log(`[weibo-article] Copying image to clipboard: ${path.basename(img.localPath)}`);
|
||||
if (!copyImageToClipboard(img.localPath)) {
|
||||
console.warn(`[weibo-article] Failed to copy image to clipboard`);
|
||||
continue;
|
||||
}
|
||||
await sleep(500);
|
||||
|
||||
// Step B: Select placeholder text (paste will replace the selection)
|
||||
const selected = await selectPlaceholder(3);
|
||||
if (!selected) {
|
||||
console.warn(`[weibo-article] Skipping image - could not select placeholder: ${img.placeholder}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(`[weibo-article] Copying image: ${path.basename(img.localPath)}`);
|
||||
|
||||
if (!copyImageToClipboard(img.localPath)) {
|
||||
console.warn(`[weibo-article] Failed to copy image to clipboard`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await sleep(1000);
|
||||
|
||||
// Delete placeholder by replacing selection with empty text
|
||||
console.log(`[weibo-article] Deleting placeholder...`);
|
||||
await cdp.send('Runtime.evaluate', {
|
||||
expression: `(() => {
|
||||
const sel = window.getSelection();
|
||||
if (!sel || sel.isCollapsed) return false;
|
||||
const range = sel.getRangeAt(0);
|
||||
range.deleteContents();
|
||||
sel.collapseToStart();
|
||||
return true;
|
||||
})()`,
|
||||
returnByValue: true,
|
||||
}, { sessionId });
|
||||
|
||||
await sleep(300);
|
||||
|
||||
// Fallback: send Backspace key if placeholder still exists
|
||||
const stillExists = await cdp!.send<{ result: { value: boolean } }>('Runtime.evaluate', {
|
||||
expression: `(() => {
|
||||
const editor = document.querySelector('div[contenteditable="true"]');
|
||||
if (!editor) return false;
|
||||
const placeholder = ${JSON.stringify(img.placeholder)};
|
||||
const regex = new RegExp(placeholder + '(?!\\\\d)');
|
||||
return regex.test(editor.innerText);
|
||||
})()`,
|
||||
returnByValue: true,
|
||||
}, { sessionId });
|
||||
|
||||
if (stillExists.result.value) {
|
||||
console.log('[weibo-article] Placeholder survived deleteContents, trying Input.insertText replacement...');
|
||||
// Re-select and replace with empty via Input.insertText
|
||||
await cdp!.send('Runtime.evaluate', {
|
||||
expression: `(() => {
|
||||
const editor = document.querySelector('div[contenteditable="true"]');
|
||||
if (!editor) return false;
|
||||
const placeholder = ${JSON.stringify(img.placeholder)};
|
||||
const walker = document.createTreeWalker(editor, NodeFilter.SHOW_TEXT, null, false);
|
||||
let node;
|
||||
while ((node = walker.nextNode())) {
|
||||
const text = node.textContent || '';
|
||||
let searchStart = 0;
|
||||
let idx;
|
||||
while ((idx = text.indexOf(placeholder, searchStart)) !== -1) {
|
||||
const afterIdx = idx + placeholder.length;
|
||||
const charAfter = text[afterIdx];
|
||||
if (charAfter === undefined || !/\\d/.test(charAfter)) {
|
||||
const range = document.createRange();
|
||||
range.setStart(node, idx);
|
||||
range.setEnd(node, idx + placeholder.length);
|
||||
const sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
return true;
|
||||
}
|
||||
searchStart = afterIdx;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})()`,
|
||||
}, { sessionId });
|
||||
await sleep(200);
|
||||
await cdp!.send('Input.insertText', { text: '' }, { sessionId });
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
await sleep(200);
|
||||
// Step C: Delete selected placeholder via Backspace (ProseMirror-compatible)
|
||||
console.log(`[weibo-article] Deleting placeholder via Backspace...`);
|
||||
await cdp.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'Backspace', code: 'Backspace', windowsVirtualKeyCode: 8 }, { sessionId });
|
||||
await cdp.send('Input.dispatchKeyEvent', { type: 'keyUp', key: 'Backspace', code: 'Backspace', windowsVirtualKeyCode: 8 }, { sessionId });
|
||||
await sleep(500);
|
||||
|
||||
// Verify placeholder was deleted
|
||||
const afterDelete = await cdp.send<{ result: { value: boolean } }>('Runtime.evaluate', {
|
||||
const placeholderGone = await cdp.send<{ result: { value: boolean } }>('Runtime.evaluate', {
|
||||
expression: `(() => {
|
||||
const editor = document.querySelector('div[contenteditable="true"]');
|
||||
if (!editor) return true;
|
||||
const text = editor.innerText;
|
||||
const placeholder = ${JSON.stringify(img.placeholder)};
|
||||
const regex = new RegExp(placeholder + '(?!\\\\d)');
|
||||
return !regex.test(text);
|
||||
return !regex.test(editor.innerText);
|
||||
})()`,
|
||||
returnByValue: true,
|
||||
}, { sessionId });
|
||||
|
||||
if (afterDelete.result.value) {
|
||||
if (placeholderGone.result.value) {
|
||||
console.log(`[weibo-article] Placeholder deleted`);
|
||||
} else {
|
||||
console.warn(`[weibo-article] Placeholder may still exist after delete`);
|
||||
console.warn(`[weibo-article] Placeholder may still exist, trying execCommand delete...`);
|
||||
// Re-select and delete via execCommand
|
||||
await selectPlaceholder(1);
|
||||
await cdp.send('Runtime.evaluate', {
|
||||
expression: `document.execCommand('delete')`,
|
||||
}, { sessionId });
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
// Focus editor for paste
|
||||
// Step D: Focus editor and paste image
|
||||
await cdp.send('Runtime.evaluate', {
|
||||
expression: `document.querySelector('div[contenteditable="true"]')?.focus()`,
|
||||
}, { sessionId });
|
||||
await sleep(300);
|
||||
await sleep(200);
|
||||
|
||||
// Count images before paste
|
||||
const imgCountBefore = await cdp.send<{ result: { value: number } }>('Runtime.evaluate', {
|
||||
@@ -613,7 +557,7 @@ export async function publishArticle(options: ArticleOptions): Promise<void> {
|
||||
returnByValue: true,
|
||||
}, { sessionId });
|
||||
|
||||
// Paste image
|
||||
// Paste image at cursor position (where placeholder was)
|
||||
console.log(`[weibo-article] Pasting image...`);
|
||||
if (pasteFromClipboard('Google Chrome', 5, 1000)) {
|
||||
console.log(`[weibo-article] Paste keystroke sent for: ${path.basename(img.localPath)}`);
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-post-to-x
|
||||
description: Posts content and articles to X (Twitter). Supports regular posts with images/videos and X Articles (long-form Markdown). Uses real Chrome with CDP to bypass anti-automation. Use when user asks to "post to X", "tweet", "publish to Twitter", or "share on X".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-post-to-x
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Post to X (Twitter)
|
||||
@@ -12,9 +20,9 @@ Posts text, images, videos, and long-form articles to X via real Chrome browser
|
||||
**Important**: All scripts are located in the `scripts/` subdirectory of this skill.
|
||||
|
||||
**Agent Execution Instructions**:
|
||||
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
|
||||
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
|
||||
3. Replace all `${SKILL_DIR}` in this document with the actual path
|
||||
1. Determine this SKILL.md file's directory path as `{baseDir}`
|
||||
2. Script path = `{baseDir}/scripts/<script-name>.ts`
|
||||
3. Replace all `{baseDir}` in this document with the actual path
|
||||
4. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
|
||||
**Script Reference**:
|
||||
@@ -36,12 +44,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-post-to-x/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-post-to-x/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-post-to-x/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-post-to-x/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-post-to-x/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-post-to-x/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -74,7 +85,7 @@ if (Test-Path "$HOME/.baoyu-skills/baoyu-post-to-x/EXTEND.md") { "user" }
|
||||
Before first use, suggest running the environment check. User can skip if they prefer.
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/check-paste-permissions.ts
|
||||
${BUN_X} {baseDir}/scripts/check-paste-permissions.ts
|
||||
```
|
||||
|
||||
Checks: Chrome, profile isolation, Bun, Accessibility, clipboard, paste keystroke, Chrome conflicts.
|
||||
@@ -107,7 +118,7 @@ Unless the user explicitly specifies the post type:
|
||||
## Regular Posts
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-browser.ts "Hello!" --image ./photo.png
|
||||
${BUN_X} {baseDir}/scripts/x-browser.ts "Hello!" --image ./photo.png
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
@@ -126,7 +137,7 @@ ${BUN_X} ${SKILL_DIR}/scripts/x-browser.ts "Hello!" --image ./photo.png
|
||||
Text + video file.
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-video.ts "Check this out!" --video ./clip.mp4
|
||||
${BUN_X} {baseDir}/scripts/x-video.ts "Check this out!" --video ./clip.mp4
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
@@ -147,7 +158,7 @@ ${BUN_X} ${SKILL_DIR}/scripts/x-video.ts "Check this out!" --video ./clip.mp4
|
||||
Quote an existing tweet with comment.
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123 "Great insight!"
|
||||
${BUN_X} {baseDir}/scripts/x-quote.ts https://x.com/user/status/123 "Great insight!"
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
@@ -166,8 +177,8 @@ ${BUN_X} ${SKILL_DIR}/scripts/x-quote.ts https://x.com/user/status/123 "Great in
|
||||
Long-form Markdown articles (requires X Premium).
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg
|
||||
${BUN_X} {baseDir}/scripts/x-article.ts article.md
|
||||
${BUN_X} {baseDir}/scripts/x-article.ts article.md --cover ./cover.jpg
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
|
||||
@@ -12,13 +12,13 @@ Publish Markdown articles to X Articles editor with rich text formatting and ima
|
||||
|
||||
```bash
|
||||
# Publish markdown article (preview mode)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md
|
||||
${BUN_X} {baseDir}/scripts/x-article.ts article.md
|
||||
|
||||
# With custom cover image
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md --cover ./cover.jpg
|
||||
${BUN_X} {baseDir}/scripts/x-article.ts article.md --cover ./cover.jpg
|
||||
|
||||
# Actually publish
|
||||
${BUN_X} ${SKILL_DIR}/scripts/x-article.ts article.md --submit
|
||||
${BUN_X} {baseDir}/scripts/x-article.ts article.md --submit
|
||||
```
|
||||
|
||||
## Markdown Format
|
||||
@@ -76,13 +76,13 @@ Convert markdown and inspect structure:
|
||||
|
||||
```bash
|
||||
# Get JSON with all metadata
|
||||
${BUN_X} ${SKILL_DIR}/scripts/md-to-html.ts article.md
|
||||
${BUN_X} {baseDir}/scripts/md-to-html.ts article.md
|
||||
|
||||
# Output HTML only
|
||||
${BUN_X} ${SKILL_DIR}/scripts/md-to-html.ts article.md --html-only
|
||||
${BUN_X} {baseDir}/scripts/md-to-html.ts article.md --html-only
|
||||
|
||||
# Save HTML to file
|
||||
${BUN_X} ${SKILL_DIR}/scripts/md-to-html.ts article.md --save-html /tmp/article.html
|
||||
${BUN_X} {baseDir}/scripts/md-to-html.ts article.md --save-html /tmp/article.html
|
||||
```
|
||||
|
||||
JSON output:
|
||||
@@ -161,7 +161,7 @@ Claude:
|
||||
- **No create button**: Ensure X Premium subscription is active
|
||||
- **Cover upload fails**: Check file path and format (PNG, JPEG)
|
||||
- **Images not inserting**: Verify placeholders exist in pasted content
|
||||
- **Content not pasting**: Check HTML clipboard: `${BUN_X} ${SKILL_DIR}/scripts/copy-to-clipboard.ts html --file /tmp/test.html`
|
||||
- **Content not pasting**: Check HTML clipboard: `${BUN_X} {baseDir}/scripts/copy-to-clipboard.ts html --file /tmp/test.html`
|
||||
|
||||
## How It Works
|
||||
|
||||
|
||||
@@ -9,20 +9,20 @@ If you prefer step-by-step control:
|
||||
### Step 1: Copy Image to Clipboard
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/copy-to-clipboard.ts image /path/to/image.png
|
||||
${BUN_X} {baseDir}/scripts/copy-to-clipboard.ts image /path/to/image.png
|
||||
```
|
||||
|
||||
### Step 2: Paste from Clipboard
|
||||
|
||||
```bash
|
||||
# Simple paste to frontmost app
|
||||
${BUN_X} ${SKILL_DIR}/scripts/paste-from-clipboard.ts
|
||||
${BUN_X} {baseDir}/scripts/paste-from-clipboard.ts
|
||||
|
||||
# Paste to Chrome with retries
|
||||
${BUN_X} ${SKILL_DIR}/scripts/paste-from-clipboard.ts --app "Google Chrome" --retries 5
|
||||
${BUN_X} {baseDir}/scripts/paste-from-clipboard.ts --app "Google Chrome" --retries 5
|
||||
|
||||
# Quick paste with shorter delay
|
||||
${BUN_X} ${SKILL_DIR}/scripts/paste-from-clipboard.ts --delay 200
|
||||
${BUN_X} {baseDir}/scripts/paste-from-clipboard.ts --delay 200
|
||||
```
|
||||
|
||||
### Step 3: Use Playwright MCP (if Chrome session available)
|
||||
@@ -59,7 +59,7 @@ mcp__playwright__browser_take_screenshot filename="preview.png"
|
||||
User: /post-to-x "Hello from Claude!" --image ./screenshot.png
|
||||
|
||||
Claude:
|
||||
1. Runs: ${BUN_X} ${SKILL_DIR}/scripts/x-browser.ts "Hello from Claude!" --image ./screenshot.png
|
||||
1. Runs: ${BUN_X} {baseDir}/scripts/x-browser.ts "Hello from Claude!" --image ./screenshot.png
|
||||
2. Chrome opens with X compose page
|
||||
3. Text is typed into editor
|
||||
4. Image is copied to clipboard and pasted
|
||||
@@ -72,7 +72,7 @@ Claude:
|
||||
- **Chrome not found**: Set `X_BROWSER_CHROME_PATH` environment variable
|
||||
- **Not logged in**: First run opens Chrome - log in manually, cookies are saved
|
||||
- **Image paste fails**:
|
||||
- Verify clipboard script: `${BUN_X} ${SKILL_DIR}/scripts/copy-to-clipboard.ts image <path>`
|
||||
- Verify clipboard script: `${BUN_X} {baseDir}/scripts/copy-to-clipboard.ts image <path>`
|
||||
- On macOS, grant "Accessibility" permission to Terminal/iTerm in System Settings > Privacy & Security > Accessibility
|
||||
- Keep Chrome window visible and in front during paste operations
|
||||
- **osascript permission denied**: Grant Terminal accessibility permissions in System Preferences
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
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".
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-slide-deck
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Slide Deck Generator
|
||||
@@ -22,8 +30,8 @@ Transform content into professional slide deck images.
|
||||
## Script Directory
|
||||
|
||||
**Agent Execution Instructions**:
|
||||
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
|
||||
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
|
||||
1. Determine this SKILL.md file's directory path as `{baseDir}`
|
||||
2. Script path = `{baseDir}/scripts/<script-name>.ts`
|
||||
3. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
|
||||
| Script | Purpose |
|
||||
@@ -195,12 +203,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-slide-deck/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-slide-deck/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-slide-deck/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-slide-deck/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-slide-deck/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-slide-deck/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -555,8 +566,8 @@ options:
|
||||
### Step 8: Merge to PPTX and PDF
|
||||
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/merge-to-pptx.ts <slide-deck-dir>
|
||||
${BUN_X} ${SKILL_DIR}/scripts/merge-to-pdf.ts <slide-deck-dir>
|
||||
${BUN_X} {baseDir}/scripts/merge-to-pptx.ts <slide-deck-dir>
|
||||
${BUN_X} {baseDir}/scripts/merge-to-pdf.ts <slide-deck-dir>
|
||||
```
|
||||
|
||||
### Step 9: Output Summary
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-translate
|
||||
description: Translates articles and documents between languages with three modes - quick (direct), normal (analyze then translate), and refined (analyze, translate, review, polish). Supports custom glossaries and terminology consistency via EXTEND.md. Use when user asks to "translate", "翻译", "精翻", "translate article", "translate to Chinese/English", "改成中文", "改成英文", "convert to Chinese", "localize", "本地化", or needs any document translation. Also triggers for "refined translation", "精细翻译", "proofread translation", "快速翻译", "快翻", "这篇文章翻译一下", or when a URL or file is provided with translation intent.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-translate
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# Translator
|
||||
@@ -9,7 +17,7 @@ Three-mode translation skill: **quick** for direct translation, **normal** for a
|
||||
|
||||
## Script Directory
|
||||
|
||||
Scripts in `scripts/` subdirectory. `${SKILL_DIR}` = this SKILL.md's directory path. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `${SKILL_DIR}` and `${BUN_X}` with actual values.
|
||||
Scripts in `scripts/` subdirectory. `{baseDir}` = this SKILL.md's directory path. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. Replace `{baseDir}` and `${BUN_X}` with actual values.
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
@@ -22,12 +30,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-translate/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-translate/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-translate/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-translate/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-translate/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-translate/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -172,7 +183,7 @@ Before translating chunks:
|
||||
|
||||
1. **Extract terminology**: Scan entire document for proper nouns, technical terms, recurring phrases
|
||||
2. **Build session glossary**: Merge extracted terms with loaded glossaries, establish consistent translations
|
||||
3. **Split into chunks**: Use `${BUN_X} ${SKILL_DIR}/scripts/chunk.ts <file> [--max-words <chunk_max_words>] [--output-dir <output-dir>]`
|
||||
3. **Split into chunks**: Use `${BUN_X} {baseDir}/scripts/chunk.ts <file> [--max-words <chunk_max_words>] [--output-dir <output-dir>]`
|
||||
- Parses markdown AST (headings, paragraphs, lists, code blocks, tables, etc.)
|
||||
- Splits at markdown block boundaries to preserve structure
|
||||
- If a single block exceeds the threshold, falls back to line splitting, then word splitting
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
---
|
||||
name: baoyu-url-to-markdown
|
||||
description: Fetch any URL and convert to markdown using Chrome CDP. Saves the rendered HTML snapshot alongside the markdown, and automatically falls back to the pre-Defuddle HTML-to-Markdown pipeline when Defuddle fails. 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.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-url-to-markdown
|
||||
requires:
|
||||
anyBins:
|
||||
- bun
|
||||
- npx
|
||||
---
|
||||
|
||||
# URL to Markdown
|
||||
@@ -12,10 +20,10 @@ Fetches any URL via Chrome CDP, saves the rendered HTML snapshot, and converts i
|
||||
**Important**: All scripts are located in the `scripts/` subdirectory of this skill.
|
||||
|
||||
**Agent Execution Instructions**:
|
||||
1. Determine this SKILL.md file's directory path as `SKILL_DIR`
|
||||
2. Script path = `${SKILL_DIR}/scripts/<script-name>.ts`
|
||||
1. Determine this SKILL.md file's directory path as `{baseDir}`
|
||||
2. Script path = `{baseDir}/scripts/<script-name>.ts`
|
||||
3. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun
|
||||
4. Replace all `${SKILL_DIR}` and `${BUN_X}` in this document with actual values
|
||||
4. Replace all `{baseDir}` and `${BUN_X}` in this document with actual values
|
||||
|
||||
**Script Reference**:
|
||||
| Script | Purpose |
|
||||
@@ -30,12 +38,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-url-to-markdown/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-url-to-markdown/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-url-to-markdown/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-url-to-markdown/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-url-to-markdown/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-url-to-markdown/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
@@ -112,19 +123,19 @@ Full reference: [references/config/first-time-setup.md](references/config/first-
|
||||
|
||||
```bash
|
||||
# Auto mode (default) - capture when page loads
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url>
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url>
|
||||
|
||||
# Wait mode - wait for user signal before capture
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url> --wait
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url> --wait
|
||||
|
||||
# Save to specific file
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url> -o output.md
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url> -o output.md
|
||||
|
||||
# Save to a custom output directory (auto-generates filename)
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url> --output-dir ./posts/
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url> --output-dir ./posts/
|
||||
|
||||
# Download images and videos to local directories
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts <url> --download-media
|
||||
${BUN_X} {baseDir}/scripts/main.ts <url> --download-media
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
name: baoyu-xhs-images
|
||||
description: Generates Xiaohongshu (Little Red Book) infographic series with 11 visual styles and 8 layouts. Breaks content into 1-10 cartoon-style images optimized for XHS engagement. Use when user mentions "小红书图片", "XHS images", "RedNote infographics", "小红书种草", or wants social media infographics for Chinese platforms.
|
||||
version: 1.56.1
|
||||
metadata:
|
||||
openclaw:
|
||||
homepage: https://github.com/JimLiu/baoyu-skills#baoyu-xhs-images
|
||||
---
|
||||
|
||||
# Xiaohongshu Infographic Series Generator
|
||||
@@ -274,12 +278,15 @@ Check EXTEND.md existence (priority order):
|
||||
```bash
|
||||
# macOS, Linux, WSL, Git Bash
|
||||
test -f .baoyu-skills/baoyu-xhs-images/EXTEND.md && echo "project"
|
||||
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/baoyu-skills/baoyu-xhs-images/EXTEND.md" && echo "xdg"
|
||||
test -f "$HOME/.baoyu-skills/baoyu-xhs-images/EXTEND.md" && echo "user"
|
||||
```
|
||||
|
||||
```powershell
|
||||
# PowerShell (Windows)
|
||||
if (Test-Path .baoyu-skills/baoyu-xhs-images/EXTEND.md) { "project" }
|
||||
$xdg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$HOME/.config" }
|
||||
if (Test-Path "$xdg/baoyu-skills/baoyu-xhs-images/EXTEND.md") { "xdg" }
|
||||
if (Test-Path "$HOME/.baoyu-skills/baoyu-xhs-images/EXTEND.md") { "user" }
|
||||
```
|
||||
|
||||
|
||||
@@ -211,13 +211,9 @@ If preferences include watermark:
|
||||
When generating multiple images in a series:
|
||||
|
||||
1. **Image 1 (cover)**: Generate without `--ref` — this establishes the visual anchor
|
||||
2. **Images 2+**: Always pass image 1 as `--ref` to the image generation skill:
|
||||
```bash
|
||||
${BUN_X} ${SKILL_DIR}/scripts/main.ts \
|
||||
--promptfiles prompts/02-content-xxx.md \
|
||||
--ref path/to/01-cover-xxx.png \
|
||||
--image 02-content-xxx.png --ar 3:4 --quality 2k
|
||||
```
|
||||
2. **Images 2+**: Always pass image 1 as `--ref` to the installed image generation skill.
|
||||
Read that skill's `SKILL.md` and use its documented interface rather than calling its scripts directly.
|
||||
For each later image, use the assembled prompt file as input, set the output image path, keep aspect ratio `3:4`, use quality `2k`, and pass image 1 as the reference.
|
||||
This ensures the AI maintains the same character design, illustration style, and color rendering across the series.
|
||||
|
||||
### Step 6: Combine
|
||||
|
||||
Reference in New Issue
Block a user