blog-publish

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

blog-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
+
jq
+ 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.
Turn any project or idea into a polished blog post and publish it to
kelegele/agent-blog
. Also supports editing existing posts.
⚠️ 请勿假设需要Node.js、pnpm、git或任何构建工具。 此Skill包含三个访问层级。最低层级(Tier 3)仅需
curl
+
jq
+ GitHub令牌
即可运行。无需git、Node.js、pnpm, 也无需本地克隆仓库。请始终检查可用环境,使用能正常运行的最高层级。绝对不要告知用户必须安装git/Node.js/pnpm——这些并非必需。
可将任意项目或想法转化为精美的博客文章,并发布至
kelegele/agent-blog
仓库。同时支持编辑已有文章。

Blog Repo Reference

博客仓库参考信息

ItemValue
Remote
https://github.com/kelegele/agent-blog
Branch
main
Posts dir
src/content/blog/
Images dir
public/blog/{categorySlug}/
Schema
src/content.config.ts
(source of truth — read it dynamically)
Auto-deployVercel (push to
main
triggers deploy)
远程仓库地址
https://github.com/kelegele/agent-blog
分支
main
文章目录
src/content/blog/
图片目录
public/blog/{categorySlug}/
元数据Schema
src/content.config.ts
(唯一可信源——需动态读取)
自动部署Vercel(推送至
main
分支触发部署)

Article Staging Location

文章暂存位置

Generated articles are saved to a local file for review before publishing. The staging location depends on the active tier:
TierArticle staging path
1 — Local clone
{blog-repo}/src/content/blog/{filename}.md
2 — Sparse clone
{BLOG_TMP}/src/content/blog/{filename}.md
3 — REST API
./docs/blog-publish/{filename}.md
(current project directory)
Why
./docs/blog-publish/
for Tier 3?
When there's no blog repo clone, the article needs a local home for editing and preview. The
docs/
directory is a conventional place for documentation in any project. The subdirectory
blog-publish
keeps it isolated from the project's own docs. Create it if it doesn't exist:
bash
mkdir -p ./docs/blog-publish
After 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 — 本地克隆仓库
{blog-repo}/src/content/blog/{filename}.md
2 — 稀疏克隆仓库
{BLOG_TMP}/src/content/blog/{filename}.md
3 — REST API
./docs/blog-publish/{filename}.md
(当前项目目录)
为什么Tier 3使用
./docs/blog-publish/
当没有克隆博客仓库时,文章需要一个本地位置用于编辑和预览。
docs/
目录是各类项目中存放文档的常规位置。
blog-publish
子目录可将文章与项目自身文档隔离开。如果该目录不存在,请创建它:
bash
mkdir -p ./docs/blog-publish
文章发布后(通过API推送至远程仓库),此本地副本会保留作为备份。请告知用户可选择删除或保留该文件。

Schema — Read Dynamically, Never Hardcode

Schema — 动态读取,切勿硬编码

The blog's frontmatter schema is defined in
src/content.config.ts
. Read this file at runtime to get the current schema — do not rely on the snapshot below.
File location:
src/content.config.ts
Known schema as of this writing (may change — always verify):
FieldTypeRequiredDefault
title
string
description
string
date
Date
(coerced)
category
string
categorySlug
string
optional
draft
boolean
optional
false
If the schema changes in the future (e.g. a
tags
field is added), the agent will pick it up automatically by reading this file.

博客的前置元数据Schema定义在
src/content.config.ts
中。请在运行时读取此文件以获取当前Schema——不要依赖下方的快照内容。
文件位置:
src/content.config.ts
撰写本文时已知的Schema(可能会变更——请始终验证):
字段类型是否必填默认值
title
string
description
string
date
Date
(可自动转换)
category
string
categorySlug
string
可选
draft
boolean
可选
false
如果未来Schema发生变更(例如新增
tags
字段),Agent会通过读取此文件自动获取更新。

Access 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:
  1. AGENT_BLOG_PATH
    env var
  2. ~/Projects/agent-blog
  3. find ~ -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>&1
