Skip to content

Releases: mwender/spinupwp-tui

v0.20.1 — README rewrite + Dev Mode fleet scale-up

Choose a tag to compare

@mwender mwender released this 09 Jul 00:43

A docs/quality-of-life release: the README got a lot easier to skim, and Dev Mode's example fleet is big enough now to actually show off the app.

Changed

  • README rewritten for readability. It had grown to 857 lines of dense, multi-paragraph feature bullets — hard to skim for someone landing on the repo. Added a screenshot gallery (real Dev Mode captures of all five main tabs), condensed the Features list to one-liners, and moved all 13 deep-dive "how it works" sections into their own pages under docs/ (linked from the README's short pointer paragraphs). No content was removed, only relocated; RELEASING.md's "Keep the README current" checklist is updated to match the new house style.
  • Dev Mode's example fleet scaled up from 4 servers / 6 sites to 12 servers / ~80 sites / 19 events, generated deterministically (same fleet every run) with a realistic spread of EOL Ubuntu/PHP, Standard WP/Bedrock/non-WP sites, disabled HTTPS, and missing backups — mainly so the new screenshots (and any future ones) show a fleet worth looking at.

Update: bun update -g spinuptui (npm install) or git pull in your checkout (a linked global spinuptui picks it up immediately).

Full changelog: v0.20.0...v0.20.1

v0.20.0 — Clone wizard correctness fixes + dest-picker site counts

Choose a tag to compare

@mwender mwender released this 08 Jul 19:59

Three correctness fixes for the clone wizard, all root-caused from real live incidents, plus a small quality-of-life addition.

Added

  • The clone wizard's existing-server picker now shows each server's current site count. Picking a destination previously showed only provider/region/IP — no sense of how busy a candidate already is. Each row now leads with N site(s).

Fixed

  • The clone wizard no longer routes git-deployed non-WordPress sites through a Bedrock pull. cloneStackFor trusted git.repo alone as "this is Bedrock" — but a git-deployed static site would be routed through composer install/wp-cli anyway, which it can't survive. A conclusive non-WordPress probe (whmcs/laravel/static) now overrides git.repo.
  • The clone wizard no longer silently skips the database for API-mislabeled WordPress sites. Its stack picker read is_wordpress straight from the API, unlike every other view, which corrects that flag against a d probe result. A mislabeled site would default to a files-only pull — filesystem copied, database never touched. The wizard now consults the same probe-corrected classification: probe the site (d) before cloning.
  • wp-cli reads now use the site's own configured PHP version, not the server's system default. wp-cli's shebang resolves through PATH to whichever PHP a server's update-alternatives currently calls default — independent of any site's configured version, and it can be missing extensions that version's CLI never got configured with. This broke the clone wizard's Verify step (v) and the installed plugins & themes view (p) whenever they differed. Verify also now distinguishes "the clone actually differs" from "wp-cli couldn't read one side's database," instead of a wall of misleading ✕ rows.

Notes

  • All three fixes share an operational caveat: probe a site (d) before cloning it so the wizard's Plan step has a corrected classification to consult — an unprobed site falls back to today's heuristics.

Update: bun update -g spinuptui (npm install) or git pull in your checkout (a linked global spinuptui picks it up immediately).

Full changelog: v0.19.1...v0.20.0

🤖 Generated with Claude Code

v0.19.1 — Finish the SpinupTUI rebrand

Choose a tag to compare

@mwender mwender released this 08 Jul 17:26

A docs-only follow-up to v0.19.0 — no app behavior changed.

Fixed

  • Finished the SpinupTUI rebrand in the README and cover banner/social-preview images. The v0.19.0 rename swept the CLI banner, header wordmark, and app chrome, but missed 14 mid-sentence "Spinup" mentions scattered through the README's prose, and the cover banner/social-preview images still spelled out "SPINUP" in block-letter art. Both are fixed now; spinup-sudo (a Keychain service name) and the spinup-tui machine key (a literal SSH key identity) are unaffected — they're real persisted identifiers, not branding.

Update: bun update -g spinuptui (npm install) or git pull in your checkout (a linked global spinuptui picks it up immediately).

Full changelog: v0.19.0...v0.19.1

🤖 Generated with Claude Code

v0.19.0 — Meet SpinupTUI, now on npm

Choose a tag to compare

@mwender mwender released this 08 Jul 14:45

The app has a proper name and a proper install: SpinupTUI, published to npm.

Highlights

  • Install with one command. bun install -g spinuptui puts the spinuptui command on your PATH; update any time with bun update -g spinuptui. No git checkout needed (that path still works for development). Running the bin under Node prints a friendly "install Bun" pointer instead of a crash — the terminal renderer needs Bun's FFI.
  • The app is now "SpinupTUI", and the command is spinuptui. The rename distinguishes the app from the SpinupWP service it talks to (and plain spinup was taken on npm). Nothing else moves — your config stays at ~/.config/spinupwp-tui/config.json.
  • The update hint knows how you installed. The ? About panel shows package installs the bun update -g spinuptui one-liner; git checkouts keep the in-place u (git pull) updater.

Fixed

  • Clone wizard no longer falsely fails a site when SpinupWP is slow to run its add-domain event. SpinupWP serializes events per server, so under a concurrent clone an additional-domain add can queue for minutes behind site-creates — the old 3-minute poll gave up mid-queue, reported "failed on SpinupWP", and aborted the site before any files were copied, even when the event succeeded seconds later. The poll now waits out queueing (30-minute backstop), takes one final look before giving up, and reports a timeout honestly — a per-site retry resumes safely.
  • An honest header badge when a server-connect build is waiting on you. A vanity-site build parked at the manual SSH-key step used to show a perpetual "Connecting…" spinner, as if work were happening. It now says what it wants and where: ○ {server} needs your SSH key — press V.

Notes

  • Source-checkout users: re-run bun run link-global to get the spinuptui command (and bun unlink the old spinup link if you had one).

Update: bun update -g spinuptui — or git pull in your checkout.

Full changelog: v0.18.0...v0.19.0

🤖 Generated with Claude Code

v0.18.0 — Site status column + plugins/themes over SSH

Choose a tag to compare

@mwender mwender released this 07 Jul 22:59
aa3a036

Two additions to the Servers view, plus a stack-detection fix.

Highlights

  • At-a-glance status column. Every site row now shows a fixed-width capability strip — 👤🔑 granted SSH keys, H HTTPS, C page cache, B backups (lit when on, faint · when off), plus linked and ↑N pending updates — aligned into columns across the whole list, with a compact key in the Sites panel title.
  • Installed plugins & themes (p). Press p on a site for its real wp plugin list / wp theme list over SSH: every plugin and theme with its status, current version, and available update (→ 1.2.3) — the detail the API only gives you as bare counts. Read-only; detects the WordPress directory itself, so it works on /public/ and Bedrock installs alike.

Fixed

  • Stack & type follow the d-identify probe, not SpinupWP's flag. is_wordpress is unreliable — false for Bedrock/git sites and for Standard-WP /public/ installs SpinupWP imported as "Generic" — so a real WordPress site could show as app (and its Details "Type" as Generic) even after d detected it. The row tag and Details fields now reflect the detected stack, and the plugins/themes view no longer refuses a misclassified WordPress site.

Update: `git pull` in your checkout (the global `spinup` symlink picks it up immediately).

Full changelog: v0.17.0...v0.18.0

v0.17.0 — per-site deploy keys for Bedrock clones

Choose a tag to compare

@mwender mwender released this 06 Jul 15:53

The clone wizard's Git-access step no longer shares one server key across every Bedrock repo — each site now brings its own read-only deploy key, generated on your machine and installed by SpinupWP as the new site's git identity.

Highlights

  • A unique deploy key per site. GitHub attaches a deploy key to exactly one repository account-wide, so the old server-key approach stopped working at the second Bedrock repo cloned to a server ("key is already in use"). The Git-access step now generates a fresh keypair per repo, puts the public half on the repo (auto via gh, with the title spinup-<domain>@<server>), and sends the pair with the site create — clone as many Bedrock repos to one server as you like.
  • Manual path included. No gh, or a repo off GitHub? The step shows each repo's generated key: o opens the repo's deploy-key settings page, and the new y copies the key to your clipboard.
  • Private keys stay private. The pair lives in memory for the length of the wizard, is never written to config, and is registered with the clone log's redaction.

Notes

  • Proven live end to end against a temporarily private repo where only the fresh per-site key could grant access — SpinupWP used it for the create-time clone and the full Bedrock clone passed.
  • Keys already added by older versions keep working; they're simply no longer reused for new sites.

Update: git pull in your checkout (the global spinup symlink picks it up immediately).

Full changelog: v0.16.1...v0.17.0

🤖 Generated with Claude Code

v0.16.1 — alert toggle covers every monitor

Choose a tag to compare

@mwender mwender released this 05 Jul 14:03

A patch release for the alert wiring shipped in v0.16.0: toggling a notification provider from the site-monitoring overlay now reaches every monitor Spinup registered for the site — including the Redis sentinel.

Fixed

  • Alert wiring (n) covers all of a site's monitors. The toggle worked from a hardcoded monitor list that predated the Redis sentinel, so silently skipped the {server} redis check — "now alerts for 2 monitors" on a server that has 3. Monitors are now collected by convention from the saved refs, so the Redis sentinel — and any monitor kind added in the future — is wired automatically. If you toggled a provider on before this fix, open n again: it shows ◐ some monitors only, and one attaches it to the rest.
  • The server-create wizard's monitor step no longer drops previously saved Redis/front-page monitor references when re-run.

Update: git pull in your checkout (the global spinup symlink picks it up immediately).

Full changelog: v0.16.0...v0.16.1

🤖 Generated with Claude Code

v0.16.0 — Site monitoring: fingerprints, a doctor, and a Redis sentinel

Choose a tag to compare

@mwender mwender released this 04 Jul 23:46

We've engineered a monitoring solution that's state-of-the-art for SpinupWP fleets — per dollar and per gram of installed weight. Zero agents, zero SaaS, nothing installed on your sites: every check runs from Uptime Kuma and a one-line cron you already had. The parts are commodity; the composition is the invention — each check deliberately watches either through the page cache (is the right thing being served?) or around it (is the machinery behind it alive?).

Highlights

  • The front-page check (f). The page cache can serve the wrong page while HTTP stays 200 — two production incidents showed a search-results template where the home page belonged, and every up/down monitor stayed green. Instead of a hand-picked headline keyword (which breaks the day someone edits the copy), Spinup reads your healthy front page, derives a template-identity fingerprint from what WordPress itself stamps into the markup (class="home, page-id-N, …), proves it discriminates against a throwaway search render, and registers the Kuma keyword monitor for you — at your chosen window (5m–1h; the check is served straight from the page cache, so it costs the site nothing). Red shows as WRONG PAGE SERVED in Details. Re-running f recalibrates the same monitor in place — history survives a redesign.
  • The site doctor (d). Read-only, zero setup, works without Kuma. It fetches your page twice — once normally, once with the cache-bypass cookie — and lets the server's own fastcgi-cache: HIT/BYPASS headers prove which layer answered each request, then compares template identity between the two: "the cache is lying" becomes a demonstrated fact with a copyable runbook, not a hunch. It also knocks on the wp-admin door (the login page — never cached; Bedrock's relocated /wp/ login handled; protected logins report "can't judge", never a false alarm).
  • The partial-outage verdict. The nastiest failure shape we found — verified live: with SpinupWP's default object-cache drop-in, a dead Redis is fatal (HTTP 500) for every request that misses the page cache. Cached pages keep serving 200, so visitors look fine while wp-admin, logged-in users and everything dynamic is broken — and page-watching monitors sleep through all of it. The doctor now diagnoses it explicitly (a PHP fatal in a plugin/theme produces the same signature and is caught the same way, including admin-only fatals via the door probe).
  • The Redis sentinel. One per server, riding the existing heartbeat cron: redis-cli ping every minute, pushed to its own {server} redis monitor that alerts independently. Registered by a/R on a vanity site — after probing that Redis actually answers on that box — and its token rotates with r like every other secret. Given the fatal-on-cache-miss behavior above, this one-minute sentinel is the primary detector for a real partial outage.
  • Alert wiring (n). Spinup detects the notification providers configured in your Kuma — by name, not assumed — and shows whether each is attached to this site's monitors ( all / some / none); toggles a provider across all of the site's checks at once, editing monitors in place. Creating the provider (bot tokens etc.) stays in Kuma; wiring it to sites now lives in Spinup.
  • M everywhere. The site-monitoring overlay opens with capital M from Servers, Stacks and Search alike (Servers keeps lowercase m too) — one muscle-memory key across the app.

Fixed

  • A finished operation's message no longer hides the monitoring overlay's action menu for the rest of the session — results show above the menu, and the overlay always reopens fresh.
  • The ?/i help overlays could deadlock open if triggered in the beat before a view's text input grabbed focus; dismissal now runs first.

Notes

  • Every claim above was verified against live infrastructure before shipping: body-class fingerprints on the incident-prone production sites, fastcgi-cache headers on two servers, the drop-in's exception handling read from source, and a full stop-Redis/watch-it-alert/restart cycle on the test box.
  • Honest boundary: this is not APM-grade observability — it's the meaningful subset for this stack, at effectively zero cost and zero installed weight. Checks that can't prove something say "can't judge" instead of guessing.
  • A per-site health endpoint (deeper internals: eviction thrash, graceful-mode inventory, DB health) is designed and deliberately parked for a future release.

Update: press u in ? Help, or git pull in your checkout. No new dependencies.

Full changelog: v0.15.0...v0.16.0

🤖 Generated with Claude Code

v0.15.0 — rotate monitoring secrets in place

Choose a tag to compare

@mwender mwender released this 04 Jul 13:20

Record your screencast with the push URL on screen, then press one key and it's dead: r rotates a vanity site's monitoring secrets in place — no monitor deleted, no history lost. Plus vanity sites now stand out in the Servers tab.

Highlights

  • Rotate monitoring secrets (r in the m overlay). Two secrets can end up on screen in a recording: the Kuma push URL (Kuma displays it in full) and the health key in a ?format=json&key=… URL. r on a vanity site mints fresh ones and kills the old ones immediately — a new push token is edited into the existing push monitor (same monitor row: heartbeat history, uptime stats and notification wiring all survive), the heartbeat cron is rewritten over SSH, a new health key is re-seeded into the page, and any Kuma monitor URL still embedding the old key is re-keyed automatically. Confirm-gated; expect at most a missed beat or two, absorbed by the monitor's retries.
  • Works without Kuma too. Unconnected, r still rotates the health key (there's no push monitor to edit) and says so.
  • Vanity sites stand out in the Servers tab. The server's own vanity/health page is marked with a brand-green tint in the sites list — with servers named like domains (the vanity convention), it otherwise hides among regular sites.

Notes

  • Rotation never deletes or re-creates monitors — it uses Kuma's edit API, so dashboards, status pages and notification assignments keep pointing at the same monitor.
  • The old push URL stops accepting beats the moment the rotation lands; the old health key starts returning 403 as soon as the page is re-seeded.
  • Acceptance-tested against a live Uptime Kuma instance and a real server: history intact across rotation, old secrets verified dead, new heartbeat flowing within a minute.

Update: press u in ? Help, or git pull in your checkout. No new dependencies.

Full changelog: v0.14.0...v0.15.0

🤖 Generated with Claude Code

v0.14.0 — Uptime Kuma integration

Choose a tag to compare

@mwender mwender released this 04 Jul 00:03

Spinup meets your monitoring: vanity pages become health endpoints any uptime tool can watch, and with an Uptime Kuma connection the monitors set themselves up — load graphs, dead-man's-switch heartbeats, sparklines in the Health view, and maintenance windows around reboots.

Highlights

  • Vanity pages double as health endpoints. The page the V wizard seeds now answers ?healthz — plain 200 ok, or 503 when 1-min load per core tops 2 or disk free drops under 10% — so any plain HTTP monitor gets resource alerting from the status code alone. ?format=json&key=… serves full metrics (load, cores, uptime, disk, memory, PHP version) behind a per-site key generated at seed time. Tool-agnostic by design; recipes in docs/uptime-kuma.md.
  • Site monitoring (m). Press m on a site to wire it into your own Uptime Kuma (one-time connect with a real login check; 2FA supported — the code is asked exactly once, then a stored token covers every later session). Vanity sites get the full treatment: a healthz monitor plus a load push monitor fed by a once-a-minute cron — Kuma graphs server load, and a silent cron (server down, cron dead, egress broken) flips the monitor. Regular sites get a homepage monitor with cert-expiry alerts; client site files are never touched. R refreshes an existing vanity page to the current version — with or without Kuma.
  • The V wizard registers monitors automatically. With Kuma connected, two new steps after publishing the page: register both monitors, install the heartbeat cron. They auto-skip when Kuma isn't set up, and a monitoring failure is skippable — the site is already live.
  • Kuma status flows back into Spinup. A Monitor row per site in Details, a ▼ N monitors down header badge (silent when all's well), and a Monitor panel in the Health view (h) with 24h uptime, response-time and server-load sparklines — real history that survives reopening the view.
  • Reboots never page you. Firing a reboot first wraps the server's monitors in a Kuma maintenance window and removes it when the reboot settles. Strictly best-effort: Kuma being unreachable never blocks the reboot.

Notes

  • Monitors are adopted, not duplicated: same-named monitors in Kuma are reused, a hand-made push monitor keeps its token, and recorded ids are re-verified against Kuma before being trusted (deleting a monitor there and pressing a re-creates it).
  • Load pushes are sent ×100 as integers (some Kuma builds silently drop float pings); Spinup's views scale them back.
  • Connection lives in config.json (0600) or via SPINUP_KUMA_URL / _USERNAME / _PASSWORD. Speaks Kuma's socket.io API; handles both 1.x and 2.x monitor schemas. Dev Mode never touches a real Kuma.
  • New dependency: socket.io-client — run bun install after updating.

Update: press u in ? Help, or git pull in your checkout, then bun install (one new dependency). The global spinup symlink picks it up immediately.

Full changelog: v0.13.0...v0.14.0