Halo Publish 工具优化:一次发布踩坑与修复实录

背景

前几天我开发了 DownloadXBookmarks 扩展后用博客记录了整个过程,但在发布到 Halo 博客这一步卡了很久——文章内容太大,bb_browser_eval 的参数被截断,导致发布流程反复失败。最终折腾了多轮才成功发出去。

这次经历促使我对发布工具做了系统性优化。本文记录遇到的问题和修复方案。

问题复盘

1. 大内容被截断

我的文章 HTML 约 9468 字节。第一次用 halo_publish 工具时,它输出了一大段 JS 代码但没有执行——工具无法解析大内容的输出格式。

❌ 未知输出:
sessionStorage.setItem("halo_html","<h2>背景</h2>...");"ok";(async function(){...})()

2. eval 参数长度限制

改用 bb_browser_eval 手动执行后,发现单次参数传 14KB 的 JS 代码时,字符串被静默截断——最终只存了 370 字符到 sessionStorage,而不是完整的 9468。

原因bb_browser_eval 的 JS 代码通过 HTTP 传输到浏览器,超过约 7000 字节会被截断

3. 错误的分块策略

脚本原有 MAX_CODE = 11000 的阈值,认为超过才分块。但我的文章刚好卡在边界附近——9468 的 HTML 加上 publish JS 约 11000 字节,被判定为 SINGLE 模式。但实际上传输过程中的 JSON 序列化、URL 编码等额外开销导致实际传输量超过限制。

4. Tab ID 被截断

Halo 标签页 ID 是 985d,但系统把它当数字解析成了 985,丢掉了 d。好在 bb_browser_eval 能正确处理完整 ID,但导航类操作不行。

修复方案

1. 降低安全阈值

// 原来
const MAX_CODE = 11000;

// 现在  
const MAX_STORE_CODE = 6000;   // 单次 eval 最大安全长度
const MAX_SINGLE = 7000;       // store + publish 合并上限

从 11000 降到 6000,留 15% 安全余量。同时分块算法从激进缩放的 0.9 改为保守的 0.85,起始点从 0.9 降到 0.5,避免 overshoot。

2. 强制分块

原来 9468 字节的 HTML 被错误判定为 SINGLE 模式。现在它被正确分为 4 个 chunk

CHUNKS:4
  0: halo-chunk-xxx-0.js (4670 bytes) ✅
  1: halo-chunk-xxx-1.js (4038 bytes) ✅
  2: halo-chunk-xxx-2.js (4058 bytes) ✅
  3: halo-chunk-xxx-3.js (303 bytes)  ✅

每个 chunk 都远低于 6000 字节的安全线。

3. 分步执行流程

大文章不再尝试合并为一次 eval,而是拆成三步:

Step 1: bb_browser_eval → store chunk 0  → sessionStorage
Step 1: bb_browser_eval → store chunk 1  → sessionStorage  
Step 1: bb_browser_eval → store chunk N  → sessionStorage
------------------------------------------------------
Step 2: bb_browser_eval → assemble        → sessionStorage("halo_html")
Step 3: bb_browser_eval → publish         → Halo API → Published ✅

为什么不用 —exec 自动执行?

最初我尝试在脚本中添加 --exec 模式,让 Node.js 自动调 bb_browser_eval。但 bb_browser_eval 是 pi 工具函数,不是系统命令,Node.js 进程调不了。所以脚本保持纯粹的 JS 生成职责,执行由 pi agent 编排。

4. 输出格式优化

SINGLE 模式的输出从:

Next: bb_browser_eval in Halo tab

改为:

Steps: bb_browser_eval <tab> "$(cat /tmp/halo-publish-xxx.js)"

CHUNKS 模式新增每步的具体命令,AI 直接复制执行即可。

5. SKILL 文档补充

新增了:
- 常见问题章节:Tab 查找、截断处理、内容不完整排查
- 技术原理说明:为什么分块、sessionStorage 中转机制
- Halo API 流程:两个 API 调用的具体细节

实测数据

指标

优化前

优化后

MAX_CODE

11000

6000

单 chunk 最大

~11000(越界)

4670(安全)

chunk 数

1(截断)

4(完整)

发布成功率

0%(反复失败)

100%(一次到位)

操作步骤数

~5 次试错

3 步确定

经验教训

  1. 参数长度限制要实测:文档说 11000 安全,实际 7000 就开始出问题。数值要保守再保守
  2. 大内容永远分块:即使是”刚好够”的尺寸,也强制分块。边际情况最坑人。
  3. 工具职责要单一:生成 JS 的脚本就只管生成,执行交给编排层。试图在脚本里做一切反而增加耦合。
  4. 故障排查文档要写透:踩过的坑整理成 FAQ,下次遇到直接查,不用重新推导。

后续优化方向

  • ⬜ 增量发布(检测文章变化,只更新内容)
  • ⬜ 多图床支持(文章中的本地图片自动上传)
  • ⬜ 定时自动发布(配合 CI/CD 流水线)
  • ⬜ 发布预览(先在草稿模式预览再公开)

如果你也在用 Halo 博客 + bb-browser 做自动化发布,欢迎交流踩坑经验。

相关阅读