Skill: leeguooooo/blog-content-publish (version 1.0.8)

--- name: blog-content-publish description: Publish editorial and dynamic section content with blog-publish, enforce quality gates for hot/news/ai_news, and sync repository skills to ClawHub via clawhub sync --all. --- # Goal - Canonical npm package name is `@leeguoo/blog-publish` (single source of truth). - Use `blog-publish` to publish normal blog content and dynamic section content. - Keep dynamic section publishing compliant with no public `producer` leakage. - Reuse one skill across `editorial`, `hot`, `news`, and `ai_news`. - Enforce deterministic quality rules so auto-published News/Hot briefs are readable and source-grounded. - Use the image upload path in `blog-publish` to generate CDN-hosted markdown URLs for embedded assets. # When to Use - Publishing normal editorial posts. - Publishing dynamic section posts under `hot/news/ai_news`. - Running batch skill sync to ClawHub. # Inputs - Required for all entries: - `locale` - `slug` - `title` - `summary` - `contentMarkdown` - Required for dynamic sections: - `section` (`hot`, `news`, or `ai_news`) - Optional: - `pairId` (if omitted, server falls back to `slug`) - `repoUrl` - `sourceUrl` - `publicSourceLabel` - `tags` - `decisionMeta` - `producer` (internal only, never for public display) # Quality Gates (Required for `hot/news/ai_news`) - Output shape: - Title + short deck (`summary`) + structured body. - Body must contain numbered topics (`## 1) ...`, `## 2) ...`) and a closing takeaways section. - Dynamic briefs should normally contain `4-8` topics; reject outputs with only `1-2` thin topics unless the source itself is extremely short. - Topic quality: - Each topic must include exactly five lines: - `来源/Source` - `证据/Evidence` - `摘要/Summary` - `解读/Interpretation` - `行动建议/Action` - `证据/Evidence` must point to a concrete anchor (release bullet / PR / issue / official doc section), not only homepage-level links. - `摘要/Summary` is factual and source-grounded. - `解读/Interpretation` is inference/opinion and must not fabricate facts; include explicit impact level (`P0`/`P1`/`P2`). - `行动建议/Action` must be executable (for example: "upgrade now", "canary first", "hold and monitor"). - Link format: - Do not publish naked URLs in prose or list items. - Use Markdown links only: `[来源标题](https://...)`. - One topic should have one primary source link + one evidence link when available. - Avoid same-link repetition across all topics; evidence links should be topic-specific whenever possible. - Forbidden patterns: - No "据说/rumor/未证实" style claims without attribution. - No placeholder text (`TBD`, `待补充`, `lorem ipsum`). - No leaked render placeholders (`INLINE_CODE`, `RUBYPH`, `@@...@@`). - No exposing internal producer identity in byline/meta/body (for example: "generated by skill/openclaw bot"). - Mentioning `OpenClaw` is allowed when it is the article subject, not the publisher identity. # Quality Score (Publish Threshold) - Score each topic on 3 axes (`0-2` each): - Evidence quality: traceable and specific. - Summary clarity: factual, concise, no ambiguity. - Actionability: recommendation can be executed. - Reject publish if: - Any topic total score `< 4`, or - Any topic missing `Evidence`/`Action`. # Body Template (`news` / `hot` / `ai_news`) ```md # {{title}} 更新时间：{{timestamp}} 数据来源：{{source_set}} > 说明：本期每条热点均包含「摘要 + 解读」。 ## 1) {{topic_title}} - 来源：[{{source_name}}]({{url}}) - 证据：[{{evidence_anchor}}]({{evidence_url}}) - 摘要：{{fact_summary}} - 解读（P1）：{{implication}} - 行动建议：{{operator_action}} ## 2) {{topic_title}} - 来源：[{{source_name}}]({{url}}) - 证据：[{{evidence_anchor}}]({{evidence_url}}) - 摘要：{{fact_summary}} - 解读（P2）：{{implication}} - 行动建议：{{operator_action}} ## 总结 1. {{takeaway_1}} 2. {{takeaway_2}} 3. {{takeaway_3}} ``` # Preflight Checks - Before publish, run dry-run and fail fast on quality violations: - `blog-publish publish --dry-run --input <file>.json` - `blog-publish publish --dry-run --input <file>.md` - Quick markdown guardrails (example): - Reject naked links: `rg -n "(^|[^\\]\\()https?://"` against generated markdown files. - Reject leaked render placeholders: `rg -n "INLINE_CODE|RUBYPH|@@[A-Z0-9_]+@@"` against generated markdown files. - Verify each topic has `Source + Evidence + Summary + Interpretation + Action`. - Verify each interpretation includes risk level label (`P0|P1|P2`). - Verify evidence links are not all identical across every topic. - If `pairId` is missing, ensure `slug` is stable because server uses it for localization grouping. - Only proceed to real publish when dry-run is clean. # Publishing Rules - Default `section` is `editorial` when absent. - `blog-publish publish` and `blog-publish update` both accept JSON payload files and markdown files with frontmatter. - Use `blog-publish post-list` to discover existing `locale` + `slug` pairs before editing existing posts. - Use `blog-publish download` to export stored content into editable markdown frontmatter, then feed that file back into `blog-publish update`. - Single-language submit is supported for all sections; server handles auto-localization. - Auto-generated section content is free by default and does not enter premium gating. - Keep `producer` as internal metadata only; public surfaces must use `publicSourceLabel` or section label. # Command Playbook - Auth: - `pnpm add -g @leeguoo/blog-publish` - `blog-publish login --api-base https://blog.misonote.com --sso-client-id misonote-blog-web --sso-redirect-uri https://blog.misonote.com/auth/callback` - `blog-publish whoami` - `blog-publish post-list --api-base https://blog.misonote.com --locale zh` - `blog-publish download --api-base https://blog.misonote.com --locale zh --slug <slug> --output ./drafts/<slug>.zh.md` - `blog-publish upload --api-base https://blog.misonote.com --file ./assets/cover.png --markdown-only` - `blog-publish upload --api-base https://blog.misonote.com --file ./assets/cover.png --filename cover-final.png` - Automation Auth (OpenClaw/CI): - Use service token only: `PUBLISH_API_TOKEN=<secret>` - Preflight: `blog-publish whoami --api-base https://blog.misonote.com` - Never prompt end users to complete browser authorization links. - Publish: - `blog-publish publish --dry-run --input <file>.json` - `blog-publish publish --dry-run --input <file>.md` - `blog-publish publish --input <file>.json` - `blog-publish publish --input <file>.md` - `blog-publish update --dry-run --input <file>.md` - `blog-publish update --input <file>.md` ### Media Notes - Publish API now uses `MEDIA_CDN_BASE_URL` and emits image markdown URLs like: - `https://img.leeguoo.com/media/<asset-id>/<filename>` - Repeated uploads of the same file are deduplicated by SHA-256 and return: - `deduped: true` and the existing `asset.id` instead of creating a duplicate. - Keep `img.leeguoo.com` as the canonical image host in generated markdown to leverage Cloudflare CDN + cache. - Skill sync: - `pnpm clawhub:sync:dry-run` - `pnpm clawhub:sync:all` - Alias compatible with team wording (`clawdhub sync all`): - `pnpm clawdhub:sync:dry-run` - `pnpm clawdhub:sync:all` # Failure Handling - Publish failure: - Check API status code and error payload first. - Fix validation issues (required fields, auth scope), then retry. - If quality gates fail, regenerate the current locale content and retry. - If login gets wrong client/redirect values, remove environment overrides (`BLOG_PUBLISH_SSO_CLIENT_ID`, `BLOG_PUBLISH_SSO_REDIRECT_URI`) and rerun strict login command. - If running in automation and error is `PUBLISH_UNAUTHORIZED`, stop interactive login attempts, rotate `PUBLISH_API_TOKEN`, then retry publish. - Sync failure: - Record error output and alert maintainers. - Do not block already-published content visibility. - Retry sync after login/permission/network issues are resolved.


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)