Read/write via filesystem + git.
检测顺序:
  1. 环境变量
    AGENT_BLOG_PATH
  2. ~/Projects/agent-blog
    目录
  3. 执行命令:
    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
git
is available.
bash
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
Cleanup:
rm -rf "$BLOG_TMP"
after publish.
无本地克隆仓库,但
git
可用。
bash
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
curl
+
jq
(pre-installed on macOS/Linux) and a GitHub PAT.
Required:
GITHUB_TOKEN
or
GH_TOKEN
env var — a GitHub PAT with
repo
scope. Create at:
https://github.com/settings/tokens/new?scopes=repo&description=blog-publish-skill
Permission 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 -d
Create 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或任何本地工具。 仅需
curl
+
jq
(macOS/Linux默认预装)和GitHub个人访问令牌(PAT)。
必需条件: 环境变量
GITHUB_TOKEN
GH_TOKEN
——拥有
repo
权限的GitHub PAT。 创建地址:
https://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

层级总结

TierRequiresPreviewReadWriteArticle staging
1 — Local clonegit + local pathfilesystemgit push
{blog-repo}/src/content/blog/
2 — Sparse clonegitfilesystemgit push
{BLOG_TMP}/src/content/blog/
3 — REST API
GITHUB_TOKEN
+ curl + jq
APIAPI
./docs/blog-publish/
Always try Tier 1 → 2 → 3. Announce active tier at startup.

层级所需条件预览功能读取方式写入方式文章暂存位置
1 — 本地克隆仓库git + 本地路径文件系统git push
{blog-repo}/src/content/blog/
2 — 稀疏克隆仓库git文件系统git push
{BLOG_TMP}/src/content/blog/
3 — REST API
GITHUB_TOKEN
+ curl + jq
APIAPI
./docs/blog-publish/
请始终尝试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.
RuleWhy
Use only standard Markdown — no HTML tags, no custom shortcodes, no platform-specific syntaxWeChat/小红书 editors strip HTML; plain Markdown renders consistently
Avoid
#
(h1) in body — use
##
and
###
only
title
in frontmatter is the h1; multiple h1s confuse SEO and readers
Avoid footnotes (
[^1]
) — use inline links instead
Most platforms don't render footnotes
Avoid tables unless essentialMany mobile platforms break table layout; prefer lists
Avoid nested lists > 2 levels deepCopy-paste often flattens nesting
Don't rely on images for critical informationWeChat/小红书 may compress or reorder images
Every image must have meaningful
alt
text
Accessibility + survives text-only copy + helps SEO
Don't use emoji in headings or frontmatterSome platforms strip emoji in titles
Keep paragraphs short (3–5 sentences max)Mobile readability on WeChat/小红书
目标: 文章复制粘贴到任意平台编辑器时,格式损失最小。
规则原因
仅使用标准Markdown——不使用HTML标签、自定义短代码或平台专属语法微信/小红书编辑器会剥离HTML;纯Markdown在各平台渲染效果一致
正文避免使用
#
(一级标题)——仅使用
##
###
前置元数据中的
title
已作为一级标题;多个一级标题会混淆SEO和读者
避免脚注(
[^1]
)——改用内联链接
大多数平台不支持渲染脚注
非必要不使用表格——优先使用列表许多移动端平台会破坏表格布局;列表可读性更强
避免嵌套层级超过2级的列表复制粘贴时常会扁平化嵌套结构
不要依赖图片传递关键信息微信/小红书可能会压缩或重排图片
每张图片必须包含有意义的
alt
文本
提升可访问性 + 支持纯文本复制 + 利于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)

