@andersonfda/springy
v0.16.1
Published
Open-source content automation — one idea into a coordinated post for every platform, in your voice.
Maintainers
Readme
springy
Turn one idea into posts for every platform — in your voice, critiqued, queued, tracked.
Springy is an open-source content automation stack. You write an anchor essay (or let it draft one from a ranked opportunity); it cascades platform-specific derivatives for LinkedIn, X, Bluesky, and Threads by default — plus Medium / Dev.to / Reel / TikTok as opt-ins. Each draft is critiqued against your brand voice, humanized, and dropped into a publish queue. API where possible, browser automation where not.
Local-first. Bring your own model — Anthropic Claude or OpenAI GPT, swappable via SPRINGY_LLM_PROVIDER. No SaaS required.
Status
Alpha. The architecture is audited and working, but the developer experience is rough and error messages assume you know the code. Not yet recommended for non-technical users. Contributors welcome.
If you're a technical alpha tester, start here:
docs/TESTER_GUIDE.md— copy-pasteable golden path with safety checklist.docs/PLATFORM_SUPPORT.md— readiness label per platform (default text / SEO / video / browser fallback).docs/KNOWN_LIMITATIONS.md— explicit list of what isn't yet done (hosted OAuth, video rendering, automated engagement polling, queue-backend swap).
Community / contributor operations:
SUPPORT.md— where to ask for help, what to include, and how to route reports.CONTRIBUTING.md— local setup, PR flow, and contribution expectations.ROADMAP.md— shipped / beta focus / next / later / not planned.docs/COMMUNITY_OPERATIONS.md— GitHub, Discord, beta, triage, and release operating model.docs/DISCORD_LAUNCH_KIT.md— Discord server setup, roles, pinned posts, and moderation playbooks.GOVERNANCE.md— current maintainer model and how ownership expands.
What it actually does
| Stage | What happens |
|---|---|
| Discovery | Bring-your-own briefings: drop markdown files into data/briefings/ (and optionally data/trending/), then run springy opportunities:rank to score them. RSS / HN / GitHub-trending / competitor scrapers are roadmap, not shipped — wire your own ingestion or paste the day's signals manually. |
| Anchor | Generates an essay from the top opportunity. Critiqued against your voice. Humanized. Human-in-the-loop gate. |
| Fan-out | Rewrites the anchor for each platform in parallel. Native style per platform, not copy-paste. Second HITL gate. |
| Media | Generates hero images per platform (Replicate Flux). Reel/TikTok require an MP4 alongside the draft — the Remotion + ElevenLabs render path is on the roadmap, not shipped. Until then, video platforms are opt-in via --platforms reel,tiktok once you've placed a video file in the cascade dir. |
| Publish | Queue drainer. API first, browser automation fallback for auth-broken / no-API platforms. Idempotent, retryable. |
| Learn | When you run springy voice:refresh (manually or as the daily cron job v0.8.10+ installs), engagement metrics already in data/analytics.db are weighted into the voice corpus and prompt-variant scores. The 1h/4h/24h/72h/7d polling cadence is in the schema and the manual springy engage collect command for LinkedIn / Bluesky / Reddit; per-platform automated polling is roadmap. |
9 cascade-complete platform generators ship today (essay, LinkedIn, X thread, Threads, Bluesky, Medium, Dev.to, Instagram Reel, TikTok). The default fan-out is the four text platforms (LinkedIn, X, Threads, Bluesky); Medium + Dev.to are --seo opt-ins; Reel + TikTok are --platforms-overrides until video rendering ships. Publish/engagement clients also exist for Discord, Reddit, Pinterest, Telegram, YouTube, Substack, Rumble, and Quora — some via API, the rest via Playwright. Local SQLite for analytics. LanceDB for voice retrieval.
Quick start
# 60-second offline tour — no keys, no commitment
npx @andersonfda/springy demo
# (the demo will offer to chain straight into init if you want to keep going)
# Install — scaffolds the project and runs an opt-in brand wizard
npx @andersonfda/springy init my-brand
cd my-brand
# Verify the install (offers to auto-rebuild better-sqlite3 + install chromium if needed)
npx springy doctor
# Add a generation provider key to .env. Pick one:
# - ANTHROPIC_API_KEY (default; SPRINGY_LLM_PROVIDER=anthropic)
# - OPENAI_API_KEY (set SPRINGY_LLM_PROVIDER=openai;
# or sign in to ChatGPT via `npx springy auth openai`)
# Plus VOYAGE_API_KEY (strongly recommended for brand-voice RAG).
# OPENAI_API_KEY is also used for Whisper transcription regardless of the
# main provider — it's the audio path, not the generation path.
$EDITOR .env
# Set up a developer portal for each platform (7 browser-guided, 4 terminal, 5 documented)
npx springy setup --list # see all platforms
npx springy setup linkedin # walk through LinkedIn Developer app creation
npx springy setup bluesky # browser-guided app-password flow
# Run OAuth where required (after setup)
npx springy auth linkedin
# After auth/setup, platforms.yaml is auto-flipped to enabled:true.
# Seed your voice corpus — two paths:
# a) Bulk-import past content (RSS feed or local markdown directory):
npx springy voice:import rss https://yourblog.example.com/feed
npx springy voice:import dir ~/old-essays/
# b) Or drop 20+ posts into content/drafts/ manually with status: approved
# Then embed:
npx springy voice:seed
# Run the full cascade for today's top opportunity
npx springy cascade --top
# Drain the queue (dry-run first)
npx springy publish
npx springy publish --live
# See what's working — terminal report or the local dashboard
npx springy report # engagement, top hooks, best hours, evergreen, spend
npx springy evergreen # recycle proven winners (dry-run; --live to enqueue)
npx springy ui # local dashboard at http://localhost:4000Local dashboard
npx springy ui starts a read-mostly ops console at http://localhost:4000 (bound to 127.0.0.1; set SPRINGY_UI_TOKEN if you expose it off-loopback). Pages: dashboard, queue, engagement, hooks (which opening styles drive engagement), variants (the A/B leaderboard), evergreen (proven posts to re-surface), cascades, and costs. It reads your local analytics.db — no cloud, no account.
Costs
Springy itself is free and MIT-licensed. Your bill is whatever upstream providers charge, and nothing else.
| Provider | What it powers | Typical monthly cost for solo use |
|---|---|---|
| Anthropic (Claude) or OpenAI (GPT) | Anchor essay + fan-out + critique loop (one generation provider required; pick via SPRINGY_LLM_PROVIDER) | $5–$40 — depends on cascade frequency and fine-grained critic usage. OpenAI usage is comparable; ChatGPT-subscription PKCE auth via npx springy auth openai is also supported in lieu of an API key |
| Voyage AI (voyage-3) | Brand-voice RAG (strongly recommended; first-run cascades work without it but degrade to brand.yaml rules only) | <$1 for seed + weekly refresh of a few-hundred-post corpus |
| Replicate (Flux) | Hero images (optional, per platform) | $0–$15 — ~$0.05/image; skip if you don't need images |
| ElevenLabs (TTS) | Voice previews + video voiceover (optional) | $0–$22 — free tier covers ~10 min of audio, paid tiers for more |
| OpenAI (Whisper) | Audio-to-essay transcription (optional; separate from generation provider) | $0–$5 — $0.006/min of audio |
A realistic first month: ~$10–30 if you run a daily cascade with voice-RAG + occasional images; ~$5 if you run weekly with no images.
springy costs shows last-30-day spend broken down by provider and caller. springy costs --trace <id> shows the cost of one specific cascade. Spending caps in .env:
CRITIQUE_BUDGET_USD=0.25— per-platform cap; aborts further critique iterations once exceeded.SPRINGY_MONTHLY_BUDGET_USD=20— month-to-date hard cap; refuses to start a new cascade once crossed.
Why
Most content automation is either a linear cron script that produces generic AI slop, or a SaaS black box you can't extend. Springy is the third thing: an opinionated graph with human gates, a brand-voice retrieval layer so it sounds like you, and 14 wired platforms you'd build yourself if you had a year.
It's designed to be the pipeline for a builder in public. It's open source because the pipeline itself is content.
Architecture
See docs/ARCHITECTURE.md. Short version: ranked opportunity → anchor essay (critique loop) → HITL → parallel fan-out (critique loop each) → HITL → draft writer → queue → API/browser publisher → metrics collector → voice-corpus back-edge.
Read docs/QUICKSTART.md to go from zero to your first automated post.
Stable vs. dev
Stable — latest
vX.Y.Ztag onmain. Published to npm. This is what you want.# latest stable: npx @andersonfda/springy init my-brand # pin to a specific version: npx @andersonfda/[email protected] init my-brandDev — HEAD of
mainbetween tagged releases. Everything that's been merged but not yet cut into a release. Expect more churn.Note: the GitHub repo is currently private, so
npx github:andersonfda/springyonly works if you have clone access (i.e. the maintainer). For everyone else, npm is the only public install channel — use the stable path above, ornpx @andersonfda/springy@<version>to pin. Thegithub:path below will start working once the repo is made public.# install from git (main) — requires repo access while private: npx github:andersonfda/springy init my-brand # or a specific tag: npx github:andersonfda/springy#v0.16.1 init my-brand
main is always deployable — CI enforces that. But tagged releases are what get --provenance-signed on npm, so @andersonfda/springy@<version> is the recommended install path unless you're hacking on springy itself.
Release process: docs/RELEASING.md.
Contributing
See CONTRIBUTING.md. The easiest high-value contributions right now:
- Wire a new platform (30–60 min per platform; see docs/ADDING_A_PLATFORM.md)
- Write a new generator for a content type we don't cover yet
- Improve an error message so it tells users what to do next
License
MIT. See LICENSE.
