Blog Draft

Draft a blog post for codyanthony.dev/blog/ from an approved blog-plan blueprint. Executes the motivating question, violated expe…

codyanthony updated 1mo ago
Claude CodeGeneric
View source ↗
---
description: Draft a blog post for codyanthony.dev/blog/ from an approved blog-plan blueprint. Executes the motivating question, violated expectation, architecture, reader movement, evidence map with collision events, personal-tone voice, and ai-antipatterns style guide into a ready-to-merge draft. Interactive flow with branch management, proposals, series support, deterministic-script validation, and optional commit/deploy.
version: 1.2
---

---

# /blog-draft

Executes an approved blueprint from `/blog-plan` into a ready-to-merge draft. The motivating question, violated expectation, central claim, architecture, reader movement, anchor story, evidence map with collision events, beat outline, opener shape, working title, slug, and links are already decided and validated in the plan. This command does not re-plan. Eight phases: Setup → Blueprint → Proposals → Compose → Validate → Review → Save → Ship. Each phase gates on user confirmation; the deterministic script runs before LLM judgment during validation.

> **Running blog-draft v1.2** — Skill load + verification gate → branch management → load the blueprint (`.claude/plans/{slug}.md`) + confirm remaining metadata → confirm proposals (title, slug, blueprint summary, tags) → compose direct to file → deterministic + LLM validation → user review → deterministic save gates → optional commit/deploy.

> Run `/blog-plan` first. It produces the blueprint this command consumes. Starting here without one is only for a simple post with one obvious example; anything with real architecture should be planned first.

Print the banner above verbatim before doing anything else. Then print:

> Type `cancel` at any point to exit. Files already written will be preserved with `draft: true` in frontmatter — re-run `/blog-draft` on the same slug to resume.

## Dependencies

**Required skills (must load before drafting begins):**

- `.claude/skills/ai-antipatterns/SKILL.md` — universal negative style guide (canonical)
- `.claude/skills/personal-tone/SKILL.md` — voice, brand alignment, audience layering
- `.claude/skills/blog-post-framework/SKILL.md` — three-beat content checks, opener shapes, structural integrity
- `.claude/skills/blog-checklist/SKILL.md` — pre-publish gates
- `writer-context` (**global skill, not in this repo**) — verified work history, role specifics, NDA/proprietary reference guidance, common overclaims to refuse. Personal to the writer, so it lives at `~/.claude/skills/writer-context/` rather than in the repo; load it by name via the Skill tool.

**Loaded conditionally (in Phase 1b if the blueprint marks the post series-participating):**

- `.claude/skills/series-blocks/SKILL.md` — intro/navigation block templates

**Required scripts:**

- `scripts/check-blog-prose.mjs` — deterministic prose validation

OG images are no longer generated as a build step: the social card is rendered
on demand by the `/og/[slug].png` endpoint and cached to R2 on first scrape (see
Phase 6). No `generate-blog-og.mjs` / static PNG.

**Required tools:** Read, Write, Bash, Edit. Bash for git operations, script invocation, file existence checks, and `pnpm astro check`.

---

## Phase 0: Setup

### 0a. Skill loading and verification gate

Load the project-local skills (`ai-antipatterns`, `personal-tone`, `blog-post-framework`, `blog-checklist`, and conditionally `series-blocks`) via Read at their `.claude/skills/<name>/SKILL.md` paths — project-local auto-discovery via the Skill tool can be session-dependent, so Read is the reliable path for these. Load `writer-context` via the Skill tool **by name**: it is a global, writer-personal skill (`~/.claude/skills/writer-context/`) that lives outside the repo, and global skills surface reliably by name. If `writer-context` fails to load, stop and report — do not draft claims about the writer without it.

Confirm each skill is loaded by listing one key rule from each in this format:

```text
Skills loaded:
  [x] ai-antipatterns — "Zero em dashes in prose (description lists / link lists exempt)"
  [x] personal-tone — "Audience layering: peers primary, recruiters always reading too"
  [x] blog-post-framework — "Three beats are content checks, not section templates"
  [x] blog-checklist — "Deterministic gate runs check-blog-prose.mjs before LLM judgment"
  [x] writer-context — "Refuse 'founding writer for ROSA' (he joined post-GA); refuse 'inherited' framing for AWS XML migration"

Do not proceed past this gate until all five skills are confirmed in context. If any failed to load, report which one and stop.

0b. Branch management

Detect current branch:

CURRENT_BRANCH=$(git -C . branch --show-current)
echo "Current branch: $CURRENT_BRANCH"

If CURRENT_BRANCH is main: drafting on main is not allowed without explicit override. Prompt:

Current branch: main

Drafting on main is not recommended — feature branches keep production
deploy safety and let you preview without affecting the live site.

Options:
  setup     Create a feature branch (named blog/wip-{YYYY-MM-DD}; renamed to blog/{slug} in Phase 2)
  continue  Proceed on main (you'll need to manage commits and deploy carefully)
  cancel    Exit

Wait for response.

  • setup: if working tree has uncommitted changes, prompt stash / commit / discard / cancel. After resolution, run:

    git -C . checkout main
    git -C . pull origin main
    git -C . checkout -b "blog/wip-$(date +%Y-%m-%d)"
    

    This branch will be renamed to blog/{slug} in Phase 2 once the slug is chosen.

  • continue: proceed on main, print warning.

  • cancel: exit.

If CURRENT_BRANCH starts with blog/: existing feature branch. Ask:

On existing feature branch: {branch}

Options:
  continue  Use this branch (draft will save to this branch)
  new       Create a new blog/wip-{date} branch off main
  cancel    Exit

If CURRENT_BRANCH is any other branch: ask:

On branch: {branch}

Options:
  stay      Stay on this b

Maintain Blog Draft?

Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.

[Blog Draft on getagentictools](https://getagentictools.com/loops/codyanthony-blog-draft?ref=badge)