12. repo-publisher + scsiwyg: the git-to-blog pipeline
#use-case#repo-publisher#scsiwyg#orchestrator#publishing
David Olsson
Two skills. One publishes. One decides what to publish.
scsiwyg is the platform skill โ it knows how to talk to scsiwyg.com, manage posts, handle newsletters, and navigate the MCP tool surface. It does exactly one thing: give Claude a fluent interface to a headless blog.
repo-publisher is the orchestration skill โ it reads your git history, analyses what changed, scores story candidates, writes drafts, and hands finished posts to scsiwyg to publish. It does exactly one thing: turn software development activity into editorial decisions.
Together they form a complete pipeline from commit to published post. Separately, each has standalone value.
The division of labour
repo-publisher handles everything upstream of publishing. scsiwyg handles everything at and after the publish call. Neither skill reaches into the other's domain.
scsiwyg: the platform skill
scsiwyg.com has no web editor. There is no dashboard for writing posts. All content management happens through MCP tool calls from Claude Code โ and the scsiwyg skill is what makes those tool calls feel like natural language.
The full tool surface:
| What you say | What happens |
|---|---|
| "list my posts on [blog]" | list_posts |
| "publish a post about X" | publish_post with slug, title, body, tags, excerpt |
| "update the intro on Y" | get_post โ edit โ update_post |
| "rename the slug" | update_post with new_slug |
| "set the date to last Tuesday" | update_post with ISO date |
| "send a test newsletter to me" | test_newsletter |
| "show my subscribers" | get_subscribers |
| "delete this post" | delete_post with confirm: true โ always asks first |
The skill carries the platform's quirks so you don't have to memorise them:
- Posts sort by
publishedAt(descending) โ ordering requires setting dates explicitly update_postonly changes fields you explicitly provide โ safe partial updatesdelete_postis permanent and requires user confirmation โ no silent deletes- Always specify
usernamewhen targeting a blog โ prevents accidents on the default
Standalone value
You don't need repo-publisher to use scsiwyg. If you write posts manually โ drafting in Claude, publishing with publish_post โ scsiwyg handles that workflow entirely on its own. The skill is useful anywhere you want Claude to manage a blog.
repo-publisher: the editorial intelligence
repo-publisher answers a different question: given everything that's happened in this repo, what's worth writing about?
It maintains a stateful picture of your project in .blog-state/ at the repo root. Every run updates this picture. Between runs, nothing is forgotten.
The six phases
Phase 1 โ Read State
Load .blog-state/state.json. Read git log since the last run. Compute the changeset: what files changed, what dependencies shifted, what branches moved.
Phase 2 โ Analyse
Run analysis pipelines on what changed. Code files touched? Run a code-audit snapshot. Dependencies updated? Run infra-cost. Security-relevant files modified? Run security posture. Results cache in .blog-state/analysis/.
Phase 3 โ Decide This is the editorial core. Every potential story gets scored:
- Significance: how much changed, how important is it to the project
- Novelty: have we written about this before? is this genuinely new?
- Timeliness: is this relevant now, or will it be stale by the time someone reads it?
- Audience fit: does the target blog's readership actually care?
Stories that don't clear the threshold don't become posts. A dependency bump is not a post. A major architecture refactor is. The decision engine makes the call โ and the threshold is configurable in config.yaml.
Phase 4 โ Produce For selected stories, generate media first: Mermaid diagrams for architecture changes, before/after tables for metric deltas, diff tables for dependency changes. Then write the post in markdown, embed media, generate an excerpt, assign tags.
Phase 5 โ Publish
Hand approved drafts to scsiwyg. publish_post to the target blog. Append to published/log.jsonl. Update the content ledger in state.json.
Phase 6 โ Save State
Snapshot state.json to history/ with today's date. Update the git baseline. The next run will measure from here.
The .blog-state/ directory
.blog-state/
โโโ state.json # The brain โ project identity, health scores,
โ # git baseline, content ledger, editorial calendar
โโโ config.yaml # Target blog, voice, cadence, publish_mode,
โ # which pipelines to run
โโโ history/ # Date-stamped state snapshots
โโโ queue/ # Drafts awaiting review
โโโ published/
โ โโโ log.jsonl # Append-only record of everything published
โโโ media/ # Generated Mermaid, charts, screenshots
โโโ analysis/ # Cached pipeline outputs
This directory lives inside your repo. It commits alongside your code. Every state change is tracked.
config.yaml: the key settings
target_blog: your-scsiwyg-username
voice: "technical but accessible, first-person, no hype"
publish_mode: draft # draft | auto | propose
cadence: weekly
pipelines:
code_audit: on_change
security: on_change
infra_cost: on_dependency_change
publish_mode: draft means repo-publisher writes posts and queues them โ you review before anything goes live. auto publishes immediately. propose surfaces story candidates without writing โ you pick which ones to develop.
How they connect
repo-publisher treats scsiwyg as a named integration in its configuration:
target_blog: making-scsiwyg
When Phase 5 runs, it calls the same MCP tools the scsiwyg skill exposes: publish_post with the draft's slug, title, body, excerpt, tags, and date. The scsiwyg skill's knowledge of the platform โ ordering behaviour, partial updates, slug conventions โ is available to repo-publisher because both skills share the same Claude Code session.
This is the design principle: skills compose through shared context, not through explicit dependencies. repo-publisher doesn't import scsiwyg. It uses the platform understanding that's already loaded.
Invocation modes
First run in a new repo
"initialize blog state for this repo"
Creates .blog-state/ with a config template, runs project-scanner to build the initial codebase inventory, scans your target blog to populate the content ledger, proposes an opening editorial calendar.
Ongoing workflow
"what should I blog about" โ Phases 1โ3, story candidates only
"run the blog workflow" โ All 6 phases end to end
"draft a post about the new auth system" โ Skip to Phase 4 with a specific topic
"publish the queue" โ Phase 5 on existing drafts
"show blog state" โ Current state.json summary
"what changed since last post" โ Phases 1โ2, change summary only
Automated triggers
For hands-off operation, add a git hook:
# .git/hooks/post-push
#!/bin/bash
LAST_RUN=$(cat .blog-state/.last-run 2>/dev/null || echo "0")
NOW=$(date +%s)
if [ $(( NOW - LAST_RUN )) -gt 86400 ]; then
claude -p "run the blog workflow for this repo" &
echo $NOW > .blog-state/.last-run
fi
Or a weekly GitHub Action:
on:
schedule:
- cron: '0 8 * * 1' # Monday 8am
jobs:
blog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: claude -p "run the weekly blog workflow"
What this pair is actually for
Most developer blogs fail the same way: they're started with good intentions, get two posts in the first week, and then go silent when the next sprint starts. The gap between "I should write about this" and "I have written about this" is exactly the friction these two skills eliminate.
scsiwyg removes the platform friction โ no editor to open, no CMS to navigate, no formatting to fight with.
repo-publisher removes the editorial friction โ no blank page, no "what should I write about", no manual tracking of what you've already covered.
The result: your blog updates when your repo updates. The knowledge in your commits surfaces as posts your audience can find. The work you're already doing gets an audience.
Download
Both skills are available at worksona-repo-publisher-toolkit.netlify.app.
The bundle download includes both repo-publisher/ and scsiwyg/ โ copy both folders to ~/.claude/commands/ and both skills are available immediately in Claude Code.
Made with โฅ in Kelowna, Canada ยท Worksona.io ยท atomic47.co ยท Atomic 47 Labs Inc.