skills/hexo-blog-manager/SKILL.md
Manage the user's configured Hexo blog repository and configured image-hosting repository through GitHub CLI (`gh`) against online repositories by default. Use when Codex needs to create or update Hexo posts, generate or replace blog covers, generate or revise blog article content, upload images and write CDN links, fix Hexo post frontmatter or rendering issues, configure the Hexo blog workflow, or commit/push blog changes. Always read repository names, paths, CDN base URLs, image generation settings, and blog content style from `~/.config/hexo/config.yaml`; prefer GitHub Contents API operations over looking for local files, local clones, or broad local git staging.
npx skillsauth add imhansiy/my-skills hexo-blog-managerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill defines the standard operating procedure (SOP) for managing the Hexo blog repository and image-hosting repository configured in ~/.config/hexo/config.yaml.
~/.config/hexo/config.yaml before deciding repository names, CDN base URLs, posts paths, API base URLs, models, or image sizes. Do not hardcode a specific blog repository, OSS repository, CDN host, or local checkout path.gh. Do not look for the user's local Hexo repo, clone repositories, or edit local blog files unless the user explicitly asks for local work. Treat the configured hexo_blog.repo and github_oss.repo as the source of truth.gh api /repos/<owner>/<repo>/contents/<path> or gh api --method PUT ... --input <payload.json>. For updates, fetch the current file SHA first and include it in the PUT payload.gh api; clean them up after successful upload/update.create_post.py --auto-commit as unsafe for an existing dirty repository: it may stage broad changes with git add .. Prefer manual git commands, stage only task-related files, and inspect git status --short before and after every Hexo generation step.hexo generate, hexo server, and plugin validation can rewrite frontmatter in unrelated posts, especially abbrlink, YAML array formatting, and folded URLs. If the user did not ask for those changes, restore those files before committing.public/, db.json, temporary payload JSON, generated cover previews, or unrelated frontmatter churn unless the user explicitly asks for them.<div class="mermaid"> is not enough; the active theme must load Mermaid JS and run initialization after first load and PJAX navigation.github_oss.repo, verify the uploaded file exists or the CDN URL resolves, then update banner and headimg.package.json and Hexo config files. Use the plugin's documented tag/filter/frontmatter syntax instead of inventing Markdown or HTML.blog_content style settings. Do not impose a fixed writing style from this skill when blog_content is empty; ask the user or infer from existing posts only when appropriate.~/.config/hexo/config.yamlpython <SKILL_PATH>/scripts/hexo_config.py init 创建默认配置image_api:
base_url: "<image-api-base-url>" # API 地址
api_key: "your-api-key-here" # API 密钥(必填)
model: "<image-model>" # 图片生成模型
size: "<image-size>" # 图片尺寸(建议 16:9)
default_prompt_style: "cinematic tech-futuristic style, vibrant lighting, 8k resolution"
github:
token: "ghp_xxxxxxxxxxxx" # GitHub Personal Access Token
use_gh_cli: true # 是否使用 gh CLI 认证(优先级高于 token)
github_oss:
repo: "<owner>/<image-repo>"
cdn_base: "https://cdn.example.com/gh/<owner>/<image-repo>@main"
hexo_blog:
repo: "<owner>/<hexo-repo>"
posts_path: "source/_posts"
blog_content:
style_prompt: "" # 正文写作风格总提示词;为空时不要硬套固定风格
audience: "" # 目标读者,例如 小白/开发者/运维/产品用户
tone: "" # 语气,例如 直接、技术博客、教程式、复盘式
structure: [] # 推荐章节结构;为空时按主题自然组织
language: "zh-CN" # 正文语言
requirements: [] # 固定要求,例如 多用示例、避免营销腔、保留代码块
支持两种认证方式(按优先级):
| 方式 | 配置 | 说明 |
|------|------|------|
| gh CLI(默认) | use_gh_cli: true | 使用 gh auth login 的 OAuth token |
| Personal Access Token | token: "ghp_xxx" | 直接使用 GitHub PAT |
# 先登录 GitHub CLI
gh auth login
# 配置自动使用 gh CLI
python hexo_config.py show # 确认 use_gh_cli: true
# 设置 GitHub Personal Access Token
python hexo_config.py set-github-token ghp_xxxxxxxxxxxxxxxxxxxx
Token 权限要求:
repo - 完整仓库访问权限workflow - 如果需要触发 GitHub Actions# 查看当前配置
python <SKILL_PATH>/scripts/hexo_config.py show
# 检查配置完整性
python <SKILL_PATH>/scripts/hexo_config.py check
# 设置图片 API Key
python <SKILL_PATH>/scripts/hexo_config.py set-api-key <your-api-key>
# 设置 GitHub Token(如果不使用 gh CLI)
python <SKILL_PATH>/scripts/hexo_config.py set-github-token <your-github-token>
# 初始化默认配置
python <SKILL_PATH>/scripts/hexo_config.py init
默认不要使用本地脚本直接改博客仓库。只有当用户明确要求生成本地草稿、临时预览或离线编辑时,才使用 create_post.py。
python <SKILL_PATH>/scripts/create_post.py --title "博客标题" [选项]
| 参数 | 说明 | 示例 |
|------|------|------|
| --title, -t | 博客标题(必填) | --title "Python 入门教程" |
| --tags | 标签,逗号分隔 | --tags "Python,编程,教程" |
| --category, -c | 分类 | --category "编程" |
| --skip-cover | 跳过封面生成 | --skip-cover |
| --skip-upload | 跳过封面上传 | --skip-upload |
| --auto-commit | 自动提交到 GitHub;仅适合全新、干净、专用输出目录,不要在已有 Hexo 仓库中默认使用 | --auto-commit |
| --output, -o | 输出目录 | --output ./posts |
# 基础用法(生成封面 + 创建 Markdown)
python <SKILL_PATH>/scripts/create_post.py --title "我的第一篇博客"
# 完整用法(仅限全新专用输出目录;已有仓库优先手动 stage/commit)
python <SKILL_PATH>/scripts/create_post.py \
--title "Python 异步编程指南" \
--tags "Python,异步,编程" \
--category "技术" \
--output ./drafts
# 跳过封面(快速创建)
python <SKILL_PATH>/scripts/create_post.py \
--title "快速笔记" \
--skip-cover \
--output ./drafts
┌─────────────────────────────────────────────────────────┐
│ Step 1: 检查配置 │
│ → 验证 API Key 和配置完整性 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Step 2: 生成封面图片 │
│ → 调用 AI API 生成 16:9 封面 │
│ → 保存到临时目录 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Step 3: 上传封面到 OSS │
│ → 上传到配置的图片仓库 │
│ → 获取 CDN 链接 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Step 4: 创建本地 Markdown 草稿 │
│ → 生成带 Frontmatter 的 .md 文件 │
│ → 包含标题、日期、标签、封面链接 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Step 5: 上传到 GitHub(使用 gh api 推荐) │
│ → 读取线上目标路径和 SHA │
│ → PUT 到 GitHub Contents API │
│ → 验证线上文件 │
└─────────────────────────────────────────────────────────┘
python <SKILL_PATH>/scripts/hexo_config.py init 创建配置文件python <SKILL_PATH>/scripts/hexo_config.py set-api-key <key> 保存python <SKILL_PATH>/scripts/hexo_config.py checkUse this workflow unless the user explicitly asks to work in a local checkout:
BLOG_REPO: read from hexo_blog.repoOSS_REPO: read from github_oss.repoPOSTS_PATH: read from hexo_blog.posts_pathCDN_BASE: read from github_oss.cdn_base$POSTS_PATH/<post>.mdgh api:
gh api /repos/$BLOG_REPO/contents/$POSTS_PATH/post.md --jq ".content" | base64 -d
Also capture .sha before updating:
gh api /repos/$BLOG_REPO/contents/$POSTS_PATH/post.md --jq ".sha"
{
"message": "fix(blog): update post frontmatter",
"content": "<base64-encoded-new-file>",
"sha": "<current-file-sha>",
"branch": "main"
}
gh api --method PUT /repos/$BLOG_REPO/contents/$POSTS_PATH/post.md --input payload.json
$OSS_REPO the same way, but omit sha when creating a new file.gh api after every write. Do not assume a local file reflects GitHub.Only use create_post.py when the user explicitly wants a local draft. For normal blog work, create or update the online file through the GitHub workflow above:
python <SKILL_PATH>/scripts/create_post.py --title "博客标题" --tags "标签1,标签2" --category "分类" --output ./drafts
已有 Hexo 仓库中不要默认使用 --auto-commit;脚本的提交逻辑会复制文件并 broad-stage,容易混入无关文件。
When a Hexo post requires an image (screenshot, diagram, asset):
github_oss.repo.img/YY-MM-DD/filename.extension unless config or the user specifies another asset convention.{"message": "...", "content": "..."} to a temporary file.gh api --method PUT ... --input temp.json.gh api /repos/$OSS_REPO/contents/img/YY-MM-DD/filename.extension.$CDN_BASE/img/YY-MM-DD/filename.extension, where CDN_BASE comes from config.To make the Hexo blog post list look more professional and textured, generate a cover image using the configured API:
image_api.base_url and image_api.api_key from ~/.config/hexo/config.yaml.image_api.model from config.image_api.size from config; use 16:9 when the config does not specify a size.gh api, then update the online Hexo post with the configured CDN URL using gh api.Check Configuration: Verify API config is complete:
python <SKILL_PATH>/scripts/hexo_config.py check
If not configured, guide user to set up API key.
Generate Image: Run the script with title or custom prompt:
# Using blog title (auto-generates professional prompt)
python <SKILL_PATH>/scripts/generate_cover.py --title "Your Blog Title" cover.png
# Using custom prompt
python <SKILL_PATH>/scripts/generate_cover.py "A futuristic tech workspace with holographic displays" cover.png
# With custom style
python <SKILL_PATH>/scripts/generate_cover.py --title "Your Title" --style "minimalist, dark theme" cover.png
If the default generated prompt is too generic, use a custom prompt. For example:
python <SKILL_PATH>/scripts/generate_cover.py "16:9 editorial tech blog cover for a Go project bypassing AWS anti-bot detection: Chrome TLS fingerprint visualization, browser fingerprint signals, AWS cloud gateway, clean cinematic composition, no text overlay" cover.png
User Review (Mandatory): Show the generated cover.png to the user and wait for user confirmation before proceeding. If the user is not satisfied, adjust the prompt and regenerate.
Store Assets: Only after user approval, upload the image to the configured image repository:
python <SKILL_PATH>/scripts/upload_prep.py cover.png "oss: add blog cover"gh api --method PUT /repos/$OSS_REPO/contents/img/YY-MM-DD/cover.png --input temp_payload.jsonEnvironment Cleanup: After a successful upload, you must delete all locally generated image files, temporary JSON files, and any temporary scripts used during the process.
Update Online Post Frontmatter: Fetch the target post from the configured blog repository, preserve existing frontmatter, replace only banner and headimg, and PUT the updated file back with its current SHA.
banner: <CDN_LINK> and headimg: <CDN_LINK> fields to configure the cover display in the Hexo environment.hexo_blog.repo.$POSTS_PATH/your-post-title.md, where POSTS_PATH is read from hexo_blog.posts_path.gh api to read the online file, update content, and PUT it back with the current SHA. Do not search local checkout paths unless explicitly requested.blog_content from config and apply style_prompt, audience, tone, structure, language, and requirements.---
title: Post Title
date: YYYY-MM-DD HH:mm:ss
tags: [Tag1, Tag2]
categories: [Category1]
banner: <CDN_LINK>
headimg: <CDN_LINK>
---
github_oss.cdn_base.Use this workflow when creating a new article body, expanding a draft, rewriting a section, or adapting generated content to the user's blog:
blog_content from ~/.config/hexo/config.yaml.blog_content.style_prompt is present, treat it as the primary writing instruction.audience: choose depth, terminology, and explanation level.tone: control voice and sentence style.structure: use the configured section order unless the user asks otherwise.language: write in that language.requirements: enforce each listed rule.blog_content is empty and the user did not provide style instructions, do not invent a house style. Ask for style preferences when the task is mostly writing; for small edits, preserve the existing article's voice.blog_content requests it.Use this workflow before adding tag plugins, diagrams, encrypted sections, math, media embeds, galleries, custom frontmatter, or any syntax that is not plain Markdown:
gh api /repos/$BLOG_REPO/contents/package.json --jq ".content" | base64 -d
Identify Hexo plugins from dependency names such as hexo-tag-*, hexo-filter-*, hexo-generator-*, hexo-renderer-*, and theme packages.gh api /repos/$BLOG_REPO/contents/_config.yml --jq ".content" | base64 -d
gh api /repos/$BLOG_REPO/contents/_config.volantis.yml --jq ".content" | base64 -d
gh api /search/code -f q="repo:<BLOG_REPO> \"{% mermaid %}\" path:<POSTS_PATH>"
gh api /search/code -f q="repo:<BLOG_REPO> \"markmap\" path:<POSTS_PATH>"
hexo-tag-mermaid: use {% mermaid %} ... {% endmermaid %}; do not wrap the block in triple backticks.{% endmermaid %}.<div class="mermaid">, verify the active theme loads the required browser runtime.Use this workflow when the user reports that a post renders incorrectly:
gh api; inspect the fetched content for unbalanced fences, tag plugins, raw HTML, and escaped text. Use local search only on temporary fetched content, not on a local repo.gh api.{% endmermaid %}.{% mermaid %} ... {% endmermaid %}.<div class="mermaid">...</div> but the page still shows source text, the active theme is missing Mermaid runtime initialization. Inject Mermaid JS in the active Hexo config and add a small initializer that runs on DOMContentLoaded and pjax:complete.A["bin[0] = 12000"] and B["获取信号量: sem <- struct{}{}"].document.querySelectorAll('.mermaid svg').length should match the number of Mermaid blocks and .error-icon count should be zero.oss: add screenshot for post X or feat: new hexo post about Y.gh api or other gh commands against online repositories by default. Do not browse or depend on local repository state unless explicitly requested.git add . when Hexo generation may rewrite unrelated posts.gh api.--input argument.gh api before officially writing the image link into the Hexo post.package.json, config, examples, or official docs.This is a Hexo-专用 (Hexo-dedicated) skill. Whenever the user mentions:
This skill should be triggered and applied.
tools
MUST USE before playwright/dev-browser/local browser tools when any remote Browserless target is configured or when the user mentions Browserless, remote browser, headless Chrome endpoint, screenshots, PDFs, rendered HTML, scraping, dynamic public webpages, browser automation, webpage debugging, clicking/typing page elements, Puppeteer/Playwright sessions, or provides a Browserless URL/token/name. This skill has priority over generic browser skills for public HTTP(S) pages; use remote Browserless first, then fall back to local Playwright/dev-browser only after Browserless health/action failure, unreachable target, or a local/private page that cannot be exposed publicly. Manages Browserless endpoints/tokens and uses the bundled Node.js script for automation.
tools
Manage CLIProxyAPI or CLIProxyAPIPlus only: save CLIProxyAPI Management API URL and password under the user's home .config/cliproxyapi directory, call every CLIProxyAPI Management API endpoint, manage config/auth files/provider keys/model aliases/logs/usage/OAuth URLs, and work on Windows, Linux, and macOS without opening the web UI.
development
Triggered when the user requests an image (e.g., architecture, flowchart, sequence diagram) or needs a technical illustration inserted into a document. This skill dynamically generates and inserts images using the official PlantUML public API.
development
Use proactively for Odoo work. Connect AI coding agents to Odoo through Python OdooRPC profiles, inspect live records, troubleshoot models, fields, access rights, modules, companies, connectors, imports, synchronization issues, odoo.conf, addons paths, backup restore, filestore checks, and guarded create/update/delete workflows.