{"id":50950648,"url":"https://github.com/AutomateLab-tech/publishing-skills","last_synced_at":"2026-06-19T20:00:59.675Z","repository":{"id":357614729,"uuid":"1237745012","full_name":"AutomateLab-tech/publishing-skills","owner":"AutomateLab-tech","description":"Three composable Claude skills for end-to-end long-tail SEO blog publishing on Ghost CMS: topic research, draft \u0026 publish, SVG figure generation.","archived":false,"fork":false,"pushed_at":"2026-06-19T07:13:23.000Z","size":123,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-19T09:13:34.074Z","etag":null,"topics":["agent-skill","blog","blog-automation","claude","claude-code","claude-skill","ghost","ghost-cms","mcp","publishing","seo"],"latest_commit_sha":null,"homepage":"https://automatelab.tech/products/skills-and-plugins/publishing-skills/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit-0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AutomateLab-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-13T13:20:34.000Z","updated_at":"2026-06-19T07:13:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/AutomateLab-tech/publishing-skills","commit_stats":null,"previous_names":["ratamaha-git/publishing-skills","automatelab-tech/publishing-skills"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AutomateLab-tech/publishing-skills","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutomateLab-tech%2Fpublishing-skills","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutomateLab-tech%2Fpublishing-skills/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutomateLab-tech%2Fpublishing-skills/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutomateLab-tech%2Fpublishing-skills/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AutomateLab-tech","download_url":"https://codeload.github.com/AutomateLab-tech/publishing-skills/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AutomateLab-tech%2Fpublishing-skills/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34546199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-skill","blog","blog-automation","claude","claude-code","claude-skill","ghost","ghost-cms","mcp","publishing","seo"],"created_at":"2026-06-18T01:00:29.332Z","updated_at":"2026-06-19T20:00:59.660Z","avatar_url":"https://github.com/AutomateLab-tech.png","language":"Python","funding_links":[],"categories":["🛠️ Frameworks \u0026 Platforms","Productivity Tools"],"sub_categories":["Multi-Agent Orchestration","Cost Optimization"],"readme":"# publishing-skills\n\nFour composable skills that turn an AI coding agent (Claude, Cursor, Codex, Gemini, Copilot, ...) into a long-tail SEO publishing pipeline. **Platform-agnostic** - works against Ghost, WordPress, Webflow, Sanity, Strapi, or any static-site generator (Hugo, Astro, Eleventy, Jekyll, Next-MDX).\n\nBuilt for indie hackers, founders, content marketers, and dev-tool teams who want AI to draft blog posts that actually rank in search and get quoted by AI assistants - not paraphrased docs, not hallucinated benchmarks, not generic \"ultimate guide\" filler.\n\n| Skill | What it does | Who it's for |\n|---|---|---|\n| **`blog-topic-research`** | Validates a topic has real, verifiable demand (People Also Ask, Reddit, Stack Overflow, GitHub issues, vendor forums, changelogs) before you spend tokens drafting. Every accepted topic carries citable evidence URLs, a problem summary, confirmed fixes, version context, and FAQ variants the writer can use directly. | Anyone tired of writing posts nobody searches for, and editorial pipelines that need an evidence-backed backlog. |\n| **`seo-blog-writer`** | End-to-end pipeline for a single post: classify → research → outbound interlinks → draft clean HTML → scrub LLM tells → AI-SEO audit → optional glossary auto-link → publish. Adds FAQPage + BreadcrumbList + HowTo JSON-LD for AI-citation extractability. Pre-publish gate asserts H2-question shape, figure count (`max(1, words // 500)` for 800+ word posts), bullet discipline (3-9 items), and currency (`as of \u003cYYYY\u003e` qualifier on stale years). Ships a glossary auto-linker that wraps the first mention of each known technical term in an internal link with hover-tooltip metadata. **Platform-pluggable publish step** - ships with Ghost Admin API, WordPress REST, and static-site adapters; any other CMS is a ~20-line snippet. | Founders and marketers who want to ship one ranking post a day without paying a writer or a designer. |\n| **`blog-figure-svg`** | Generates accessible SVG figures (flow, comparison bars, taxonomy, terminal mocks, 1600x840 OG feature cards) with a consistent palette, screen-reader metadata, and figcaption-ready output. Rasterizes to compressed PNG for upload to any CMS. | Anyone shipping more than 3 posts a month who doesn't want stock photos or Midjourney filler on every article. |\n| **`blog-editorial-calendar`** | The orchestration layer over the other three. Keeps an evidence-backed backlog, picks the next topic so your corpus drifts toward the cluster + format mix you defined in `config.json`, schedules posts into a rolling daily cadence, reconciles the backlog against what's live on your CMS, and auto-refills via `blog-topic-research` when the queue runs dry. Drives whatever adapter `seo-blog-writer` is configured for. | Teams who want a hands-off cadence that publishes on schedule and stays balanced - not a pile of posts in one category. |\n\nTogether, they form a complete pipeline: **plan the cadence → research the topic → write the post → illustrate it → publish to your platform of choice**.\n\n## Installing\n\n### Via skills.sh (any agent runtime)\n\nInstalls all 4 skills into Claude Code, Cursor, Codex, Gemini CLI, GitHub Copilot, and 50+ other runtimes at once:\n\n```bash\nnpx skills add AutomateLab-tech/publishing-skills\n```\n\n### Via clawhub CLI (Claude / OpenClaw runtimes)\n\n```bash\nnpm i -g clawhub\nclawhub login\nclawhub skill install blog-topic-research\nclawhub skill install seo-blog-writer\nclawhub skill install blog-figure-svg\nclawhub skill install blog-editorial-calendar\n```\n\n### Manually\n\nEach skill is a single `SKILL.md` file with YAML frontmatter. Drop it into your project's `.claude/skills/\u003cname\u003e/` directory (or your agent runtime's equivalent skill folder) and reload.\n\n```bash\ngit clone https://github.com/AutomateLab-tech/publishing-skills.git\ncp -r publishing-skills/skills/* .claude/skills/\n```\n\n## How they compose\n\n```\n+----------------------+      +--------------------------+      +-------------------+      +-------------------+\n| blog-topic-research  | ---\u003e | blog-editorial-calendar  | ---\u003e |  seo-blog-writer  | \u003c--- |  blog-figure-svg  |\n| 'is the topic worth  |      | 'pick the next topic to  |      | 'write + publish' |      | 'illustrate the   |\n|  writing about?'     | \u003c--- |  balance the corpus +    |      |                   |      |   post'           |\n+----------------------+ refill  schedule the cadence'   |      +-------------------+      +-------------------+\n                              +--------------------------+               |\n                                                                         v\n                                              +----------------------------------+\n                                              | platform adapter (one of):       |\n                                              |   - Ghost Admin API              |\n                                              |   - WordPress REST API           |\n                                              |   - static-site file output      |\n                                              |   - bring-your-own (~20 lines)   |\n                                              +----------------------------------+\n```\n\n- **`blog-topic-research`** runs first - it answers \"does anyone actually search this?\" before you spend tokens drafting.\n- **`blog-editorial-calendar`** picks the next topic to keep the corpus balanced against your target mix, schedules it into a rolling cadence, and calls `blog-topic-research` to refill when the backlog runs dry. (Optional - you can drive the writer by hand instead.)\n- **`seo-blog-writer`** consumes the research-proof scaffold (or runs from scratch), drafts the HTML, validates the bundle, and ships it through a platform adapter.\n- **`blog-figure-svg`** is invoked from within the writer's illustration step (or standalone) when a post needs charts, diagrams, or a feature card.\n\n## Requirements\n\n- **`blog-topic-research`** - no system dependencies beyond `WebSearch` / `WebFetch` in the agent runtime.\n- **`seo-blog-writer`** - Python 3. Platform-specific extras:\n  - **Ghost adapter**: `pip install requests pyjwt`; `GHOST_URL` + `GHOST_ADMIN_KEY` env vars.\n  - **WordPress adapter**: `pip install requests`; `WP_URL` + `WP_USER` + `WP_APP_PASSWORD` env vars.\n  - **Static-site adapter**: no credentials; just a target directory in your SSG repo.\n- **`blog-figure-svg`** - Python 3, plus one SVG rasterizer (ImageMagick / `rsvg-convert` / Inkscape / `cairosvg`) and optionally `pngquant` for compression.\n\n### Optional - ai-seo MCP (programmatic citation scoring)\n\n`seo-blog-writer` Step 5 (AI-SEO audit) runs a programmatic citation-worthiness and schema pass when the [**ai-seo MCP**](https://github.com/AutomateLab-tech/ai-seo-mcp) (`@automatelab/ai-seo-mcp`) is connected. The skill checks at preflight and prompts you to install it if it's missing. Without it, Step 5 falls back to a manual reasoning pass covering the same ground.\n\n```bash\nnpx -y @automatelab/ai-seo-mcp\n```\n\nThen register it in your agent's MCP config. See the [ai-seo-mcp README](https://github.com/AutomateLab-tech/ai-seo-mcp) for one-line configs for Claude Code, Cursor, and Cline.\n\n## Maintenance scripts\n\nThe per-post audit inside `seo-blog-writer` catches structural problems before publish. For corpus-wide drift - characters or banlist phrases that crept back across many posts - run [`scripts/audit-corpus.py`](scripts/audit-corpus.py) against your content directory:\n\n```bash\npython3 scripts/audit-corpus.py path/to/your/content/\npython3 scripts/audit-corpus.py content/posts/ --extra \"synergy,best-in-class\"\n```\n\nExits `0` clean / `1` on hits - composes with CI for a pre-deploy drift gate.\n\n## Glossary auto-link\n\n`seo-blog-writer` Step 7i (optional) pipes the draft HTML through [`scripts/inject-glossary-links.py`](scripts/inject-glossary-links.py), which wraps the first mention of each known technical term in an internal link to its definition page and writes a `data-definition` attribute for hover tooltips. Schema and starter file in [`skills/seo-blog-writer/references/glossary-schema.md`](skills/seo-blog-writer/references/glossary-schema.md); a self-contained tooltip-rendering snippet for your site `\u003chead\u003e` is at [`skills/seo-blog-writer/references/decorate.js`](skills/seo-blog-writer/references/decorate.js).\n\n```bash\npython3 scripts/inject-glossary-links.py post.html \\\n    --glossary glossary.json --base-url /glossary/ \u003e post.linked.html\n```\n\nThe injector handles the awkward edges automatically: first-occurrence-only per post, longest-alias wins, skips headings / code / tables / blockquotes / TL;DR, and rejects matches embedded in identifier-like compounds (`user-agent` won't match `agent`, `@scope/ai-seo-mcp` won't match `mcp`). You bring the glossary file and the definition pages; the injector handles the linking.\n\n## Why platform-agnostic?\n\nThe writing pipeline (research, classify, draft, scrub, AI-SEO audit, JSON-LD generation) is the hard part. The publish step is glue. Coupling the two means you're locked into one CMS forever - and if you move from Ghost to WordPress, you rewrite the whole skill.\n\nThis repo separates them. The writer produces a stable bundle (`\u003cslug\u003e.draft.html`, `\u003cslug\u003e.schema.html`, `\u003cslug\u003e.metadata.json`) and the adapter ships it. Add Webflow, Sanity, or Strapi in an afternoon without touching the pipeline.\n\n## License\n\n[MIT-0](LICENSE) - public domain equivalent. Use, modify, redistribute without attribution.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAutomateLab-tech%2Fpublishing-skills","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAutomateLab-tech%2Fpublishing-skills","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAutomateLab-tech%2Fpublishing-skills/lists"}