How I automated my content distribution with a DSH plugin I scaffolded myself
Posting is easy. Posting everywhere, consistently, is the hard part.
I wanted a single command that takes one markdown article and pushes it to Dev.to, GitHub (as a gist), and eventually Bluesky and Mastodon — without my ever touching those web editors again. So I built it as a plugin for DSH (DeepSeek Harness), using a scaffolding tool that I published myself.
Here's the story, the 3 pitfalls that cost me the most time, and how you can get the same thing running in about a minute.
Why automate distribution at all?
Writing in public is the cheapest compounding asset a developer has. But cross-posting manually has two failure modes:
- You skip platforms — the "I'll do it later" tab that stays open forever.
- You lose the content graph — each platform becomes a silo with a slightly different version.
A plugin that accepts content + title + [platforms] and returns per-platform status + links removes both. One source, many destinations, audited every time.
What I built
A DSH content-automation plugin (dsh-crosspost) with:
- Platform adapters: Dev.to (real), GitHub gist (real), Bluesky + Mastodon (stubs, next milestone).
- BYOK credentials: your tokens live in your DSH profile config — never in code, no platform approval needed from the plugin author.
-
Error classification: every adapter wraps HTTP in try/catch and returns
auth / rate-limit / bad-requestinstead of a raw stack trace, so an agent can decide to retry or skip per platform. - Parallel orchestration: one platform failing never blocks the others.
The 3 pitfalls that cost me the most time
1. The stale latest dist-tag (the big one)
npm install @deepseek-ai/dsh-tools gives you a stale 0.0.1-rc.1 — the real line lives under the next tag. Wasted an evening debugging failures that were purely "wrong version resolved." Lesson: check dist-tags before installing anything in a fast-moving young ecosystem (npm view pkg dist-tags).
2. Pure ESM + bare specifiers
The plugin must be pure ESM ("type": "module"), built with module: esnext + moduleResolution: bundler. Half my build errors were me fighting CJS habits (require, module.exports) at the boundary.
3. The bundle patch, not a relative path
Deps aren't installed via npm in the profile directory — the profile loader resolves bundle names through node_modules/profile store. Unlearning "relative path == works" was harder than the API calls themselves.
The 60-second scaffold
Instead of hand-writing the plugin skeleton, I packaged everything I learned into create-dsh-content — a scaffold that generates a working, verifying content plugin in one command, then runs --verify (type-check + loader dry-run) until it's green.
What it bakes in: version pins (no stale-tag trap), pure-ESM tsconfig, the cordis patch wiring, BYOK credential plumbing, and a generate → verify → install → publish loop you can dogfood.
The best part: dogfooding it
The final step was using my own published package to generate the very plugin that published this post:
-
create-dsh-content(published to npm) → generatesdsh-crosspost -
dsh plugin add→ loads it into my profile - Agent calls the
dsh_crossposttool → this article + a GitHub gist live
That's the loop I'd recommend for anyone shipping dev tools: dogfood = honest docs. When your instructions mysteriously work, you know they're real.
Links
- Scaffold repo: github.com/buchylx/create-dsh-content-plugin
- Scaffold on npm: npmjs.com/package/create-dsh-content
- This plugin:
dsh-crosspost(multi-platform cross-poster for DSH)
Give the scaffold a try and let me know what your first automated cross-post looks like. 🚀
Top comments (0)