RuleDetails
title
under 60 chars
Search engines truncate longer titles
description
120–160 chars
Optimal length for SERP snippet
Front-load keywords in
title
Put the most important concept in the first half
Use descriptive
##
headings
Search engines use headings to understand structure
Natural keyword densityMention key terms naturally 3–5 times across the article — don't stuff
Internal linksLink to other blog posts when relevant:
[相关文章](/blog/{slug})
External authority linksLink to docs, papers, or official sources when making claims
Image alt textEvery
![]()
must have descriptive alt text containing relevant keywords
First paragraph hookThe opening paragraph should contain the primary keyword and clearly state what the article covers
规则细节
title
长度不超过60字符
搜索引擎会截断更长的标题
description
长度为120-160字符
是搜索结果摘要的最优长度
title
前置关键词
将最重要的概念放在标题前半部分
使用描述性
##
标题
搜索引擎会通过标题理解文章结构
自然的关键词密度文章中自然提及关键术语3-5次——不要堆砌
内部链接相关时链接至其他博客文章:
[相关文章](/blog/{slug})
外部权威链接发表观点时链接至文档、论文或官方来源
图片alt文本每个
![]()
必须包含带有相关关键词的描述性alt文本
第一段钩子开头段落应包含核心关键词,并明确说明文章内容

GEO (Generative Engine Optimization)

生成式引擎优化(GEO)

Goal: Make the article easy for LLMs (ChatGPT, Perplexity, Gemini, etc.) to understand, quote, and cite.
RuleWhy
Start with a clear thesis statementLLMs extract the article's purpose from the first paragraph
Use structured sections with descriptive headingsLLMs parse heading hierarchy to build understanding
Define terms when first introducedLLMs benefit from explicit definitions: "CI/CD(持续集成/持续部署)"
Use lists and tables for structured dataLLMs parse structured content more accurately than prose
Include a summary or takeaway at the endLLMs often quote conclusions and summaries
State key points explicitly — don't bury them in metaphorsLLMs 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 phrasingGeneric 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):
FilePurpose
src/styles/global.css
Design tokens, reset, base styles
src/layouts/BaseLayout.astro
HTML shell, font imports, theme script
src/layouts/BlogPost.astro
Article structure, hero, meta, content styles
src/components/Nav.astro
Navigation bar structure + scoped styles
src/components/Footer.astro
Footer structure + scoped styles
从博客仓库读取以下文件(Tier 1/2通过文件系统,Tier 3通过API):
文件用途
src/styles/global.css
设计令牌、样式重置、基础样式
src/layouts/BaseLayout.astro
HTML框架、字体导入、主题脚本
src/layouts/BlogPost.astro
文章结构、标题区、元数据、内容样式
src/components/Nav.astro
导航栏结构 + 作用域样式
src/components/Footer.astro
页脚结构 + 作用域样式

How to Assemble the Preview

预览组装步骤

  1. Read all 5 source files listed above from the repo.
  2. Extract the CSS. From each
    .astro
    file, pull the content between
    <style>
    and
    </style>
    . Collect all scoped styles. From
    global.css
    , take the full file.
  3. Extract the HTML structure. From each component/layout, pull the HTML template (the part outside
    ---
    frontmatter and
    <style>
    /
    <script>
    blocks).
  4. Build the preview HTML by combining:
    • BaseLayout.astro
      's
      <head>
      (meta, font links, theme script)
    • All CSS (global + scoped from each component) in a single
      <style>
      block
    • Nav HTML from
      Nav.astro
    • Article HTML following
      BlogPost.astro
      's structure, with the Markdown content converted to HTML in the
      post-content
      slot
    • Footer HTML from
      Footer.astro
  5. Convert the Markdown body to HTML. Use the agent's built-in Markdown understanding — headings →
    <h2>
    /
    <h3>
    , code blocks →
    <pre><code>
    , images →
    <img>
    , links →
    <a>
    , etc.
  6. 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
  1. 读取上述5个源码文件
  2. 提取CSS。从每个
    .astro
    文件中提取
    <style>
    </style>
    之间的内容,收集所有作用域样式。从
    global.css
    中提取完整文件内容。
  3. 提取HTML结构。从每个组件/布局中提取HTML模板(即
    ---
    前置元数据和
    <style>
    /
    <script>
    块之外的部分)。
  4. 构建预览HTML,组合以下内容:
    • BaseLayout.astro
      <head>
      部分(元数据、字体链接、主题脚本)
    • 所有CSS(全局样式 + 各组件的作用域样式)放入单个
      <style>
    • 来自
      Nav.astro
      的导航HTML
    • 遵循
      BlogPost.astro
      结构的文章HTML,将Markdown内容转换为HTML放入
      post-content
      插槽
    • 来自
      Footer.astro
      的页脚HTML
  5. 将Markdown正文转换为HTML。使用Agent内置的Markdown解析能力——标题转换为
    <h2>
    /
    <h3>
    、代码块转换为
    <pre><code>
    、图片转换为
    <img>
    、链接转换为
    <a>
    等。
  6. 保存并打开(自动检测平台):
    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
