blog-publish
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseblog-publish — Generate & Publish Blog Posts
blog-publish — 生成并发布博客文章
⚠️ DO NOT assume Node.js, pnpm, git, or any build tools are required. This skill has three access tiers. The lowest tier (Tier 3) works with only+curl+ a GitHub token. No git, no Node.js, no pnpm, no local clone. Always check what's available and use the highest tier that works. NEVER tell the user they must install git/Node/pnpm — they are NOT required.jq
Turn any project or idea into a polished blog post and publish it to
. Also supports editing existing posts.
kelegele/agent-blog⚠️ 请勿假设需要Node.js、pnpm、git或任何构建工具。 此Skill包含三个访问层级。最低层级(Tier 3)仅需+curl+ GitHub令牌即可运行。无需git、Node.js、pnpm, 也无需本地克隆仓库。请始终检查可用环境,使用能正常运行的最高层级。绝对不要告知用户必须安装git/Node.js/pnpm——这些并非必需。jq
可将任意项目或想法转化为精美的博客文章,并发布至仓库。同时支持编辑已有文章。
kelegele/agent-blogBlog Repo Reference
博客仓库参考信息
| Item | Value |
|---|---|
| Remote | |
| Branch | |
| Posts dir | |
| Images dir | |
| Schema | |
| Auto-deploy | Vercel (push to |
| 项 | 值 |
|---|---|
| 远程仓库地址 | |
| 分支 | |
| 文章目录 | |
| 图片目录 | |
| 元数据Schema | |
| 自动部署 | Vercel(推送至 |
Article Staging Location
文章暂存位置
Generated articles are saved to a local file for review before publishing.
The staging location depends on the active tier:
| Tier | Article staging path |
|---|---|
| 1 — Local clone | |
| 2 — Sparse clone | |
| 3 — REST API | |
Why for Tier 3? When there's no blog repo clone, the
article needs a local home for editing and preview. The directory is a
conventional place for documentation in any project. The subdirectory
keeps it isolated from the project's own docs. Create it if it doesn't exist:
./docs/blog-publish/docs/blog-publishbash
mkdir -p ./docs/blog-publishAfter the article is published (pushed to remote via API), this local copy remains
as a backup. Tell the user they can delete it or keep it.
生成的文章会保存到本地文件中,供发布前审核。暂存位置取决于当前使用的访问层级:
| 层级 | 文章暂存路径 |
|---|---|
| 1 — 本地克隆仓库 | |
| 2 — 稀疏克隆仓库 | |
| 3 — REST API | |
为什么Tier 3使用? 当没有克隆博客仓库时,文章需要一个本地位置用于编辑和预览。目录是各类项目中存放文档的常规位置。子目录可将文章与项目自身文档隔离开。如果该目录不存在,请创建它:
./docs/blog-publish/docs/blog-publishbash
mkdir -p ./docs/blog-publish文章发布后(通过API推送至远程仓库),此本地副本会保留作为备份。请告知用户可选择删除或保留该文件。
Schema — Read Dynamically, Never Hardcode
Schema — 动态读取,切勿硬编码
The blog's frontmatter schema is defined in . Read this
file at runtime to get the current schema — do not rely on the snapshot below.
src/content.config.tsFile location:
src/content.config.tsKnown schema as of this writing (may change — always verify):
| Field | Type | Required | Default |
|---|---|---|---|
| | ✅ | — |
| | ✅ | — |
| | ✅ | — |
| | ✅ | — |
| | optional | — |
| | optional | |
If the schema changes in the future (e.g. a field is added), the agent
will pick it up automatically by reading this file.
tags博客的前置元数据Schema定义在中。请在运行时读取此文件以获取当前Schema——不要依赖下方的快照内容。
src/content.config.ts文件位置:
src/content.config.ts撰写本文时已知的Schema(可能会变更——请始终验证):
| 字段 | 类型 | 是否必填 | 默认值 |
|---|---|---|---|
| | ✅ | — |
| | ✅ | — |
| | ✅ | — |
| | ✅ | — |
| | 可选 | — |
| | 可选 | |
如果未来Schema发生变更(例如新增字段),Agent会通过读取此文件自动获取更新。
tagsAccess Tiers — Read & Write the Blog Repo
访问层级 — 读写博客仓库
Three tiers. Always try Tier 1 → 2 → 3 and use the highest one that works.
NEVER tell the user they need to install git, Node.js, or pnpm. If Tier 1
or 2 isn't available, use Tier 3 silently.
共三个层级。请始终尝试Tier 1 → 2 → 3,使用能正常运行的最高层级。
绝对不要告知用户需要安装git、Node.js或pnpm。 如果Tier 1或Tier 2不可用,请静默使用Tier 3。
Tier 1 — Existing Local Clone (fastest)
Tier 1 — 已有本地克隆仓库(速度最快)
Detection — check in order:
- env var
AGENT_BLOG_PATH ~/Projects/agent-blogfind ~ -maxdepth 3 -type d -name "agent-blog" 2>/dev/null | head -1
Permission check:
bash
cd {blog-repo} && git push --dry-run origin main 2>&1Read/write via filesystem + git.
检测顺序:
- 环境变量
AGENT_BLOG_PATH - 目录
~/Projects/agent-blog - 执行命令:
find ~ -maxdepth 3 -type d -name "agent-blog" 2>/dev/null | head -1
权限检查:
bash
cd {blog-repo} && git push --dry-run origin main 2>&1通过文件系统 + git进行读写操作。
Tier 2 — Shallow Sparse Clone (~1 MB download)
Tier 2 — 稀疏克隆仓库(约1MB下载量)
No local clone, but is available.
gitbash
BLOG_TMP=$(mktemp -d)
git clone --depth 1 --filter=blob:none --no-checkout \
https://github.com/kelegele/agent-blog.git "$BLOG_TMP"
cd "$BLOG_TMP"
git sparse-checkout init --cone
git sparse-checkout set \
src \
astro.config.mjs \
tsconfig.json \
package.json \
pnpm-lock.yaml \
pnpm-workspace.yaml \
public/favicon.ico \
public/logo.png \
public/logo-black-bg.png
git checkoutCleanup: after publish.
rm -rf "$BLOG_TMP"无本地克隆仓库,但可用。
gitbash
BLOG_TMP=$(mktemp -d)
git clone --depth 1 --filter=blob:none --no-checkout \
https://github.com/kelegele/agent-blog.git "$BLOG_TMP"
cd "$BLOG_TMP"
git sparse-checkout init --cone
git sparse-checkout set \
src \
astro.config.mjs \
tsconfig.json \
package.json \
pnpm-lock.yaml \
pnpm-workspace.yaml \
public/favicon.ico \
public/logo.png \
public/logo-black-bg.png
git checkout清理操作:发布完成后执行。
rm -rf "$BLOG_TMP"Tier 3 — Pure GitHub REST API (ZERO DEPENDENCIES)
Tier 3 — 纯GitHub REST API(零依赖)
No git, no Node.js, no pnpm, no local tools required.
Only needs + (pre-installed on macOS/Linux) and a GitHub PAT.
curljqRequired: or env var — a GitHub PAT with scope.
Create at:
GITHUB_TOKENGH_TOKENrepohttps://github.com/settings/tokens/new?scopes=repo&description=blog-publish-skillPermission check:
bash
curl -sf -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/kelegele/agent-blog \
| grep -q '"push":true' && echo "HAS_PUSH" || echo "NO_PUSH"Operations:
List posts:
bash
curl -sf -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog \
| jq -r '.[].name'Read a file:
bash
curl -sf -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/{path}" \
| jq -r '.content' | base64 -dCreate a file:
bash
B64=$(printf '%s' "$CONTENT" | base64)
curl -sf -X PUT -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog/{filename}.md" \
-d "{\"message\":\"post: add {title}\",\"content\":\"$B64\",\"branch\":\"main\"}"Update a file:
bash
SHA=$(curl -sf -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog/{filename}.md" \
| jq -r '.sha')
B64=$(printf '%s' "$UPDATED" | base64)
curl -sf -X PUT -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog/{filename}.md" \
-d "{\"message\":\"post: publish {title}\",\"content\":\"$B64\",\"branch\":\"main\",\"sha\":\"$SHA\"}"Upload an image:
bash
B64=$(base64 < /path/to/image.webp)
curl -sf -X PUT -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/public/blog/{categorySlug}/{name}.webp" \
-d "{\"message\":\"post: add image for {title}\",\"content\":\"$B64\",\"branch\":\"main\"}"无需git、Node.js、pnpm或任何本地工具。
仅需 + (macOS/Linux默认预装)和GitHub个人访问令牌(PAT)。
curljq必需条件: 环境变量或——拥有权限的GitHub PAT。
创建地址:
GITHUB_TOKENGH_TOKENrepohttps://github.com/settings/tokens/new?scopes=repo&description=blog-publish-skill权限检查:
bash
curl -sf -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/kelegele/agent-blog \
| grep -q '"push":true' && echo "HAS_PUSH" || echo "NO_PUSH"操作命令:
列出文章:
bash
curl -sf -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog \
| jq -r '.[].name'读取文件:
bash
curl -sf -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/{path}" \
| jq -r '.content' | base64 -d创建文件:
bash
B64=$(printf '%s' "$CONTENT" | base64)
curl -sf -X PUT -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog/{filename}.md" \
-d "{\"message\":\"post: add {title}\",\"content\":\"$B64\",\"branch\":\"main\"}"更新文件:
bash
SHA=$(curl -sf -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog/{filename}.md" \
| jq -r '.sha')
B64=$(printf '%s' "$UPDATED" | base64)
curl -sf -X PUT -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/src/content/blog/{filename}.md" \
-d "{\"message\":\"post: publish {title}\",\"content\":\"$B64\",\"branch\":\"main\",\"sha\":\"$SHA\"}"上传图片:
bash
B64=$(base64 < /path/to/image.webp)
curl -sf -X PUT -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/kelegele/agent-blog/contents/public/blog/{categorySlug}/{name}.webp" \
-d "{\"message\":\"post: add image for {title}\",\"content\":\"$B64\",\"branch\":\"main\"}"Tier Summary
层级总结
| Tier | Requires | Preview | Read | Write | Article staging |
|---|---|---|---|---|---|
| 1 — Local clone | git + local path | ✅ | filesystem | git push | |
| 2 — Sparse clone | git | ✅ | filesystem | git push | |
| 3 — REST API | | ✅ | API | API | |
Always try Tier 1 → 2 → 3. Announce active tier at startup.
| 层级 | 所需条件 | 预览功能 | 读取方式 | 写入方式 | 文章暂存位置 |
|---|---|---|---|---|---|
| 1 — 本地克隆仓库 | git + 本地路径 | ✅ | 文件系统 | git push | |
| 2 — 稀疏克隆仓库 | git | ✅ | 文件系统 | git push | |
| 3 — REST API | | ✅ | API | API | |
请始终尝试Tier 1 → 2 → 3。启动时需告知用户当前使用的层级。
Writing Standards — Cross-Platform & SEO/GEO
写作规范 — 跨平台与SEO/GEO优化
Articles published through this skill are likely to be republished to other
platforms (WeChat Official Account, 小红书, 知乎, 掘金, etc.) and will be
crawled by search engines and LLM training bots. Follow these rules.
通过此Skill发布的文章可能会同步至其他平台(微信公众号、小红书、知乎、掘金等),并会被搜索引擎和大语言模型训练爬虫抓取。请遵循以下规则。
Cross-Platform Compatibility
跨平台兼容性
Goal: The article should survive copy-paste into any platform's editor with
minimal formatting loss.
| Rule | Why |
|---|---|
| Use only standard Markdown — no HTML tags, no custom shortcodes, no platform-specific syntax | WeChat/小红书 editors strip HTML; plain Markdown renders consistently |
Avoid | |
Avoid footnotes ( | Most platforms don't render footnotes |
| Avoid tables unless essential | Many mobile platforms break table layout; prefer lists |
| Avoid nested lists > 2 levels deep | Copy-paste often flattens nesting |
| Don't rely on images for critical information | WeChat/小红书 may compress or reorder images |
Every image must have meaningful | Accessibility + survives text-only copy + helps SEO |
| Don't use emoji in headings or frontmatter | Some platforms strip emoji in titles |
| Keep paragraphs short (3–5 sentences max) | Mobile readability on WeChat/小红书 |
目标: 文章复制粘贴到任意平台编辑器时,格式损失最小。
| 规则 | 原因 |
|---|---|
| 仅使用标准Markdown——不使用HTML标签、自定义短代码或平台专属语法 | 微信/小红书编辑器会剥离HTML;纯Markdown在各平台渲染效果一致 |
正文避免使用 | 前置元数据中的 |
避免脚注( | 大多数平台不支持渲染脚注 |
| 非必要不使用表格——优先使用列表 | 许多移动端平台会破坏表格布局;列表可读性更强 |
| 避免嵌套层级超过2级的列表 | 复制粘贴时常会扁平化嵌套结构 |
| 不要依赖图片传递关键信息 | 微信/小红书可能会压缩或重排图片 |
每张图片必须包含有意义的 | 提升可访问性 + 支持纯文本复制 + 利于SEO |
| 标题或前置元数据中不要使用emoji | 部分平台会剥离标题中的emoji |
| 段落保持简短(最多3-5句话) | 提升微信/小红书等平台的移动端可读性 |
Platform Safety — Content Restrictions
平台安全 — 内容限制
The article MUST NOT contain content that would be flagged or blocked on major
Chinese content platforms (微信、小红书、知乎、掘金).
When writing for Chinese audiences, avoid:
- Political sensitive terms or references
- Unsubstantiated claims about companies, products, or individuals
- Direct URLs to blocked/regulated sites (use descriptive text instead)
- Promotional language that reads like an ad (unless the article IS sponsored)
- Excessive use of superlatives ("最强", "第一", "最好" without citation)
- Unverified statistics or data without attribution
When in doubt, write with a neutral, informative tone. State facts, not opinions
about controversial topics.
文章绝对不能包含会在国内主流内容平台(微信、小红书、知乎、掘金)被标记或屏蔽的内容。
面向中文读者写作时,请避免:
- 政治敏感术语或相关内容
- 对企业、产品或个人的无根据指控
- 直接链接被屏蔽/监管的网站(改用描述性文字)
- 类似广告的推广语(除非文章本身是赞助内容)
- 过度使用最高级词汇(无引用依据的“最强”、“第一”、“最好”)
- 未经验证且无来源的统计数据
如有疑问,请保持中立、客观的信息性语气。陈述事实,而非对争议话题发表观点。
SEO (Search Engine Optimization)
搜索引擎优化(SEO)
| Rule | Details |
|---|---|
| Search engines truncate longer titles |
| Optimal length for SERP snippet |
Front-load keywords in | Put the most important concept in the first half |
Use descriptive | Search engines use headings to understand structure |
| Natural keyword density | Mention key terms naturally 3–5 times across the article — don't stuff |
| Internal links | Link to other blog posts when relevant: |
| External authority links | Link to docs, papers, or official sources when making claims |
| Image alt text | Every |
| First paragraph hook | The opening paragraph should contain the primary keyword and clearly state what the article covers |
| 规则 | 细节 |
|---|---|
| 搜索引擎会截断更长的标题 |
| 是搜索结果摘要的最优长度 |
| 将最重要的概念放在标题前半部分 |
使用描述性 | 搜索引擎会通过标题理解文章结构 |
| 自然的关键词密度 | 文章中自然提及关键术语3-5次——不要堆砌 |
| 内部链接 | 相关时链接至其他博客文章: |
| 外部权威链接 | 发表观点时链接至文档、论文或官方来源 |
| 图片alt文本 | 每个 |
| 第一段钩子 | 开头段落应包含核心关键词,并明确说明文章内容 |
GEO (Generative Engine Optimization)
生成式引擎优化(GEO)
Goal: Make the article easy for LLMs (ChatGPT, Perplexity, Gemini, etc.) to
understand, quote, and cite.
| Rule | Why |
|---|---|
| Start with a clear thesis statement | LLMs extract the article's purpose from the first paragraph |
| Use structured sections with descriptive headings | LLMs parse heading hierarchy to build understanding |
| Define terms when first introduced | LLMs benefit from explicit definitions: "CI/CD(持续集成/持续部署)" |
| Use lists and tables for structured data | LLMs parse structured content more accurately than prose |
| Include a summary or takeaway at the end | LLMs often quote conclusions and summaries |
| State key points explicitly — don't bury them in metaphors | LLMs prefer direct statements over indirect language |
| Include dates, versions, and specifics | "Astro 6" not just "Astro"; "2026-05" not "recently" — helps LLMs with temporal relevance |
| Use unique, specific phrasing | Generic phrasing ("it's important to note") gets ignored; specific insights get quoted |
目标: 让文章易于大语言模型(ChatGPT、Perplexity、Gemini等)理解、引用和标注。
| 规则 | 原因 |
|---|---|
| 开头包含清晰的论点陈述 | 大语言模型会从第一段提取文章主旨 |
| 使用结构化章节和描述性标题 | 大语言模型会通过标题层级构建理解 |
| 首次提及术语时明确定义 | 大语言模型受益于明确的定义:"CI/CD(持续集成/持续部署)" |
| 使用列表和表格呈现结构化数据 | 大语言模型解析结构化内容比散文更准确 |
| 结尾包含总结或要点提炼 | 大语言模型常引用结论和总结内容 |
| 明确陈述关键点——不要隐藏在隐喻中 | 大语言模型更喜欢直接陈述而非间接表达 |
| 包含日期、版本和具体细节 | 使用“Astro 6”而非“Astro”;使用“2026-05”而非“最近”——帮助大语言模型判断时效性 |
| 使用独特、具体的表述 | 通用表述(“需要注意的是”)会被忽略;具体见解会被引用 |
Preview — Standalone HTML from Live Source
预览 — 基于实时源码生成独立HTML
Every tier generates the preview the same way: read the blog's actual source files
from the remote repo, assemble a self-contained HTML file, open in browser.
This ensures the preview always matches the live blog's current design — if the blog's
CSS or layout changes, the preview reflects it automatically. No stale embedded templates.
所有层级的预览生成方式一致:从远程仓库读取博客的实际源码文件,组装成独立HTML文件,在浏览器中打开。
这确保预览始终与线上博客的当前设计一致——如果博客的CSS或布局发生变化,预览会自动同步更新。不会使用过时的嵌入式模板。
Source Files to Read
需要读取的源码文件
Read these files from the blog repo (via filesystem for Tier 1/2, via API for Tier 3):
| File | Purpose |
|---|---|
| Design tokens, reset, base styles |
| HTML shell, font imports, theme script |
| Article structure, hero, meta, content styles |
| Navigation bar structure + scoped styles |
| Footer structure + scoped styles |
从博客仓库读取以下文件(Tier 1/2通过文件系统,Tier 3通过API):
| 文件 | 用途 |
|---|---|
| 设计令牌、样式重置、基础样式 |
| HTML框架、字体导入、主题脚本 |
| 文章结构、标题区、元数据、内容样式 |
| 导航栏结构 + 作用域样式 |
| 页脚结构 + 作用域样式 |
How to Assemble the Preview
预览组装步骤
-
Read all 5 source files listed above from the repo.
-
Extract the CSS. From eachfile, pull the content between
.astroand<style>. Collect all scoped styles. From</style>, take the full file.global.css -
Extract the HTML structure. From each component/layout, pull the HTML template (the part outsidefrontmatter and
---/<style>blocks).<script> -
Build the preview HTML by combining:
- 's
BaseLayout.astro(meta, font links, theme script)<head> - All CSS (global + scoped from each component) in a single block
<style> - Nav HTML from
Nav.astro - Article HTML following 's structure, with the Markdown content converted to HTML in the
BlogPost.astroslotpost-content - Footer HTML from
Footer.astro
-
Convert the Markdown body to HTML. Use the agent's built-in Markdown understanding — headings →/
<h2>, code blocks →<h3>, images →<pre><code>, links →<img>, etc.<a> -
Save and open (detect platform automatically):bash
PREVIEW_FILE=$(mktemp --suffix=.html) # Write assembled HTML to $PREVIEW_FILE # Open in browser: case "$(uname -s)" in Darwin) open "$PREVIEW_FILE" ;; Linux) xdg-open "$PREVIEW_FILE" ;; MINGW*|MSYS*|CYGWIN*) start "$PREVIEW_FILE" ;; *) echo "Preview saved to: $PREVIEW_FILE" ;; esac
-
读取上述5个源码文件。
-
提取CSS。从每个文件中提取
.astro和<style>之间的内容,收集所有作用域样式。从</style>中提取完整文件内容。global.css -
提取HTML结构。从每个组件/布局中提取HTML模板(即前置元数据和
---/<style>块之外的部分)。<script> -
构建预览HTML,组合以下内容:
- 的
BaseLayout.astro部分(元数据、字体链接、主题脚本)<head> - 所有CSS(全局样式 + 各组件的作用域样式)放入单个块
<style> - 来自的导航HTML
Nav.astro - 遵循结构的文章HTML,将Markdown内容转换为HTML放入
BlogPost.astro插槽post-content - 来自的页脚HTML
Footer.astro
-
将Markdown正文转换为HTML。使用Agent内置的Markdown解析能力——标题转换为/
<h2>、代码块转换为<h3>、图片转换为<pre><code>、链接转换为<img>等。<a> -
保存并打开(自动检测平台):bash
PREVIEW_FILE=$(mktemp --suffix=.html) # 将组装好的HTML写入$PREVIEW_FILE # 在浏览器中打开: case "$(uname -s)" in Darwin) open "$PREVIEW_FILE" ;; Linux) xdg-open "$PREVIEW_FILE" ;; MINGW*|MSYS*|CYGWIN*) start "$PREVIEW_FILE" ;; *) echo "预览已保存至: $PREVIEW_FILE" ;; esac
Scoped Style Handling
作用域样式处理
Astro components use scoped CSS. In the preview HTML, include all scoped
blocks as-is. This blog's component classes (, , , )
are already well-namespaced and won't conflict.
<style>.post.post-hero.nav.footerAstro组件使用作用域CSS。在预览HTML中,直接包含所有作用域块即可。此博客的组件类(、、、)已做好命名空间隔离,不会产生冲突。
<style>.post.post-hero.nav.footerPreview Workflow
预览流程
- Read live source files from repo
- Assemble standalone HTML
- Open in browser
- User reviews visually
- If edits needed → update article → regenerate preview → reopen
- User approves → proceed to publish
After publish, cleanup:
bash
rm -f "$PREVIEW_FILE"- 从仓库读取实时源码文件
- 组装独立HTML
- 在浏览器中打开
- 用户进行视觉审核
- 如需编辑 → 更新文章 → 重新生成预览 → 重新打开
- 用户批准 → 继续发布
发布完成后清理:
bash
rm -f "$PREVIEW_FILE"Workflow — New Article
工作流程 — 新文章
Follow these phases in order.
请按以下阶段依次执行。
Phase 1 — Detect Access & Check Permissions
阶段1 — 检测访问权限
Run tier detection (Tier 1 → 2 → 3). Verify push permission.
If all tiers fail:
- First check if or
GITHUB_TOKENis set → Tier 3GH_TOKEN - Ask the user to provide a GitHub PAT with scope if not set
repo - NEVER ask the user to install git, Node.js, or pnpm — these are optional, not required
Announce active tier and article staging location. Do not proceed until access is confirmed.
执行层级检测(Tier 1 → 2 → 3),验证推送权限。
如果所有层级均失败:
- 首先检查是否设置了或
GITHUB_TOKEN→ 尝试Tier 3GH_TOKEN - 如果未设置,请用户提供拥有权限的GitHub PAT
repo - 绝对不要要求用户安装git、Node.js或pnpm——这些都是可选的,并非必需
告知用户当前使用的层级和文章暂存位置。确认访问权限后再继续。
Phase 2 — Discover the Angle
阶段2 — 确定文章角度
Ask the user:
- What topic or angle?
- Any specific points to cover?
- What language? (default: match user's input)
If the trigger implies the angle, propose a default and confirm.
Do NOT start writing yet.
询问用户:
- 文章主题或角度是什么?
- 有没有需要重点覆盖的内容?
- 使用哪种语言?(默认:匹配用户输入语言)
如果触发词已暗示文章角度,可提出默认方案并确认。
请勿立即开始写作。
Phase 3 — Collect Project Context
阶段3 — 收集项目上下文
From the current working directory (user's project), gather at least 3 sources:
git log --oneline -20- /
README.md— project overview, tech stackpackage.json - /
AGENTS.md— conventions and contextCLAUDE.md - Key source files for the chosen angle
- — what changed recently
git diff --stat
If not a code repo, ask for key points directly. Silently absorb context.
从当前工作目录(用户的项目)中收集至少3种来源的信息:
git log --oneline -20- /
README.md— 项目概述、技术栈package.json - /
AGENTS.md— 项目约定和上下文CLAUDE.md - 与所选角度相关的关键源码文件
- — 近期变更内容
git diff --stat
如果不是代码仓库,请直接询问用户关键信息。静默收集上下文。
Phase 4 — Propose Outline
阶段4 — 提出大纲
Generate: title, section headings (3–7), summary per section, category, filename.
Present to user. Iterate until approved.
生成:标题、章节标题(3-7个)、各章节摘要、分类、文件名。
呈现给用户,迭代至用户批准。
Phase 5 — Read Existing Categories & Schema
阶段5 — 读取现有分类与Schema
Read schema from to get the current frontmatter fields.
src/content.config.tsRead categories by scanning frontmatter from all posts:
Tier 1/2:
bash
grep -rh "^category:" {blog-repo}/src/content/blog/*.md | sort -u
grep -rh "^categorySlug:" {blog-repo}/src/content/blog/*.md | sort -uTier 3: Use "List posts" + "Read file" API calls to scan frontmatter.
Category rules: Prefer existing categories. New allowed — confirm first.
= display label, = URL-safe slug.
categorycategorySlug读取Schema:从获取当前前置元数据字段。
src/content.config.ts读取分类:扫描所有文章的前置元数据:
Tier 1/2:
bash
grep -rh "^category:" {blog-repo}/src/content/blog/*.md | sort -u
grep -rh "^categorySlug:" {blog-repo}/src/content/blog/*.md | sort -uTier 3: 使用“列出文章” + “读取文件”API调用扫描前置元数据。
分类规则: 优先使用现有分类。允许新增分类——但需先确认。
= 显示标签, = URL友好的短标识。
categorycategorySlugPhase 6 — Write the Article
阶段6 — 撰写文章
Write full Markdown with frontmatter that matches the schema read in Phase 5.
Follow all rules in the Writing Standards section above.
Save to staging location (see Article Staging Location table above):
- Tier 1/2: Write to (or
{blog-repo}/src/content/blog/{filename}.md){BLOG_TMP}/... - Tier 3: Write to
./docs/blog-publish/{filename}.md
bash
undefined撰写符合阶段5读取的Schema的完整Markdown文章,包含前置元数据。
严格遵循上述写作规范中的所有规则。
保存至暂存位置(参考文章暂存位置表格):
- Tier 1/2: 保存至(或
{blog-repo}/src/content/blog/{filename}.md){BLOG_TMP}/... - Tier 3: 保存至
./docs/blog-publish/{filename}.md
bash
undefinedTier 3 staging
Tier 3暂存目录创建
mkdir -p ./docs/blog-publish
Rules:
- `date`: today, `YYYY-MM-DD`
- `draft`: ALWAYS `true` at this stage
- Match user's language, adapt tone
- 800+ words, proper Markdown, include code/image placeholders
- Filename: kebab-case, no collisions
- **Cross-platform safe:** standard Markdown only, no HTML, no footnotes
- **SEO optimized:** title < 60 chars, description 120–160 chars, keyword in first paragraph
- **GEO friendly:** clear thesis, structured sections, explicit definitions, summary at end
- **Platform safe:** neutral tone, no superlatives without citation, no sensitive content
Tell the user where the article was saved: "Article saved to `{staging_path}`"mkdir -p ./docs/blog-publish
规则:
- `date`:今日日期,格式为`YYYY-MM-DD`
- `draft`:此阶段必须设为`true`
- 匹配用户使用的语言,调整语气
- 字数不少于800字,使用规范Markdown,包含代码/图片占位符
- 文件名:短横线分隔式(kebab-case),避免重名
- **跨平台安全:** 仅使用标准Markdown,不使用HTML,不使用脚注
- **SEO优化:** 标题长度<60字符,描述长度120-160字符,首段包含关键词
- **GEO友好:** 论点清晰、章节结构化、定义明确、结尾有总结
- **平台安全:** 语气中立,无无依据的最高级词汇,无敏感内容
告知用户文章保存位置:“文章已保存至`{staging_path}`”Phase 7 — Handle Images
阶段7 — 图片处理
- Tier 1/2: Copy to
{blog-repo}/public/blog/{categorySlug}/ - Tier 3: Copy to for local reference, upload via API in Phase 11
./docs/blog-publish/{categorySlug}/ - Path:
 - Every image must have descriptive alt text (SEO + accessibility + cross-platform)
- Tier 1/2: 复制图片至
{blog-repo}/public/blog/{categorySlug}/ - Tier 3: 复制图片至供本地参考,在阶段11通过API上传
./docs/blog-publish/{categorySlug}/ - 图片路径格式:
 - 每张图片必须包含描述性alt文本(SEO + 可访问性 + 跨平台兼容)
Phase 8 — Validate Article Format
阶段8 — 验证文章格式
Before generating the preview, run a format validation check on the article.
This acts as a mini CI gate — all checks must pass before proceeding to preview.
Auto-fix what you can, then report what you fixed. Block on critical errors.
生成预览前,对文章进行格式验证检查。这相当于一个小型CI检查——所有检查必须通过才能进入预览阶段。
自动修复可修复的问题,然后报告修复内容。遇到严重错误时需暂停。
Validation Checklist
验证清单
Run every check below. Fix issues inline if possible, then report results.
Frontmatter structure (block if invalid):
| # | Check | Rule | Auto-fix? |
|---|---|---|---|
| 1 | | File starts with | ✅ Add fences |
| 2 | YAML parseable | Content between fences is valid YAML | ❌ Block |
| 3 | No extra fields | Only fields defined in | ✅ Remove extras |
Frontmatter fields (block if missing required, auto-fix optional):
| # | Check | Rule | Auto-fix? |
|---|---|---|---|
| 4 | | Non-empty string, < 60 chars | ❌ Block |
| 5 | | 120–160 chars, contains primary keyword | ❌ Block |
| 6 | | | ✅ Default to today |
| 7 | | Non-empty string | ❌ Block |
| 8 | | Non-empty, lowercase, hyphenated | ✅ Derive from |
| 9 | | Must be boolean | ✅ Set to |
Cross-platform compatibility (WARN + auto-fix):
| # | Check | Rule | Auto-fix? |
|---|---|---|---|
| 10 | No HTML tags in body | No | ✅ Convert to Markdown |
| 11 | No | Only | ✅ Convert |
| 12 | No footnotes | No | ✅ Convert to inline links |
| 13 | Image alt text | Every | ❌ Warn |
Content quality (WARN — non-blocking but fix if possible):
| # | Check | Rule | Auto-fix? |
|---|---|---|---|
| 14 | Body length | ≥ 400 words (warn if < 800, allow user override) | ❌ Warn |
| 15 | Headings | At least one | ❌ Warn |
| 16 | Unclosed code blocks | Every opening | ✅ Close them |
| 17 | Empty sections | No heading followed by zero content before next heading | ❌ Warn |
| 18 | Image paths | All | ✅ Fix paths |
| 19 | First paragraph | Contains the article's primary topic/keyword | ❌ Warn |
SEO/GEO quality (WARN — non-blocking):
| # | Check | Rule | Auto-fix? |
|---|---|---|---|
| 20 | Descriptive headings | | ❌ Warn |
| 21 | Has summary/conclusion | Article ends with a summary or takeaway section | ❌ Warn |
| 22 | Specifics present | Contains dates, versions, or numbers (not just "recently") | ❌ Warn |
Filename (block if invalid):
| # | Check | Rule | Auto-fix? |
|---|---|---|---|
| 23 | kebab-case | Only | ✅ Convert |
| 24 | No collision | Filename doesn't already exist in | ✅ Append suffix |
| 25 | | Filename ends with | ✅ Append |
Reporting format:
✅ Format validation passed (or)
⚠️ Format validation: {N} issues found and auto-fixed (list them)
🚫 Format validation: {N} critical issues require attention (list them)
📊 SEO/GEO: {N} suggestions (list them)If any BLOCK-level check cannot be auto-fixed, stop and ask the user for input.
Do not proceed to Phase 9 (preview) until all blockers are resolved.
执行以下所有检查。如有可能,直接修复问题,然后报告结果。
前置元数据结构(不修复则暂停):
| 序号 | 检查项 | 规则 | 是否自动修复 |
|---|---|---|---|
| 1 | | 文件第一行是 | ✅ 添加分隔符 |
| 2 | YAML可解析 | 分隔符之间的内容是有效的YAML | ❌ 暂停 |
| 3 | 无额外字段 | 仅包含 | ✅ 删除额外字段 |
前置元数据字段(缺少必填项则暂停,可选字段自动修复):
| 序号 | 检查项 | 规则 | 是否自动修复 |
|---|---|---|---|
| 4 | | 非空字符串,长度<60字符 | ❌ 暂停 |
| 5 | | 长度120-160字符,包含核心关键词 | ❌ 暂停 |
| 6 | | 格式为 | ✅ 默认设为今日 |
| 7 | | 非空字符串 | ❌ 暂停 |
| 8 | | 非空、小写、短横线分隔 | ✅ 从 |
| 9 | | 此阶段必须为布尔值 | ✅ 设置为 |
跨平台兼容性(警告 + 自动修复):
| 序号 | 检查项 | 规则 | 是否自动修复 |
|---|---|---|---|
| 10 | 正文无HTML标签 | 正文Markdown中无 | ✅ 转换为Markdown格式 |
| 11 | 正文无 | 仅允许使用 | ✅ 将 |
| 12 | 无脚注 | 无 | ✅ 转换为内联链接 |
| 13 | 图片alt文本 | 每个 | ❌ 警告 |
内容质量(警告——不暂停但尽可能修复):
| 序号 | 检查项 | 规则 | 是否自动修复 |
|---|---|---|---|
| 14 | 正文长度 | ≥400字(<800字时警告,允许用户覆盖) | ❌ 警告 |
| 15 | 标题数量 | 正文至少包含一个 | ❌ 警告 |
| 16 | 代码块闭合 | 每个开头的 | ✅ 补充闭合 |
| 17 | 无空章节 | 标题后到下一个标题前无空内容 | ❌ 警告 |
| 18 | 图片路径 | 所有 | ✅ 修复路径 |
| 19 | 首段内容 | 包含文章核心主题/关键词 | ❌ 警告 |
SEO/GEO质量(警告——不暂停):
| 序号 | 检查项 | 规则 | 是否自动修复 |
|---|---|---|---|
| 20 | 标题描述性 | | ❌ 警告 |
| 21 | 有总结/结论 | 文章结尾包含总结或要点提炼章节 | ❌ 警告 |
| 22 | 包含具体细节 | 包含日期、版本或数字(而非仅“最近”) | ❌ 警告 |
文件名(不修复则暂停):
| 序号 | 检查项 | 规则 | 是否自动修复 |
|---|---|---|---|
| 23 | 短横线分隔式 | 仅包含 | ✅ 转换格式 |
| 24 | 无重名 | 文件名在 | ✅ 添加后缀 |
| 25 | | 文件名以 | ✅ 添加扩展名 |
报告格式:
✅ 格式验证通过(或)
⚠️ 格式验证:发现{N}个问题并已自动修复(列出问题)
🚫 格式验证:{N}个严重问题需要处理(列出问题)
📊 SEO/GEO:{N}条建议(列出建议)如果任何必须暂停的检查项无法自动修复,请停止操作并询问用户。
所有阻塞问题解决前,请勿进入阶段9(预览)。
Phase 9 — Generate Preview from Live Source
阶段9 — 基于实时源码生成预览
Read the 5 source files listed in the Preview section. Assemble standalone HTML.
Convert Markdown body to HTML. Save and open in browser.
Wait for user feedback. If edits → Phase 6 → Phase 8 (re-validate) → Phase 9.
读取预览部分列出的5个源码文件,组装独立HTML。将Markdown正文转换为HTML,保存并在浏览器中打开。
等待用户反馈。如需编辑 → 阶段6 → 阶段8(重新验证) → 阶段9。
Phase 10 — User Final Approval
阶段10 — 用户最终批准
Ask: "Ready to publish?" Wait for explicit confirmation.
Do NOT proceed until user says yes.
询问:“是否准备发布?”等待用户明确确认。
未得到用户确认前请勿继续。
Phase 11 — Publish
阶段11 — 发布
-
Change→
draft: truedraft: false -
Tier 1:bash
cd {blog-repo} git add src/content/blog/{filename}.md public/blog/{categorySlug}/ 2>/dev/null || true git commit -m "post: publish {title}" git push origin main -
Tier 2:bash
cd "$BLOG_TMP" git add src/content/blog/{filename}.md public/blog/{categorySlug}/ 2>/dev/null || true git commit -m "post: publish {title}" git push origin main rm -rf "$BLOG_TMP" -
Tier 3: Use "Create file" API to pushto remote. Also upload any images via "Upload image" API call.
./docs/blog-publish/{filename}.md -
Verify deployment (optional but recommended):bash
curl -sf "https://agent-blog-kelegele.vercel.app/blog/{slug}" -o /dev/null -w "%{http_code}" # 200 = deployed successfully -
Confirm: "Pushed to. Vercel will auto-deploy. Live URL: https://agent-blog-kelegele.vercel.app/blog/{slug}"
main -
Cleanup:Tier 3 note:
rm -f "$PREVIEW_FILE"is kept as local backup. Tell the user: "Local copy at./docs/blog-publish/{filename}.md— you can delete it or keep it."./docs/blog-publish/{filename}.md
Commit message:
post: publish {title}-
将修改为
draft: truedraft: false -
Tier 1:bash
cd {blog-repo} git add src/content/blog/{filename}.md public/blog/{categorySlug}/ 2>/dev/null || true git commit -m "post: publish {title}" git push origin main -
Tier 2:bash
cd "$BLOG_TMP" git add src/content/blog/{filename}.md public/blog/{categorySlug}/ 2>/dev/null || true git commit -m "post: publish {title}" git push origin main rm -rf "$BLOG_TMP" -
Tier 3: 使用“创建文件”API将推送至远程仓库。同时使用“上传图片”API调用上传所有图片。
./docs/blog-publish/{filename}.md -
验证部署(可选但推荐):bash
curl -sf "https://agent-blog-kelegele.vercel.app/blog/{slug}" -o /dev/null -w "%{http_code}" # 200 = 部署成功 -
确认信息:“已推送至分支。Vercel将自动部署。线上地址:https://agent-blog-kelegele.vercel.app/blog/{slug}”
main -
清理操作:Tier 3备注:
rm -f "$PREVIEW_FILE"会保留作为本地备份。告知用户:“本地副本位于./docs/blog-publish/{filename}.md——您可以选择删除或保留。”./docs/blog-publish/{filename}.md
提交信息:
post: publish {title}Workflow — Edit Existing Article
工作流程 — 编辑已有文章
When the user wants to edit an existing post (trigger: "edit article", "修改文章",
"update blog post", etc.):
当用户想要编辑已有文章时(触发词:"edit article"、"修改文章"、"update blog post"等):
E-Phase 1 — Find the Article
E-阶段1 — 查找文章
List existing posts and ask which one to edit. Or accept a slug/filename from the user.
列出已有文章并询问用户要编辑哪一篇。或接受用户提供的短标识/文件名。
E-Phase 2 — Read Current Content
E-阶段2 — 读取当前内容
Read the article file from the repo (filesystem or API).
从仓库读取文章文件(文件系统或API)。
E-Phase 3 — Apply Edits
E-阶段3 — 应用编辑
Ask the user what to change. Apply edits to the Markdown content.
Do NOT change status — keep whatever it currently is.
draftFor Tier 3, save the edited version to .
./docs/blog-publish/{filename}.md询问用户需要修改的内容,将编辑应用到Markdown内容中。
不要修改状态——保持当前状态。
draft对于Tier 3,将编辑后的版本保存至。
./docs/blog-publish/{filename}.mdE-Phase 4 — Re-validate (Phase 8 from new article workflow)
E-阶段4 — 重新验证(参考新文章工作流程的阶段8)
Run the same validation checklist. Fix issues, report results.
执行相同的验证清单,修复问题并报告结果。
E-Phase 5 — Preview
E-阶段5 — 预览
Generate preview from live source. Open in browser. Iterate until approved.
基于实时源码生成预览,在浏览器中打开。迭代至用户批准。
E-Phase 6 — Push
E-阶段6 — 推送
Commit and push with message:
post: update {title}提交并推送,信息为:
post: update {title}Error Handling
错误处理
| Scenario | Action |
|---|---|
| All tiers fail | Ask for |
| Permission denied | Check token has |
| Filename collision | Append distinguishing word |
| User rejects outline | Iterate, do not write |
| Validation blockers | Fix auto-fixable issues, ask user for the rest |
| Edits after preview | Phase 6 → Phase 8 (re-validate) → Phase 9 |
| Push fails (conflict) | Pull/rebase (Tier 1/2) or get latest SHA (Tier 3) |
| Source file read fails | Preview may be degraded — warn user and proceed |
| API rate limit | Wait/retry, or help set up Tier 1/2 |
| User lacks technical background | Use Tier 3, explain in simple terms, never require installs |
| Deployment verification fails | Non-blocking — Vercel may take 30–60s to deploy |
| Inform user, ask if they want to overwrite or use a different name |
| 场景 | 操作 |
|---|---|
| 所有层级均失败 | 请求用户提供 |
| 权限被拒绝 | 检查令牌是否拥有 |
| 文件名重名 | 添加区分性词汇 |
| 用户拒绝大纲 | 迭代修改,不要开始写作 |
| 验证阻塞问题 | 自动修复可修复的问题,其余询问用户 |
| 预览后需要编辑 | 阶段6 → 阶段8(重新验证) → 阶段9 |
| 推送失败(冲突) | 拉取/变基(Tier 1/2)或获取最新SHA(Tier 3) |
| 源码文件读取失败 | 预览效果可能受损——警告用户并继续 |
| API速率限制 | 等待/重试,或帮助用户设置Tier 1/2 |
| 用户缺乏技术背景 | 使用Tier 3,用简单语言解释,绝不要求安装工具 |
| 部署验证失败 | 非阻塞——Vercel可能需要30-60秒完成部署 |
| 告知用户,询问是否要覆盖或使用其他名称 |