All notable changes are recorded here. This project follows semantic versioning.
substack cover <id> --image X, which replaces a post's hero image without touching a word of its body. It finds the hero node by matchingcover_imageor by position above all text, refuses to overwrite a picture that sits below body text because that is article content, and fingerprints the document to assert exactly one node changed before anything is written.--insert-herocovers posts that never had one.
Agent support, which is what the tool was built for.
substack agent install, which writes this tool's operating instructions into whatever file your coding agent reads: a Claude Code skill, a Cursor rule, or anAGENTS.mdblock. It detects the target, never clobbers rules you already keep, and replaces its own managed block rather than stacking copies on a reinstall.substack agent print, which dumps the instructions without writing anything.--globalonagent install, for Claude Code and Cursor, so every project picks it up.substack audit --json, a machine-readable result with acleanfield an agent or a script can gate on. The exit code matches it.docs/agents.md, replacingdocs/agent-skill.md, with the full agent setup.
- The README leads with the agent path.
doctorprints the setup instructions before anything else when no credentials exist.- A local image skipped because uploads are off is reported separately from one that is actually missing from disk.
First public release. Extracted and generalised from a private publishing harness that has run a real newsletter since July 2024.
push, which turns a markdown file into a Substack draft and writes the id back.update, which rewrites an already published post with no email and no feed bump.audit, which reports what an update would destroy before it destroys it.pull, which downloads live posts as markdown with their images.publish,unpublish,schedule, andunschedule.noteandnote-deletefor Substack Notes, with image attachments.render, an offline markdown to ProseMirror conversion that sends nothing.initanddoctorfor setup and diagnosis, with id discovery from one API call.list,get,set,delete,templates, andsitemap.- Markdown tables rendered to PNG, because Substack's schema has no table node.
- Automatic cover upload, used as both the post thumbnail and the template cover slot.
- Slug enforcement, so Substack never invents a truncated public URL.
- Preservation of editor-only blocks across an update, re-anchored by surrounding text.
- 94 offline tests, each pinning a bug that reached a live newsletter.