<style>
blocks as-is. This blog's component classes (
.post
,
.post-hero
,
.nav
,
.footer
) are already well-namespaced and won't conflict.
Astro组件使用作用域CSS。在预览HTML中,直接包含所有作用域
<style>
块即可。此博客的组件类(
.post
.post-hero
.nav
.footer
)已做好命名空间隔离,不会产生冲突。

Preview Workflow

预览流程

  1. Read live source files from repo
  2. Assemble standalone HTML
  3. Open in browser
  4. User reviews visually
  5. If edits needed → update article → regenerate preview → reopen
  6. User approves → proceed to publish
After publish, cleanup:
bash
rm -f "$PREVIEW_FILE"

  1. 从仓库读取实时源码文件
  2. 组装独立HTML
  3. 在浏览器中打开
  4. 用户进行视觉审核
  5. 如需编辑 → 更新文章 → 重新生成预览 → 重新打开
  6. 用户批准 → 继续发布
发布完成后清理:
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
    GITHUB_TOKEN
    or
    GH_TOKEN
    is set → Tier 3
  • Ask the user to provide a GitHub PAT with
    repo
    scope if not set
  • 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
    GH_TOKEN
    → 尝试Tier 3
  • 如果未设置,请用户提供拥有
    repo
    权限的GitHub PAT
  • 绝对不要要求用户安装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
    /
    package.json
    — project overview, tech stack
  • AGENTS.md
    /
    CLAUDE.md
    — conventions and context
  • Key source files for the chosen angle
  • git diff --stat
    — what changed recently
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
src/content.config.ts
to get the current frontmatter fields.
Read 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 -u
Tier 3: Use "List posts" + "Read file" API calls to scan frontmatter.
Category rules: Prefer existing categories. New allowed — confirm first.
category
= display label,
categorySlug
= URL-safe slug.
读取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 -u
Tier 3: 使用“列出文章” + “读取文件”API调用扫描前置元数据。
分类规则: 优先使用现有分类。允许新增分类——但需先确认。
category
= 显示标签,
categorySlug
= URL友好的短标识。

