From ec1743592cbe585cf412ea0cd59838735f963d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20Liu=20=E5=AE=9D=E7=8E=89?= Date: Sun, 25 Jan 2026 16:09:24 -0600 Subject: [PATCH] fix(baoyu-post-to-wechat): fix regressions from Windows compatibility PR - Fix broken md-to-wechat-fixed.ts/wechat-article-fixed.ts filename references that cause runtime crash (files were never renamed) - Restore frontmatter quote stripping for title/summary values - Restore --title CLI parameter functionality (was silently ignored) - Fix summary extraction to properly skip headings, quotes, lists - Fix argument parsing to reject single-dash args as file paths - Remove debug console.error logs left from development --- .../scripts/md-to-wechat.ts | 52 ++++++++++++------- .../scripts/wechat-article.ts | 19 +++---- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts b/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts index 690b5d0..26e65ee 100644 --- a/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts +++ b/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts @@ -101,7 +101,10 @@ function parseFrontmatter(content: string): { frontmatter: Record 0) { const key = line.slice(0, colonIdx).trim(); - const value = line.slice(colonIdx + 1).trim(); + let value = line.slice(colonIdx + 1).trim(); + if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { + value = value.slice(1, -1); + } frontmatter[key] = value; } } @@ -109,21 +112,36 @@ function parseFrontmatter(content: string): { frontmatter: Record { +export async function convertMarkdown(markdownPath: string, options?: { title?: string; theme?: string }): Promise { const baseDir = path.dirname(markdownPath); const content = fs.readFileSync(markdownPath, 'utf-8'); + const theme = options?.theme ?? 'default'; const { frontmatter, body } = parseFrontmatter(content); - let title = frontmatter.title || path.basename(markdownPath, path.extname(markdownPath)); + let title = options?.title ?? frontmatter.title ?? ''; + if (!title) { + const h1Match = body.match(/^#\s+(.+)$/m); + if (h1Match) title = h1Match[1]!; + } + if (!title) title = path.basename(markdownPath, path.extname(markdownPath)); const author = frontmatter.author || ''; let summary = frontmatter.description || frontmatter.summary || ''; if (!summary) { - const paragraphs = body.split('\n\n').filter(p => p.trim() && !p.startsWith('#')); - for (const para of paragraphs) { - const cleanText = para - .replace(/[#*`_\[\]]/g, '') + const lines = body.split('\n'); + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) continue; + if (trimmed.startsWith('#')) continue; + if (trimmed.startsWith('![')) continue; + if (trimmed.startsWith('>')) continue; + if (trimmed.startsWith('-') || trimmed.startsWith('*')) continue; + if (/^\d+\./.test(trimmed)) continue; + + const cleanText = trimmed + .replace(/\*\*(.+?)\*\*/g, '$1') + .replace(/\*(.+?)\*/g, '$1') .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') .replace(/`([^`]+)`/g, '$1'); @@ -149,14 +167,11 @@ export async function convertMarkdown(markdownPath: string, theme = 'default'): const tempMdPath = path.join(tempDir, 'temp-article.md'); await writeFile(tempMdPath, modifiedMarkdown, 'utf-8'); - // 使用 fileURLToPath 来正确处理 Windows 路径 const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const renderScript = path.join(__dirname, 'md', 'render.ts'); console.error(`[md-to-wechat] Rendering markdown with theme: ${theme}`); - console.error(`[md-to-wechat] Script dir: ${__dirname}`); - console.error(`[md-to-wechat] Render script: ${renderScript}`); const result = spawnSync('npx', ['-y', 'bun', renderScript, tempMdPath, '--theme', theme], { stdio: ['inherit', 'pipe', 'pipe'], @@ -196,7 +211,7 @@ function printUsage(): never { console.log(`Convert Markdown to WeChat-ready HTML with image placeholders Usage: - npx -y bun md-to-wechat-fixed.ts [options] + npx -y bun md-to-wechat.ts [options] Options: --title Override title @@ -217,8 +232,8 @@ Output JSON format: } Example: - npx -y bun md-to-wechat-fixed.ts article.md - npx -y bun md-to-wechat-fixed.ts article.md --theme grace + npx -y bun md-to-wechat.ts article.md + npx -y bun md-to-wechat.ts article.md --theme grace `); process.exit(0); } @@ -230,15 +245,16 @@ async function main(): Promise<void> { } let markdownPath: string | undefined; - let theme = 'default'; + let title: string | undefined; + let theme: string | undefined; for (let i = 0; i < args.length; i++) { const arg = args[i]!; if (arg === '--title' && args[i + 1]) { - args[i + 1]; // skip value + title = args[++i]; } else if (arg === '--theme' && args[i + 1]) { - theme = args[++i]!; - } else if (!arg.startsWith('--')) { + theme = args[++i]; + } else if (!arg.startsWith('-')) { markdownPath = arg; } } @@ -253,7 +269,7 @@ async function main(): Promise<void> { process.exit(1); } - const result = await convertMarkdown(markdownPath, theme); + const result = await convertMarkdown(markdownPath, { title, theme }); console.log(JSON.stringify(result, null, 2)); } diff --git a/skills/baoyu-post-to-wechat/scripts/wechat-article.ts b/skills/baoyu-post-to-wechat/scripts/wechat-article.ts index 2f992cc..a4ce55b 100644 --- a/skills/baoyu-post-to-wechat/scripts/wechat-article.ts +++ b/skills/baoyu-post-to-wechat/scripts/wechat-article.ts @@ -111,8 +111,7 @@ async function copyHtmlFromBrowser(cdp: CdpConnection, htmlFilePath: string): Pr await sleep(300); console.log('[wechat] Copying with CDP keyboard event...'); - // 使用 CDP 发送 Ctrl+C (更可靠,不依赖系统工具) - const modifiers = process.platform === 'darwin' ? 4 : 2; // 4=Cmd, 2=Ctrl + const modifiers = process.platform === 'darwin' ? 4 : 2; await cdp.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'c', @@ -136,8 +135,7 @@ async function copyHtmlFromBrowser(cdp: CdpConnection, htmlFilePath: string): Pr async function pasteFromClipboardInEditor(session: ChromeSession): Promise<void> { console.log('[wechat] Pasting with CDP keyboard event...'); - // 使用 CDP 发送 Ctrl+V (更可靠,不依赖系统工具) - const modifiers = process.platform === 'darwin' ? 4 : 2; // 4=Cmd, 2=Ctrl + const modifiers = process.platform === 'darwin' ? 4 : 2; await session.cdp.send('Input.dispatchKeyEvent', { type: 'keyDown', key: 'v', @@ -159,7 +157,7 @@ async function pasteFromClipboardInEditor(session: ChromeSession): Promise<void> async function parseMarkdownWithPlaceholders(markdownPath: string, theme?: string): Promise<{ title: string; author: string; summary: string; htmlPath: string; contentImages: ImageInfo[] }> { const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); - const mdToWechatScript = path.join(__dirname, 'md-to-wechat-fixed.ts'); + const mdToWechatScript = path.join(__dirname, 'md-to-wechat.ts'); const args = ['-y', 'bun', mdToWechatScript, markdownPath]; if (theme) args.push('--theme', theme); @@ -325,7 +323,6 @@ export async function postArticle(options: ArticleOptions): Promise<void> { await clickElement(session, '.ProseMirror'); await sleep(1000); - // 再次点击确保焦点 console.log('[wechat] Ensuring editor focus...'); await clickElement(session, '.ProseMirror'); await sleep(500); @@ -409,7 +406,7 @@ function printUsage(): never { console.log(`Post article to WeChat Official Account Usage: - npx -y bun wechat-article-fixed.ts [options] + npx -y bun wechat-article.ts [options] Options: --title <text> Article title (auto-extracted from markdown) @@ -424,10 +421,10 @@ Options: --profile <dir> Chrome profile directory Examples: - npx -y bun wechat-article-fixed.ts --markdown article.md - npx -y bun wechat-article-fixed.ts --markdown article.md --theme grace --submit - npx -y bun wechat-article-fixed.ts --title "标题" --content "内容" --image img.png - npx -y bun wechat-article-fixed.ts --title "标题" --html article.html --submit + npx -y bun wechat-article.ts --markdown article.md + npx -y bun wechat-article.ts --markdown article.md --theme grace --submit + npx -y bun wechat-article.ts --title "标题" --content "内容" --image img.png + npx -y bun wechat-article.ts --title "标题" --html article.html --submit Markdown mode: Images in markdown are converted to placeholders. After pasting HTML,