diff --git a/skills/baoyu-post-to-wechat/SKILL.md b/skills/baoyu-post-to-wechat/SKILL.md index cd562a8..d1ac7c6 100644 --- a/skills/baoyu-post-to-wechat/SKILL.md +++ b/skills/baoyu-post-to-wechat/SKILL.md @@ -1,7 +1,7 @@ --- name: baoyu-post-to-wechat description: Posts content to WeChat Official Account (微信公众号) via API or Chrome CDP. Supports article posting (文章) with HTML, markdown, or plain text input, and image-text posting (贴图, formerly 图文) with multiple images. Markdown article workflows default to converting ordinary external links into bottom citations for WeChat-friendly output. Use when user mentions "发布公众号", "post to wechat", "微信公众号", or "贴图/图文/文章". -version: 1.117.5 +version: 1.118.0 metadata: openclaw: homepage: https://github.com/JimLiu/baoyu-skills#baoyu-post-to-wechat 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 3e8cba1..7cf41e2 100644 --- a/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts +++ b/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts @@ -8,6 +8,7 @@ import { extractSummaryFromBody, extractTitleFromMarkdown, parseFrontmatter, + preprocessMermaidInMarkdown, renderMarkdownDocument, replaceMarkdownImagesWithPlaceholders, resolveColorToken, @@ -15,6 +16,7 @@ import { serializeFrontmatter, stripWrappingQuotes, } from "baoyu-md"; +import { closeRenderer, renderMermaidToPng } from "baoyu-chrome-cdp/mermaid"; interface ImageInfo { placeholder: string; @@ -55,8 +57,27 @@ export async function convertMarkdown( summary = extractSummaryFromBody(body, 120); } + const { markdown: mermaidProcessedBody, images: mermaidImages } = + await preprocessMermaidInMarkdown(body, { + baseDir, + renderFn: renderMermaidToPng, + onError: (error, block) => { + const message = error instanceof Error ? error.message : String(error); + console.error( + `[md-to-wechat] mermaid render failed (${block.code.slice(0, 40).replace(/\s+/g, " ")}…): ${message}`, + ); + }, + }); + + if (mermaidImages.length > 0) { + const fresh = mermaidImages.filter((image) => !image.cached).length; + console.error( + `[md-to-wechat] mermaid: ${mermaidImages.length} block(s), ${fresh} rendered, ${mermaidImages.length - fresh} cached`, + ); + } + const { images, markdown: rewrittenBody } = replaceMarkdownImagesWithPlaceholders( - body, + mermaidProcessedBody, "WECHATIMGPH_", ); const rewrittenMarkdown = `${serializeFrontmatter(frontmatter)}${rewrittenBody}`; @@ -166,7 +187,11 @@ async function main(): Promise { console.log(JSON.stringify(result, null, 2)); } -await main().catch((error) => { +try { + await main(); +} catch (error) { console.error(`Error: ${error instanceof Error ? error.message : String(error)}`); - process.exit(1); -}); + process.exitCode = 1; +} finally { + await closeRenderer(); +} diff --git a/skills/baoyu-post-to-weibo/SKILL.md b/skills/baoyu-post-to-weibo/SKILL.md index e720801..c767010 100644 --- a/skills/baoyu-post-to-weibo/SKILL.md +++ b/skills/baoyu-post-to-weibo/SKILL.md @@ -1,7 +1,7 @@ --- name: baoyu-post-to-weibo description: Posts content to Weibo (微博). Supports regular posts with text, images, and videos, and headline articles (头条文章) with Markdown input via Chrome CDP. Use when user asks to "post to Weibo", "发微博", "发布微博", "publish to Weibo", "share on Weibo", "写微博", or "微博头条文章". -version: 1.56.1 +version: 1.57.0 metadata: openclaw: homepage: https://github.com/JimLiu/baoyu-skills#baoyu-post-to-weibo diff --git a/skills/baoyu-post-to-weibo/scripts/md-to-html.ts b/skills/baoyu-post-to-weibo/scripts/md-to-html.ts index 1296c6c..c25e863 100644 --- a/skills/baoyu-post-to-weibo/scripts/md-to-html.ts +++ b/skills/baoyu-post-to-weibo/scripts/md-to-html.ts @@ -8,6 +8,7 @@ import { extractTitleFromMarkdown, parseFrontmatter, pickFirstString, + preprocessMermaidInMarkdown, renderMarkdownDocument, replaceMarkdownImagesWithPlaceholders, resolveColorToken, @@ -16,6 +17,7 @@ import { serializeFrontmatter, stripWrappingQuotes, } from "baoyu-md"; +import { closeRenderer, renderMermaidToPng } from "baoyu-chrome-cdp/mermaid"; interface ImageInfo { placeholder: string; @@ -69,8 +71,27 @@ export async function parseMarkdown( || pickFirstString(frontmatter, ["featureImage", "cover_image", "coverImage", "cover", "image"]) || null; + const { markdown: mermaidProcessedBody, images: mermaidImages } = + await preprocessMermaidInMarkdown(body, { + baseDir, + renderFn: renderMermaidToPng, + onError: (error, block) => { + const message = error instanceof Error ? error.message : String(error); + console.error( + `[md-to-html] mermaid render failed (${block.code.slice(0, 40).replace(/\s+/g, " ")}…): ${message}`, + ); + }, + }); + + if (mermaidImages.length > 0) { + const fresh = mermaidImages.filter((image) => !image.cached).length; + console.error( + `[md-to-html] mermaid: ${mermaidImages.length} block(s), ${fresh} rendered, ${mermaidImages.length - fresh} cached`, + ); + } + const { images, markdown: rewrittenBody } = replaceMarkdownImagesWithPlaceholders( - body, + mermaidProcessedBody, "WBIMGPH_", ); const rewrittenMarkdown = `${serializeFrontmatter(frontmatter)}${rewrittenBody}`; @@ -163,8 +184,12 @@ Options: } if (import.meta.main ?? (process.argv[1] && path.resolve(process.argv[1]) === path.resolve(import.meta.filename ?? ""))) { - await main().catch((error) => { + try { + await main(); + } catch (error) { console.error(`Error: ${error instanceof Error ? error.message : String(error)}`); - process.exit(1); - }); + process.exitCode = 1; + } finally { + await closeRenderer(); + } } diff --git a/skills/baoyu-post-to-x/SKILL.md b/skills/baoyu-post-to-x/SKILL.md index 36a0e50..1d3efca 100644 --- a/skills/baoyu-post-to-x/SKILL.md +++ b/skills/baoyu-post-to-x/SKILL.md @@ -1,7 +1,7 @@ --- name: baoyu-post-to-x description: Posts content and articles to X (Twitter). Supports regular posts with images/videos and X Articles (long-form Markdown). In Codex, honor explicit requests for the Codex Chrome plugin/@chrome by using the Chrome Extension workflow; otherwise use Chrome Computer Use when available and fall back to real Chrome CDP scripts only when allowed. Use when user asks to "post to X", "tweet", "publish to Twitter", or "share on X". -version: 1.57.2 +version: 1.58.0 metadata: openclaw: homepage: https://github.com/JimLiu/baoyu-skills#baoyu-post-to-x diff --git a/skills/baoyu-post-to-x/scripts/md-to-html.ts b/skills/baoyu-post-to-x/scripts/md-to-html.ts index 77fb331..7ee6ce1 100644 --- a/skills/baoyu-post-to-x/scripts/md-to-html.ts +++ b/skills/baoyu-post-to-x/scripts/md-to-html.ts @@ -15,6 +15,9 @@ import remarkCjkFriendly from 'remark-cjk-friendly'; import remarkParse from 'remark-parse'; import remarkStringify from 'remark-stringify'; +import { preprocessMermaidInMarkdown } from 'baoyu-md'; +import { closeRenderer, renderMermaidToPng } from 'baoyu-chrome-cdp/mermaid'; + interface ImageInfo { placeholder: string; localPath: string; @@ -318,10 +321,29 @@ export async function parseMarkdown( coverImagePath = findCoverImageNearMarkdown(baseDir); } + const { markdown: mermaidProcessedBody, images: mermaidImages } = + await preprocessMermaidInMarkdown(body, { + baseDir, + renderFn: renderMermaidToPng, + onError: (error, block) => { + const message = error instanceof Error ? error.message : String(error); + console.error( + `[md-to-html] mermaid render failed (${block.code.slice(0, 40).replace(/\s+/g, ' ')}…): ${message}`, + ); + }, + }); + + if (mermaidImages.length > 0) { + const fresh = mermaidImages.filter((image) => !image.cached).length; + console.error( + `[md-to-html] mermaid: ${mermaidImages.length} block(s), ${fresh} rendered, ${mermaidImages.length - fresh} cached`, + ); + } + const images: Array<{ src: string; alt: string; blockIndex: number }> = []; let imageCounter = 0; - const { html, totalBlocks } = convertMarkdownToHtml(body, (src, alt) => { + const { html, totalBlocks } = convertMarkdownToHtml(mermaidProcessedBody, (src, alt) => { const placeholder = `XIMGPH_${++imageCounter}`; images.push({ src, alt, blockIndex: -1 }); return placeholder; @@ -460,8 +482,12 @@ async function main(): Promise { } if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { - await main().catch((err) => { + try { + await main(); + } catch (err) { console.error(`Error: ${err instanceof Error ? err.message : String(err)}`); - process.exit(1); - }); + process.exitCode = 1; + } finally { + await closeRenderer(); + } } diff --git a/skills/baoyu-post-to-x/scripts/package.json b/skills/baoyu-post-to-x/scripts/package.json index 7ab7949..390a71d 100644 --- a/skills/baoyu-post-to-x/scripts/package.json +++ b/skills/baoyu-post-to-x/scripts/package.json @@ -4,6 +4,7 @@ "type": "module", "dependencies": { "baoyu-chrome-cdp": "^0.1.0", + "baoyu-md": "^0.1.0", "front-matter": "^4.0.2", "highlight.js": "^11.11.1", "marked": "^15.0.6",