diff --git a/CHANGELOG.md b/CHANGELOG.md index db42b77..f7e02a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ ### Fixed +- **推送标题缺省取 H1**:不显式传 `--title` 时,orchestrator 的推送标题曾退化为输入文件名 slug(`publish.md` → 草稿标题「publish」,2026-07-18 生产现场复现并清理废草稿);新增 `extractH1FromFile`/`extractH1FromMarkdown`,`pushTitle = --title || H1 || slug`,自动 relay 与 manual relay 两条推送路径统一使用 - **draft/update 47001**:`create_wechat_draft --update` 复用了 draft/add 的 `articles` 数组形状,而 draft/update 要求单篇文章对象,微信返回 47001 data format error(relay 现场 A/B 复现:数组 → 47001,对象 → ok);新增 `applyDraftUpdateShape` 统一转换,harness 测试钉住形状 - **Pipeline 自洽修补**:显式串联 render/preflight/orchestrator 的封面图和 `--skip-image-check` 参数,避免 `pre_image_missing` 隐式破坏默认入口 - **AutoHeal 阻断逻辑**:preflight JSON 改为完整解析,存在不可自动修复的 L1/Agent 失败时不再继续进入 bundle diff --git a/scripts/orchestrator.mjs b/scripts/orchestrator.mjs index 6a613aa..8636a1f 100644 --- a/scripts/orchestrator.mjs +++ b/scripts/orchestrator.mjs @@ -157,6 +157,19 @@ export function extractSummaryFromFile(mdPath) { } } +export function extractH1FromMarkdown(text) { + const match = text.match(/^#\s+(.+)$/m); + return match ? match[1].trim() : ""; +} + +export function extractH1FromFile(mdPath) { + try { + return extractH1FromMarkdown(fs.readFileSync(mdPath, "utf8")); + } catch { + return ""; + } +} + function formatLocalDateStamp(date = new Date()) { const yyyy = String(date.getFullYear()); const mm = String(date.getMonth() + 1).padStart(2, "0"); @@ -702,6 +715,8 @@ function main() { // 工作目录和日志 const paths = resolvePipelinePaths({ inputPath, outDirArg: args["out-dir"] || "" }); const { workDir, slug, archiveDir, outDir, logPath, renderOut, lintOut, auditOut, pushResultOut } = paths; + // 推送标题缺省取正文 H1,避免退化为文件名(曾产出标题为「publish」的废草稿,2026-07-18) + const pushTitle = title || extractH1FromFile(inputPath) || slug; fs.mkdirSync(archiveDir, { recursive: true }); // 清空旧日志,避免累积 if (fs.existsSync(logPath)) { @@ -986,7 +1001,7 @@ function main() { } info("Executing create_wechat_draft.mjs on relay..."); - const remoteTitle = title || slug; + const remoteTitle = pushTitle; const remoteThumbArg = thumbImage ? ` --thumb-image ${shellQuote(path.basename(thumbImage))}` : ""; const remoteCropArg = cropSpec ? ` --crop-235-1 ${shellQuote(cropSpec)}` : ""; const remoteDigestArg = digest ? ` --digest ${shellQuote(digest)}` : ""; @@ -1087,7 +1102,7 @@ function main() { outDir, renderOut, lintOut, - title, + title: pushTitle, slug, author, openComment,