Phase 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
    {blog-repo}/src/content/blog/{filename}.md
    (or
    {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
undefined

Tier 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
    ./docs/blog-publish/{categorySlug}/
    for local reference, upload via API in Phase 11
  • Path:
    ![Descriptive alt text](/blog/{categorySlug}/image-name.webp)
  • Every image must have descriptive alt text (SEO + accessibility + cross-platform)
  • Tier 1/2: 复制图片至
    {blog-repo}/public/blog/{categorySlug}/
  • Tier 3: 复制图片至
    ./docs/blog-publish/{categorySlug}/
    供本地参考,在阶段11通过API上传
  • 图片路径格式:
    ![描述性alt文本](/blog/{categorySlug}/image-name.webp)
  • 每张图片必须包含描述性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):
#CheckRuleAuto-fix?
1
---
fences
File starts with
---
on line 1, closing
---
present
✅ Add fences
2YAML parseableContent between fences is valid YAML❌ Block
3No extra fieldsOnly fields defined in
src/content.config.ts
schema
✅ Remove extras
Frontmatter fields (block if missing required, auto-fix optional):
#CheckRuleAuto-fix?
4
title
present
Non-empty string, < 60 chars❌ Block
5
description
present
120–160 chars, contains primary keyword❌ Block
6
date
present & valid
YYYY-MM-DD
format, must be a real date
✅ Default to today
7
category
present
Non-empty string❌ Block
8
categorySlug
present
Non-empty, lowercase, hyphenated✅ Derive from
category
9
draft
is
true
Must be boolean
true
at this stage
✅ Set to
true
Cross-platform compatibility (WARN + auto-fix):
#CheckRuleAuto-fix?
10No HTML tags in bodyNo
<div>
,
<span>
,
<br>
etc. in Markdown body
✅ Convert to Markdown
11No
#
(h1) in body
Only
##
and
###
headings allowed
✅ Convert
#
##
12No footnotesNo
[^n]
footnote references
✅ Convert to inline links
13Image alt textEvery
![]()
has non-empty alt text
❌ Warn
Content quality (WARN — non-blocking but fix if possible):
#CheckRuleAuto-fix?
14Body length≥ 400 words (warn if < 800, allow user override)❌ Warn
15HeadingsAt least one
##
heading in body
❌ Warn
16Unclosed code blocksEvery opening
has a closing
✅ Close them
17Empty sectionsNo heading followed by zero content before next heading❌ Warn
18Image pathsAll
![]()
paths start with
/blog/
or are external URLs
✅ Fix paths
19First paragraphContains the article's primary topic/keyword❌ Warn
SEO/GEO quality (WARN — non-blocking):
#CheckRuleAuto-fix?
20Descriptive headings
##
headings describe content, not generic ("更多内容")
❌ Warn
21Has summary/conclusionArticle ends with a summary or takeaway section❌ Warn
22Specifics presentContains dates, versions, or numbers (not just "recently")❌ Warn
Filename (block if invalid):
#CheckRuleAuto-fix?
23kebab-caseOnly
a-z0-9-
, no spaces, underscores, or uppercase
✅ Convert
24No collisionFilename doesn't already exist in
src/content/blog/
✅ Append suffix
25
.md
extension
Filename ends with
.md
✅ 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
---
分隔符
文件第一行是
---
,且存在闭合的
---
✅ 添加分隔符
2YAML可解析分隔符之间的内容是有效的YAML❌ 暂停
3无额外字段仅包含
src/content.config.ts
Schema中定义的字段
✅ 删除额外字段
前置元数据字段(缺少必填项则暂停,可选字段自动修复):
序号检查项规则是否自动修复
4
title
存在
非空字符串,长度<60字符❌ 暂停
5
description
存在
长度120-160字符,包含核心关键词❌ 暂停
6
date
存在且有效
格式为
YYYY-MM-DD
,是真实日期
✅ 默认设为今日
7
category
存在
非空字符串❌ 暂停
8
categorySlug
存在
非空、小写、短横线分隔✅ 从
category
派生
9
draft
设为
true
此阶段必须为布尔值
true
✅ 设置为
true
跨平台兼容性(警告 + 自动修复):
序号检查项规则是否自动修复
10正文无HTML标签正文Markdown中无
<div>
<span>
<br>
等标签
✅ 转换为Markdown格式
11正文无
#
(一级标题)
仅允许使用
##
###
标题
✅ 将
#
转换为
##
12无脚注
[^n]
脚注引用
✅ 转换为内联链接
13图片alt文本每个
![]()
都有非空alt文本
❌ 警告
内容质量(警告——不暂停但尽可能修复):
序号检查项规则是否自动修复
14正文长度≥400字(<800字时警告,允许用户覆盖)❌ 警告
15标题数量正文至少包含一个
##
标题
❌ 警告
16代码块闭合每个开头的
都有对应的闭合
✅ 补充闭合
17无空章节标题后到下一个标题前无空内容❌ 警告
18图片路径所有
![]()
路径以
/blog/
开头或为外部URL
✅ 修复路径
19首段内容包含文章核心主题/关键词❌ 警告
SEO/GEO质量(警告——不暂停):
序号检查项规则是否自动修复
20标题描述性
##
标题描述内容,而非通用表述(如“更多内容”)
❌ 警告
21有总结/结论文章结尾包含总结或要点提炼章节❌ 警告
22包含具体细节包含日期、版本或数字(而非仅“最近”)❌ 警告
文件名(不修复则暂停):
序号检查项规则是否自动修复
23短横线分隔式仅包含
a-z0-9-
,无空格、下划线或大写字母
✅ 转换格式
24无重名文件名在
src/content/blog/
中不存在
✅ 添加后缀
25
.md
扩展名
文件名以
.md
结尾
✅ 添加扩展名
报告格式:
✅ 格式验证通过(或)
⚠️ 格式验证:发现{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 — 发布

  1. Change
    draft: true
    draft: false
  2. 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
  3. 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"
  4. Tier 3: Use "Create file" API to push
    ./docs/blog-publish/{filename}.md
    to remote. Also upload any images via "Upload image" API call.
  5. 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
  6. Confirm: "Pushed to
    main
    . Vercel will auto-deploy. Live URL: https://agent-blog-kelegele.vercel.app/blog/{slug}"
  7. Cleanup:
    rm -f "$PREVIEW_FILE"
    Tier 3 note:
    ./docs/blog-publish/{filename}.md
    is kept as local backup. Tell the user: "Local copy at
    ./docs/blog-publish/{filename}.md
    — you can delete it or keep it."
Commit message:
post: publish {title}

  1. draft: true
    修改为
    draft: false
  2. 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
  3. 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"
  4. Tier 3: 使用“创建文件”API将
    ./docs/blog-publish/{filename}.md
    推送至远程仓库。同时使用“上传图片”API调用上传所有图片。
  5. 验证部署(可选但推荐):
    bash
    curl -sf "https://agent-blog-kelegele.vercel.app/blog/{slug}" -o /dev/null -w "%{http_code}"
    # 200 = 部署成功
  6. 确认信息:“已推送至
    main
    分支。Vercel将自动部署。线上地址:https://agent-blog-kelegele.vercel.app/blog/{slug}”
  7. 清理操作:
    rm -f "$PREVIEW_FILE"
    Tier 3备注:
    ./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
draft
status — keep whatever it currently is.
For Tier 3, save the edited version to
./docs/blog-publish/{filename}.md
.
询问用户需要修改的内容,将编辑应用到Markdown内容中。 不要修改
draft
状态——保持当前状态。
对于Tier 3,将编辑后的版本保存至
./docs/blog-publish/{filename}.md

E-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

错误处理

ScenarioAction
All tiers failAsk for
GITHUB_TOKEN
— do NOT ask for git/Node/pnpm install
Permission deniedCheck token has
repo
scope and push access
Filename collisionAppend distinguishing word
User rejects outlineIterate, do not write
Validation blockersFix auto-fixable issues, ask user for the rest
Edits after previewPhase 6 → Phase 8 (re-validate) → Phase 9
Push fails (conflict)Pull/rebase (Tier 1/2) or get latest SHA (Tier 3)
Source file read failsPreview may be degraded — warn user and proceed
API rate limitWait/retry, or help set up Tier 1/2
User lacks technical backgroundUse Tier 3, explain in simple terms, never require installs
Deployment verification failsNon-blocking — Vercel may take 30–60s to deploy
./docs/blog-publish/
already has files
Inform user, ask if they want to overwrite or use a different name
场景操作
所有层级均失败请求用户提供
GITHUB_TOKEN
——绝对不要要求用户安装git/Node.js/pnpm
权限被拒绝检查令牌是否拥有
repo
权限和推送权限
文件名重名添加区分性词汇
用户拒绝大纲迭代修改,不要开始写作
验证阻塞问题自动修复可修复的问题,其余询问用户
预览后需要编辑阶段6 → 阶段8(重新验证) → 阶段9
推送失败(冲突)拉取/变基(Tier 1/2)或获取最新SHA(Tier 3)
源码文件读取失败预览效果可能受损——警告用户并继续
API速率限制等待/重试,或帮助用户设置Tier 1/2
用户缺乏技术背景使用Tier 3,用简单语言解释,绝不要求安装工具
部署验证失败非阻塞——Vercel可能需要30-60秒完成部署
./docs/blog-publish/
已有文件
告知用户,询问是否要覆盖或使用其他名称