为什么用 Halo CLI,而不是直接调 API
这个博客跑在 Halo 上,文章由 AI(老八)代写代发。最开始我让 AI 直接调用 Halo 的 REST API 写文章,结果踩了一连串坑。后来换成 Halo 官方 2026 年 3 月推出的命令行工具 Halo CLI,定位就写着 "Halo for Agents"——专门给 AI 用的。这篇记录踩过的坑和最终用法。
最初直接调 API 的问题
- 正文空白:Halo 文章的内容快照分
raw(原文)和content(渲染后的 HTML)。只传 Markdown 原文、不提供渲染 HTML,前台就是一片空白。 - 快照被写脏:手滑去构造
baseSnapshot、headSnapshot、releaseSnapshot这些本该后端管理的字段,正文会变成<p>[{...JSON...}]一类的脏数据,文章直接报废。 - 标签/令牌粘连:明文令牌文件在反复修改时新旧内容粘在一起,排查很费劲。
- 草稿改发布时间报 500:这个版本里对草稿直接改
publishTime会触发后端错误。
Halo CLI 怎么解决
- 登录后凭证由 CLI 统一管理(存在自己的配置和系统 keyring),不用维护明文令牌文件。
- 发文走官方封装,快照字段全部留给后端,不再手写,脏数据问题基本消失。
- 支持
--json输出和多 profile,天生适合脚本和自动化。 - 文章、页面、分类、标签、插件、主题、附件、备份、评论、通知都能在命令行管理。
安装
要求 Node.js ≥ 22:
npm install -g @halo-dev/cli
安装后命令叫 halo。国内网络用镜像更快:
npm install -g @halo-dev/cli --registry=https://registry.npmmirror.com
登录
halo auth login --profile prod --url https://ieagoo.com --auth-type bearer --token 你的令牌
令牌在 Halo 后台用对应账号生成(PAT)。之后所有命令自动用这个 profile,不用重复登录。
常用命令
halo auth current # 查看当前连接
halo post list --json # 列出文章
halo post get <name> --json # 查看单篇(name 是 UUID,不是 slug)
halo post create --title "标题" --content "$(cat body.html)" \
--raw-type html --visible PUBLIC --publish true
halo post update <name> --content "$(cat body.html)" --raw-type html --publish true
halo post delete <name> --force
halo post category list # 分类
halo post tag list # 标签
关于格式:Markdown 还是原生
Halo 的默认富文本编辑器是 Tiptap,内部存的是专有 JSON 结构,不适合代码直接手写。Halo CLI 只封装了 markdown 和 html 两种格式。实测下来:
- 用
--raw-type html发布,前台标题、列表、表格、引用、代码块全部渲染正常; - 关键是——后台用 默认富文本编辑器 也能直接打开并编辑这些 HTML 文章。
所以最终方案定为:AI 一律用 HTML 原生方式发文,前台正常、人工在后台也能直接改,不再依赖 Markdown。
几条铁律
- 脚本里一律加
--json,多个站点用--profile区分。 - 绝不手写
baseSnapshot/headSnapshot/releaseSnapshot/owner。 - 内容用文件 +
"$(cat file)"传入,避免长内容在 shell 里被引号和换行搞坏。 - 破坏性操作(delete、覆盖式 import)才加
--force,动手前先读现状。 - 先发布、再改发布时间,不要在草稿状态直接改
publishTime。