Engineering Notes

Hub-and-spoke SEO for comparison pages — fielding ‘alternative’ search intent from multiple angles

The WordPress maintenance space has several decade-old incumbents — ManageWP, MainWP, WP Umbrella, InfiniteWP. Building a new entrant means inevitably fielding queries like “ManageWP alternative” and “WordPress maintenance tools comparison” — search intent that names a competitor or the category itself. To handle that intent carefully, the LP runs a hub-and-spoke comparison structure. Here’s how it’s built and why. What hub-and-spoke means A hub-and-spoke pattern places one central page (the hub) and multiple related sub-pages (spokes) in a radial arrangement. The naming follows airline hub airports: the hub is the overview, the spokes are the per-item deep dives. In an SEO context, that maps neatly onto search intent: broad overview …

Read more
WordPress Maintenance

Playwright versus WordPress’s ‘admin email confirmation’ screen — how automation can clear the 6-month gate

If you drive the WordPress admin via Playwright for long enough, one day a screen you’ve never seen before will appear after login, and everything downstream stops working. Is admin@example.com still the correct admin email address? [ Yes, the email is correct ] [ Change the address ] That’s WordPress’s admin email confirmation screen. Roughly every six months, after the admin user logs in, this confirmation screen gets injected — standard behavior since WP 4.9. A human just clicks once. An automation script can’t see it without explicit handling. Why automation gets stuck A straightforward Playwright login looks like: page.fill(‘#user_login’, user) page.fill(‘#user_pass’, pwd) page.click(‘input[type="submit"]’) page.wait_for_load_state(‘domcontentloaded’) # Assumes we’re on the …

Read more
WordPress Maintenance

When WP admin shows a plugin update but WP-CLI doesn’t — making automation see proprietary updaters

You open the “Updates” page in WordPress admin and see that Elementor Pro / ACF Pro / vk-blocks-pro have updates available. Then you run wp plugin update –all from your automation, and those exact plugins don’t update. The asymmetry — “the admin sees it; WP-CLI doesn’t” — traces back to how WordPress detects updates and how premium plugins layer proprietary update mechanisms on top of that. Here’s the mechanism and how an automation tool can adapt. WordPress update detection is held by a transient cache WordPress doesn’t decide “is there an update?” on every request. It caches the answer in the wp_options table as a transient, valid for up to …

Read more
WordPress Maintenance

Solving ‘Permissions are too open’ from inside the app — auto-diagnosing and auto-fixing SSH key permissions

Almost every user new to SSH hits this wall: WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0644 for ‘/Users/…/id_rsa.pem’ are too open. This private key will be ignored. They placed the key in ~/.ssh/, entered the path into the SSH settings, and clicked Connect — only to see this. The fix is a single command (chmod 600 ~/.ssh/id_rsa.pem), which is obvious to anyone familiar with SSH but the biggest stumbling block for users who don’t open a terminal. Here’s the design behind solving this inside the app — diagnose, confirm, then auto-fix — and how the phases broke out. Why OpenSSH demands 0600 OpenSSH (and paramiko, which mirrors the same check …

Read more
WordPress Maintenance

‘not a valid OPENSSH private key file’ — building a compat layer for seven SSH private-key formats

If you wire SSH into WordPress maintenance automation, you’ll meet this error sooner or later: SSHException: not a valid OPENSSH private key file “I configured the key file — why?” is the usual reaction. Tracing several real SSH-connection-test failures, the root issue becomes clear: paramiko alone can’t read SSH private keys outside the OpenSSH format. In production, hosting providers and key-generation tools produce different formats, and paramiko’s standard loader rejects many of them. Here’s the design of a “seven-format compat loader” we built to handle this. Far more SSH key formats than you’d guess “SSH key” usually conjures up —–BEGIN OPENSSH PRIVATE KEY—–, but in practice the keys you receive …

Read more
WordPress Maintenance

Renaming a site without losing its data — separating display name from a stable identifier

A client asks you to rename a site from acme-staging to the production name acme. The moment you rename it in the app, the DB backups, screenshots, and thumbnails you had been collecting all appear to disappear. The files are still on disk, but the new directory is empty. The data hasn’t carried over as “the same site.” It’s a trap you can fall into on day one, and we did — with our original design. Here’s how we redesigned things so renames don’t orphan data. Why the data appears to disappear — the site name was the key The original design of WP Maintenance Manager decided file locations based …

Read more
Engineering Notes

Distributing a Python desktop app on Windows and Mac — the full release pipeline

WP Maintenance Manager ships from a single Python codebase to both Windows and macOS. “Python is cross-platform — write once, run anywhere,” the saying goes. The reality is that the distribution pipeline is completely separate per OS, each with its own pitfalls. PyInstaller / Inno Setup / Apple Notarization / eSigner — the release cycle is a combination of OS-specific toolchains. Here’s the full picture, plus what to watch out for at each step. (The choice of internal architecture, Flask + browser UI, is covered separately in why we built a desktop app on local Flask + browser UI; this post is about distributing that architecture across two operating systems.) …

Read more
Engineering Notes

Why we built a desktop app on local Flask + browser UI instead of PyQt or Electron

When you double-click WP Maintenance Manager, it opens a browser tab — and the entire UI lives inside that tab. No native window is created. It’s an unusual structure for a first-time user, and the natural question is: “why a browser?” That choice was an intentional design decision when building a Python desktop application. Here’s the comparison that led to it, and the side effects of the choice. Four realistic options For a WordPress maintenance automation tool, four implementation styles were practical: Approach UI Distribution size Dev cost Per-OS extra work Native (Swift / WPF) OS-native windows Small–medium High (separate impl per OS) Heavy PyQt / PySide Qt widgets Medium …

Read more