Skip to content

Add blog-post CLI and ship cli-tools as a moshcode plugin marketplace - #5

Merged
ralyodio merged 1 commit into
masterfrom
blog-post-tool
Aug 16, 2026
Merged

Add blog-post CLI and ship cli-tools as a moshcode plugin marketplace#5
ralyodio merged 1 commit into
masterfrom
blog-post-tool

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Why

The blog at ~/public_html/blog has no build step — writing a file is
publishing — so every convention lives only in the existing files, and nothing
catches a mistake before it goes live.

That bit us: three posts were dated 7–10 hours in the future, which pinned
them above every real post in feed.xml and caused readers that filter future
items to drop them. The feed looked like it had stopped updating while every
file on disk looked perfect.

What's here

blog-post encodes the conventions so a new post cannot quietly get one wrong:

  • picks the next NNN-post.html
  • renders the smolweb-valid template (explicit <html lang>,
    <meta http-equiv="Content-Type"> rather than a bare <meta charset>, every
    <p> closed) with the AI-drafting acknowledgment
  • splices the entry into the hand-maintained index.html
  • runs build-feed.mjs

It refuses a future date unless you pass --allow-future, requires the
description that becomes the RSS summary, and writes with the wx flag so two
concurrent runs cannot pick the same number and silently lose a post.

blog-post check reports exactly what breaks the feed in silence: missing or
unparseable <meta name="date"> (the generator skips those posts without a
useful message), future dates, empty descriptions, missing <h1>. Non-zero exit,
so it works as a pre-publish gate.

Plugin marketplace. The repo now exposes /blog:post, /blog:check,
/blog:list and /blog:feed in moshcode:

moshcode plugin marketplace add profullstack/cli-tools
moshcode plugin install blog@cli-tools

Testing

11 unit tests (node --test), covering the template shape, attribute escaping
of a hostile description, index splicing idempotency, every lint rule, and the
concurrent-create race.

Verified against the real blog: blog-post check reports clean and
blog-post list reads all 11 posts.

🤖 Generated with Claude Code

The blog at ~/public_html/blog has no build step — writing a file is
publishing — so its conventions live only in the files already there and
nothing catches a mistake before it is live. Three posts were recently
dated 7-10 hours in the future, which pinned them above every real post
and made feed.xml look like it had stopped updating.

blog-post encodes the conventions: next NNN-post.html, the smolweb-valid
template with the AI-drafting acknowledgment, the index.html entry, and a
build-feed.mjs run. It refuses a future date unless forced, requires the
description that becomes the RSS summary, and writes with 'wx' so two
concurrent runs cannot land on the same number and lose a post.

`blog-post check` reports what silently breaks the feed — missing,
unparseable or future dates, empty summaries, missing h1 — and exits
non-zero, so it works as a gate.

Also adds .claude-plugin/ so the repo is an installable marketplace,
exposing /blog:post, /blog:check, /blog:list and /blog:feed.

Additive: no existing file changes except 48 new lines of README.
14 new tests (66 total), typecheck clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

2 finding(s)

MEDIUM: 2

Severity Rule Location
MEDIUM insecure-temp-file test/blog.test.ts:56
MEDIUM insecure-temp-file test/blog.test.ts:57

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit e3882eb into master Aug 16, 2026
4 checks passed
@ralyodio
ralyodio deleted the blog-post-tool branch August 19, 2026 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant