Skip to content

Latest commit

 

History

History
315 lines (244 loc) · 38.9 KB

File metadata and controls

315 lines (244 loc) · 38.9 KB

Changelog

[1.10] - 2026-04-20

✨ New Features

  • cove trust Command: A one-shot installer that drops Cove's local root certificate into the OS trust store and every NSS database it can find, so Firefox and Chromium stop showing "Not Secure" warnings on *.localhost without hand-rolling certutil commands.
    • Wraps frankenphp trust for the baseline (macOS login keychain, Linux /usr/local/share/ca-certificates + ~/.pki/nssdb + ~/.mozilla/firefox/*).
    • On Linux, auto-installs libnss3-tools / nss-tools if certutil is missing, then walks ~/snap/*/common/.mozilla/firefox/*/cert9.db and ~/snap/chromium/* to inject the root into snap-packaged browsers — a path Caddy's built-in scanner doesn't touch.
    • Idempotent on re-run: existing "Cove Local Authority" entries are removed before the current root is re-added, so rotating the Caddy CA doesn't stack stale copies.
    • cove install calls cove_trust at the end of first setup, so a fresh install is trusted everywhere with no extra step.
  • cove memory Command: A cross-cutting view + editor for PHP memory_limit everywhere it can bite you.
    • cove memory prints a side-by-side report: Cove's own ~/Cove/php.ini, the memory_limit baked into the Caddyfile's frankenphp block, every php binary on PATH (version + loaded ini + live value), and wp-cli's effective PHP.
    • cove memory set <value> writes memory_limit, upload_max_filesize, and post_max_size into Cove's ini (values accept 512M, 2G, or -1 for unlimited), regenerates the Caddyfile so FrankenPHP picks up the new limits, then walks external inis on PATH and offers to update each one individually.
    • New cove_ini_get helper in main makes Cove's ini the single source of truth: regenerate_caddyfile reads the current values at render time instead of hardcoding 512M.
    • cove memory set --yes accepts every writable ini non-interactively for scripted fleet updates.
  • Cove-Branded Landing Page for Plain Sites: cove add --plain now writes a designed index.php that matches the dashboard and landing page palette — Fraunces italic headline, Geist/Geist Mono body, teal accent, and the cove brand mark — instead of leaving an empty directory that serves a 404. The page reads $_SERVER['HTTP_HOST'] and __FILE__ at request time, so it self-identifies no matter which hostname or mapping serves it, and includes a ~-shortened absolute path so users can jump straight to the file they need to edit.
  • Linux cove.service Systemd Unit: cove enable now generates /etc/systemd/system/cove.service alongside the existing mailpit.service, so the whole stack survives a reboot without a manual cove enable on each boot.
    • Runs FrankenPHP as the invoking user (not root), Restart=on-failure with a 2s backoff, and passes PHPRC + HOME so php-cli sees the same ini Cove writes.
    • cove enable stops any ad-hoc FrankenPHP left over from a pre-1.10 install before systemctl takes the listening sockets, and cove disable now stops cove.service first (with a fallback to frankenphp stop for users who never re-ran cove enable).
    • cove install masks the distro-packaged frankenphp.service that ships with the apt package — previously that unit would fight Cove for ports 80/443.

🛠️ Improvements & Changes

  • Adminer 5.4.2 with a Native Cove Skin: The old Catppuccin-derived theme has been replaced with a full redesign matching the dashboard and landing page — warm cream + teal palette in light mode, dark olive + teal in dark mode, Fraunces/Geist/Geist Mono typography.
    • Explicit light/dark toggle in the Adminer header, persisted in localStorage and applied synchronously via a head-injected inline script so there's no theme flash on load.
    • Drag-to-resize sidebar (persisted, clamped 180–480px) so wide table names don't truncate.
    • Cove's AdminerCoveLogin class now overrides head() to inject the pre-paint theme script and adminer.js via \Adminer\nonce(), so the CSP nonce the Adminer core emits lines up with Cove's asset.
    • Stale Catppuccin preview screenshots (adminer-theme/assets/*.webp) removed from the repo.
  • Dashboard — Post-Create Alerts, Spinner, and Smart Errors: After creating a site the dashboard now shows a persistent dismissible alert row with either "Log in to admin" (WP) or "Open site" (plain), so the one-time login URL is one click away instead of buried in the toast that fades in 3.5s.
    • Inline spinner on the create button plus an animated teal progress stripe across the top of the add-row while cove add is running (site creation takes 5–10s; the extra cue makes the wait feel intentional).
    • New-site row now carries the correct size_bytes from the server's inline du -sk measurement, so the size column shows "4.0 KB" immediately instead of until the next refresh.
    • Backend translates known cove add failure signatures into user-facing messages ("Site name is taken", "That name is reserved", "Invalid site name", "WordPress installation failed — check the logs") instead of a flat "An error occurred."
    • Dashboard header pills for db and mail now carry inline SVG icons (barrel database, envelope) that inherit currentColor so they tint correctly in both themes.
    • Inline data-theme bootstrap runs in <head> before any CSS paints, eliminating the first-frame FOUC on cold loads.
  • cove upgrade Now Refreshes the Full Cove Surface: Pre-1.10 cove upgrade only replaced cove.sh + frankenphp + adminer-core.php, which left upgraders stuck with the old Catppuccin CSS, the old Adminer index.php, and whatever memory_limit they'd set in the past.
    • Extracted a shared deploy_adminer_theme helper used by both cove install and cove upgrade. Upgraders now pick up the new Cove skin, the theme toggle, and the resizable sidebar in a single cove upgrade — no reinstall required.
    • Floors Cove's memory_limit/upload_max_filesize/post_max_size at 1G (the fresh-install default) but leaves any user-set value >= 1G untouched, so a user who bumped to 2G stays at 2G.
    • Runs cove reload at the end of the upgrade (via the on-disk binary so the newly-replaced script's functions are in use), so dashboard and Caddyfile changes apply without a second manual step.
  • Scripted Flags on Confirmation-Only Prompts: Following the cove ports --yes fix, the rest of the confirmation-only prompts now accept --force / --yes and auto-promote when stdin isn't a TTY, so dashboard-backed and CI-driven use never deadlocks on gum confirm.
    • cove directive delete <name> [--force]
    • cove proxy add <name> <domain> <target> [--force] (skips the overwrite confirm)
    • cove proxy delete <name> [--force]
    • cove memory set <value> [--yes] (accepts every writable ini in one shot)
    • cove upgrade [--yes] (skips the prompt shown when the local Adminer version can't be parsed)

🐛 Bug Fixes

  • Linux — Pre-1.10 Sites and Reload Lock Were Root-Owned: Before v1.10, Cove sudo-started FrankenPHP on Linux so it could bind 80/443. Every site created from the dashboard, every /etc/hosts edit, the reload lock dir, and the caddy.pid file ended up owned by root — which meant a later user-run cove delete silently failed (with a success message) and a user-run cove reload couldn't reclaim its own lock. v1.10 flips this entirely:
    • cove install runs setcap 'cap_net_bind_service=+ep' on the FrankenPHP binary so it can bind low ports as the invoking user, without sudo.
    • cove enable writes cove.service with User=$current_user, so the systemd-managed process is user-owned going forward.
    • A new heal_cove_state_ownership helper runs at the top of cove_reload and repairs ownership of the reload lock, caddy.pid, and site directories left behind by a pre-1.10 install.
    • cove delete now falls back to sudo -n rm -rf when the site dir is root-owned, and surfaces a real error (with the exact recovery command) instead of silently skipping the delete.
  • Concurrent Reloads Deadlocking Caddy's Admin Server: The dashboard fires reload_server in the background after every site add/delete (shell_exec '…&'), so bulk actions would spawn many concurrent cove reload processes. Two parallel frankenphp reload calls reliably deadlock Caddy's admin endpoint with its 10s shutdown timeout, wedging further reloads and HTTP requests. v1.10 serializes reloads with an atomic lock: first caller does the work, subsequent callers touch a pending marker and exit, and the holder re-runs once if the marker is set — so the final state always converges on the latest Sites listing.
  • Reload Lock TOCTOU Allowing 3+ Concurrent Reloads: The initial mkdir + echo > pid implementation of the reload lock left a window where a competing reload could cat an empty pid file, decide the holder was dead, and stomp the lock — letting two or more reloads run in parallel and race create_gui_file's .tmp writes. Switched to a single lock file opened with set -C (noclobber) so the pid is written atomically with the lock's creation. The cleanup trap is also paired with an explicit rm -f at function end, since the trap was observed not firing reliably under shell_exec('cove reload &').
  • Dashboard Deletes Queued During Reload Were Lost: processDeleteQueue would shift() every item once, await apiPost('reload_server'), and then return — but deletes queued during that await would sit forever, because the next deleteSite() call short-circuited on isProcessingQueue. Wrapped the drain in an outer loop so post-reload enqueues are picked up in the same batch.
  • Adminer Session Warnings on Every Request: The apt php-zts package defaults session.save_path to /var/lib/php-zts/session, owned by the frankenphp user. Since Cove now runs FrankenPHP as the invoking user, that path is unwritable and Adminer emits a session_start(): Failed to read session data warning on every request. The Caddyfile now pins session.save_path to ~/Cove/cache/sessions/ (auto-created by regenerate_caddyfile), so sessions land somewhere the process can actually write to.

[1.9] - 2026-04-18

✨ New Features

  • Redesigned Dashboard: The built-in web dashboard at https://cove.localhost has been fully rewritten to match the Cove landing page.
    • Warm-dark-first palette with a teal accent (oklch(72% 0.12 190) in dark mode), Fraunces/Geist/JetBrains Mono typography, and a new SVG cove/bay brand mark with disc/land/horizon/water/waves/ring layers and theme-aware colour overrides.
    • Single rounded card with a soft elevation shadow, three-tier backgrounds (--bg / --panel / --bg-sunk), and subgrid columns so every WP/STATIC pill, modified stamp, size, and action row lines up across rows instead of sizing independently.
    • Per-site size cache at ~/Cove/cache/site-sizes.json, populated by a new refresh_sizes API action. The dashboard shows cached bytes, auto-refreshes on an empty cache, and exposes a manual ↻ button in the footer.
    • "Last modified" column backed by a modified_at field in list_sites (mtime of public/ falling back to the site dir), rendered as relative time with the full timestamp on hover.
    • Filter input with / focus shortcut (GitHub-style), Esc to clear, and clickable WP/STATIC pills that set a dedicated type: chip for exact-type matching rather than substring.
    • Sort pill cycles name / size / modified.
    • Matched substrings in domain names are wrapped in <mark> so the letters you typed are highlighted as you filter. The site-name portion of each domain is accented in teal while the .localhost suffix stays dim.
    • Optimistic single-flight delete queue: rows pop out instantly, the backend runs deletes sequentially so concurrent deletes can't race on Caddyfile regeneration or /etc/hosts writes, and a single reload fires at the end.
    • Click anywhere on a row to open the site — skipped when text is selected so drag-to-copy still works.
    • Login button uses an inline-grid label/spinner stack so the loading state can't shift neighbouring actions.
    • Snackbar fades in/out (no sliding) and is centered without transform so Alpine's transition styles don't fight CSS centering.
    • Theme defaults to prefers-color-scheme on first visit; the moon/sun toggle cross-fades between two stroked SVGs in a 32×32 bordered button.
    • Inline SVG favicon ships with the dashboard — no extra asset to deploy.
  • Installer --main Mode: install-cove.sh now accepts --main to pull cove.sh from the main branch instead of the latest GitHub release, giving testers a one-liner for verifying unreleased changes.

🛠️ Improvements & Changes

  • cove.sh PATH Hardening: cove.sh now prepends /opt/homebrew/bin, /usr/local/bin, and ~/.local/bin to PATH at the top of the script. Callers with a minimal PATH — launchd plists, systemd units, and the dashboard's shell_exec — can now find gum, wp, frankenphp, and mariadb without per-platform shims.
  • Shared Caddy Start Helpers: New is_caddy_running and start_caddy_service helpers in main. regenerate_caddyfile probes localhost:2019 before reloading and starts Caddy if it's down (the start reads the fresh Caddyfile, so no separate reload is needed). cove enable delegates to the shared helper instead of duplicating the macOS/Linux start block.

🐛 Bug Fixes

  • cove add No Longer Lies About Success on a Stopped Stack: On a stopped stack, cove add used to print "Caddy configuration reload initiated" while the reload silently failed, leaving the new site unreachable until the user noticed and ran cove enable. regenerate_caddyfile now detects a down Caddy and starts it, and the reload itself is no longer backgrounded — we wait for the admin API to return and surface a real error if it fails. The deadlock that originally motivated backgrounding is now handled at the PHP layer (the dashboard's reload_server already backgrounds cove reload via shell_exec '…&').
  • First TLS Request After cove add Hitting tlsv1 alert internal error: On a busy running stack, the old backgrounded reload plus sleep 0.25 returned before Caddy had issued the new hostname's internal-CA cert. cove add now polls the site's HTTPS URL for up to ~2s after reload so the cert is warmed up before the command returns. Happy-path cost is one ~5ms probe.
  • cove db backup Overwriting Previous Snapshots: Backups were always written to ../private/database-backup.sql, so a second run silently clobbered the earlier snapshot. Each backup now includes a YYYYMMDD-HHMMSS suffix so repeat runs accumulate instead of overwriting.
  • Orphan /etc/hosts Entries After cove delete: cove reload appends 127.0.0.1 entries for every site hostname and custom mapping, but cove delete previously only removed the site directory and the custom Caddy directive file — the /etc/hosts lines lingered forever. Delete now reads the mappings file before rm -rf, then uses sudo sed -i.bak -E to strip the matching 127.0.0.1 lines in one pass, only prompting for sudo when entries actually need removing.
  • Dashboard Delete Hanging on Sudo Prompt: The /etc/hosts cleanup inside cove delete used plain sudo sed, which hangs the caller when there's no TTY — notably the dashboard's PHP shell_exec, which was locking up the UI waiting for a password prompt nothing could answer. cove delete now checks [ -t 0 ] and drops to sudo -n otherwise, so it fails fast with a warning instead of blocking the whole delete flow.
  • cove rename Temp File Collisions and Symlink Risk: The old database dump was written to a predictable /tmp/${old_db_name}.sql path, which collides if two renames run in parallel and is a symlink-attack vector on shared systems. Switched to mktemp with a trap EXIT cleanup so the temp file is removed on any exit path, not just the happy path.
  • Shell Injection in cove pull and cove push: Interpolating $remote_path into ssh "cd $remote_path && …" passed shell metacharacters — spaces, semicolons, $(…) — straight through to the remote shell. A path with a space would break the cd; a path with a ; or $(…) would execute arbitrary commands on the remote server. A new shell_quote helper wraps values in single quotes and rewrites interior ' as '\'', and pull/push now route $remote_path and $backup_filename through it at every ssh call site.
  • Installer Prompts Silently Falling Through Under curl | bash: When the installer is run the documented way — bash <(curl -sL https://cove.run/install-cove.sh) — bash's stdin is the piped script, so every gum confirm/choose/input during cove install received a closed stdin and silently fell through. install-cove.sh now wires the child cove install call to /dev/tty when it's readable so the interactive port-conflict and option prompts actually work during the fresh install.

[1.8] - 2026-04-15

✨ New Features

  • Alternative HTTP/HTTPS Ports: Cove can now run alongside other local WordPress tools (Local, WordPress Studio, DevKinsta, MAMP) that already bind 80/443. The installer detects conflicts and offers a menu of alternatives.
    • IPv4 and IPv6 port probing via bash /dev/tcp, so the check works even against root-owned listeners (which lsof can't see from a regular user on macOS).
    • Recommended fallback ports 8090/8453 — picked specifically to avoid the well-trodden 8080/8443/8888/8881 range used by Docker, Lando, wp-env, MAMP, and WordPress Studio.
    • Chosen ports persist to ~/Cove/config and are emitted into the Caddy global block as http_port/https_port. Site blocks continue to use their plain site.localhost {} form — Caddy handles the rewrite automatically.
    • Re-running cove install on a machine with non-default ports saved presents a "Keep current / Switch to default / Pick custom" menu so you can migrate in either direction.
  • cove ports Command: A new top-level command to reconfigure ports at any time, not just during install.
    • Interactive menu by default; accepts --http PORT --https PORT for scripted use.
    • After a port change, walks every WordPress site under ~/Cove/Sites/ and runs wp search-replace --all-tables --skip-plugins --skip-themes to rewrite stored URLs (siteurl, home, serialized content, custom mappings) so existing sites keep working on the new port.
    • Iterates each hostname a site answers on — base domain plus any entries in site/mappings — so extra domains don't get left stale.
    • --dry-run previews the port change and per-site replacement counts without committing anything.
    • --skip-urls changes ports without touching databases, for power users who want to migrate manually.
    • Shows a confirmation list before running (ask-once, not per-site).
    • cove install now also runs this DB migration step when a re-install changes ports with pre-existing WordPress sites on disk.
  • FrankenPHP-Backed wp-cli: Cove now uses FrankenPHP's bundled PHP for both the web server and wp-cli invocations, removing the standalone brew install php dependency entirely.
    • get_wp_cmd routes all wp-cli calls through frankenphp php-cli — one PHP runtime for everything Cove touches.
    • A dedicated ~/Cove/php.ini is written at install time and exported via PHPRC, giving Cove full control of memory_limit, display_errors, and error_reporting without fighting any system-wide /opt/homebrew/etc/php/*/php.ini.
    • cove list, cove db, and cove upgrade also use frankenphp php-cli -r for their inline PHP helpers, so Cove works on a fresh Apple Silicon Mac with zero standalone PHP installed.

🛠️ Improvements & Changes

  • Tailscale Access Serves Sites Directly: cove tailscale enable now serves site files directly from the Tailscale-scoped server block instead of reverse-proxying through the local site.localhost block. This fixes CSS/JS/image loading when a site is accessed from a remote device.
  • Dynamic siteurl/home Override: The bundled captaincore-helper.php MU-plugin now filters option_home and option_siteurl at request time when a site is accessed via a non-.localhost host (Tailscale, LAN, or cove share). Assets resolve against the current host so the page renders correctly, and wp-cli is unaffected.
  • Smarter FrankenPHP Upgrade: cove upgrade now detects how FrankenPHP was installed and uses the right upgrade path — apt or dnf for distro-packaged installs, direct download for static binaries.
  • macOS Services via launchd: Caddy, Mailpit, and the Cove-managed services now run via custom launchd plists on macOS instead of brew services, giving Cove precise control over process arguments and log routing, plus proper auto-restart on crashes.
  • Shared Port Helpers: port_is_free, port_is_own, port_has_conflict, prompt_custom_ports, port_url_for, and update_wp_site_urls_for_port_change are now top-level helpers in main, shared between cove install and cove ports.
  • Cleaner cove add Output: cove add now writes WP_DEBUG_DISPLAY = false into wp-config.php so WordPress doesn't force display_errors back on mid-install, keeping the command output clean. An additional stderr filter strips any remaining Deprecated: lines that leak out of wp-cli's colorizer on PHP 8.5.
  • Readme Overhaul: Major readme refresh, including a new Quick Start section, a "Running Alongside Local, Studio, or DevKinsta" walkthrough, a Troubleshooting section (cert warnings, WSL systemd, port conflicts, DB recovery), and a rewritten Features list that now covers LAN/mobile, Tailscale, Cloudflare share, WordPress migration, and /etc/hosts automation.

🐛 Bug Fixes

  • "Installation Cancelled" No Longer Reads as "Successful": The outer install-cove.sh installer used to print SUCCESS: Cove has been installed successfully! even when the user explicitly cancelled from Cove's interactive prompts. The installer now lets set -e handle the non-zero exit from cove install cleanly, so a real cancel no longer ends with a contradictory success message.
  • Mailpit Install on Fresh Apple Silicon Macs: The upstream Mailpit installer hardcodes /usr/local/bin as its install directory, which doesn't exist on a fresh Apple Silicon Mac (Homebrew lives at /opt/homebrew). Cove now uses brew install mailpit on macOS instead, sidestepping the issue entirely. The upstream installer is still used on Linux, where /usr/local/bin is always present.
  • FrankenPHP Install on Fresh Apple Silicon Macs: The official FrankenPHP installer had the same /usr/local/bin problem — it would silently drop the binary in the current working directory instead of on PATH. Cove now runs the installer from a tempdir and, if the binary ends up there, moves it into $BIN_DIR (e.g., /opt/homebrew/bin) before continuing.
  • PHP 8.5 Deprecation Noise: wp-cli 2.12.0's bundled vendor code (react/promise, php-cli-tools/Colors.php) emits Deprecated: warnings on PHP 8.5 that previously flooded every cove add run — ~50 lines per install, polluting captured output like the one-time login URL. A combination of PHPRC display_errors=0, WP_DEBUG_DISPLAY=false, and a precision stderr filter on the install subshell now keeps output clean while preserving real errors.
  • IPv6-Only Port Listeners Not Detected: The initial version of port_is_free only probed 127.0.0.1, which missed IPv6-only listeners like Python's http.server (which binds :: by default). The helper now probes both IPv4 and IPv6 loopback so a service on either stack is seen.
  • wp --version Validation Loop: install_dependency used to run wp --version as a sanity check after install, which failed when no standalone php was on PATH (wp's shebang is #!/usr/bin/env php). The check now skips that validation step for wp, matching the existing special case for mariadb.
  • Adminer Version Detection on macOS: cove upgrade used Perl-regex grep -oP ... \K to read the installed Adminer version, which only works on GNU grep. macOS ships BSD grep, so detection silently fell back to "unknown" and the upgrade prompt always asked to re-download even when the current version was up to date. Switched to a portable LC_ALL=C sed -nE extraction that pulls the version cleanly from both VERSION="x.y.z" and the @version docblock.

[1.7] - 2026-01-31

✨ New Features

  • Linux & WSL Support: Cove now runs natively on Linux distributions including Ubuntu, Debian, Fedora, CentOS, and RHEL. It also includes full support for Windows Subsystem for Linux (WSL).
    • Automatic OS and package manager detection (apt/dnf/brew).
    • Smart MariaDB service name detection across different distros.
    • WP-CLI --allow-root support for Docker and WSL environments where running as root is common.
  • LAN Access for Mobile Sync: A new cove lan command enables LAN access to your sites for mobile app testing and sync.
    • Assigns a unique port and broadcasts via Bonjour/mDNS for easy device discovery.
    • Includes cove lan trust instructions for installing Caddy's CA certificate on mobile devices.
  • Log Viewer: A new cove log command provides quick access to site logs or the global error log.
    • Supports --follow (-f) flag for real-time log tailing.
  • Public Site Sharing: A new cove share command creates temporary public tunnels using Cloudflare Quick Tunnels.
    • Uses cloudflared (installed on-demand via Homebrew if missing).
    • Generates a random public URL that works until you press Ctrl+C.
  • Tailscale Integration: A new cove tailscale command exposes all Cove sites to your Tailscale network.
    • Auto-detects your Tailscale hostname or accepts a manual override.
    • Assigns unique ports to each site, plus fixed ports for Mailpit (9901), Adminer (9902), and the dashboard (9900).
  • Reverse Proxy Management: A new cove proxy command manages standalone reverse proxy entries.
    • Useful for exposing local services (like AI coding tools) via Tailscale or custom domains.
  • Domain Mappings: A new cove mappings command allows a single site to be served from multiple domains.
    • Mappings are automatically added to /etc/hosts and the Caddyfile on reload.
  • WSL Hosts Helper: A new cove wsl-hosts command (WSL only) displays PowerShell commands for updating the Windows hosts file so you can access Cove sites from your Windows browser.

🛠️ Improvements & Changes

  • Catppuccin Adminer Theme: A new custom Adminer theme has been bundled with Cove, featuring the beautiful Catppuccin color palette.
    • Automatic light/dark mode switching based on system preferences (Latte for light, Mocha for dark).
    • Full SQL syntax highlighting with Catppuccin colors.
    • Modern UI with improved typography, spacing, and styled action buttons.
  • Adminer Auto-Upgrade: The cove upgrade command now also checks for and installs the latest version of Adminer.
  • Improved Site Listing: The cove list command output has been refined for better readability.
  • Smarter Tailscale Detection: Tailscale hostname auto-detection has been improved for more reliable setup.
  • Cleaner Error Display: PHP's display_errors is now disabled by default. The Whoops error handler has been refined to silence noisy E_DEPRECATED and E_NOTICE warnings (common in older plugins) while still displaying fatal errors with full stack traces.
  • Enhanced Share Command: The cove share command now displays a real-time access log showing timestamp, HTTP status (color-coded), client IP address, method, and path for each request. Connection loss is now detected and reported, and shutdown no longer displays terminal noise.

[1.6] - 2025-09-18

✨ New Features

  • Remote Site Pushing: A new cove push command has been introduced to migrate a local Cove site to a remote server via SSH.
    • It features an interactive TUI to guide you through selecting a local site and providing remote credentials.
    • The command creates a local backup, securely uploads it, and then executes a migration script on the remote server to overwrite the destination site's content.

[1.5] - 2025-09-14

✨ New Features

  • Remote Site Pulling: A new cove pull command has been introduced to migrate a remote WordPress site into Cove via SSH.
    • It features an interactive TUI to guide you through providing remote credentials.
    • It can create a new local site or overwrite an existing one.
    • Includes a powerful --proxy-uploads flag that skips downloading the wp-content/uploads directory and instead configures Caddy to reverse_proxy media requests to the live site, saving significant time and disk space.
  • Piped Directives: The cove directive add <site> command now accepts input from stdin, allowing you to pipe complex, multi-line Caddy rules directly into a site's configuration. This is ideal for scripting and is used by the new pull command to set up the upload proxy.

🛠️ Improvements & Changes

  • FrankenPHP Auto-Upgrade: The cove upgrade command is now more powerful. In addition to upgrading the Cove script itself, it now also checks for the latest version of the FrankenPHP binary on GitHub and will automatically download and install it if a newer version is available.
  • Correct Directive Order: The Caddyfile generation logic has been updated to place custom directives before the php_server directive. This ensures that custom rules like reverse_proxy are evaluated first, which is critical for the new upload proxy feature to function correctly.
  • Automatic Directive Cleanup: When a site is deleted using cove delete, any associated custom Caddy directive file is now also automatically removed, ensuring no orphaned configuration files are left behind.

[1.4] - 2025-09-11

✨ New Features

  • Self-Healing Login Command: The cove login command is now "self-healing." If the command fails, it will automatically check for and inject a required Must-Use (MU) plugin into the WordPress site, then retry the login process. This ensures the command works reliably even on sites created with older versions of Cove or if the plugin was manually deleted.
  • Integrated MU-Plugin: Cove now uses a dedicated MU-plugin (captaincore-helper.php) which is automatically added to new WordPress sites. This plugin provides the core functionality for one-time logins via a custom WP-CLI command (wp user login <user>) and also disables WordPress's plugin and theme auto-update email notifications for a cleaner local experience.

🛠️ Improvements & Changes

  • Global PHP Memory Limit: The global PHP memory_limit has been increased to 512M in the main Caddyfile configuration. This helps prevent errors when working with memory-intensive plugins or operations across all sites.
  • Refactored Plugin Injection: The logic for creating the MU-plugin has been moved into its own dedicated function (inject_mu_plugin), cleaning up the cove add command and allowing the new self-healing cove login command to utilize it.
  • More Robust Dashboard Logins: The web dashboard's "Login" button is now significantly more reliable. It delegates directly to the cove login command, inheriting its new self-healing capabilities and simplifying the dashboard's backend logic.
  • Non-Blocking Server Reloads: Server reloads triggered from the web UI (or the cove reload command) now run as a background process. This fixes a potential deadlock issue, preventing the dashboard from freezing and providing a much smoother user experience when adding, deleting, or modifying sites.

[1.3] - 2025-08-24

✨ New Features

  • Admin Login Command: A new cove login <site> [<user>] command has been added to generate a one-time login link for a WordPress site. This works by finding the first available administrator or by specifying a user ID, email, or login.
  • Dashboard Login Button: The web dashboard now includes a "Login" button for WordPress sites, allowing for one-click access to the admin area. This is powered by a new get_login_link API endpoint.

🛠️ Improvements & Changes

  • Automatic /etc/hosts Management: The reload command now automatically checks for and adds required entries for all Cove sites to the /etc/hosts file, ensuring local domains resolve without manual setup. This requires sudo privileges upon first run.
  • Smarter Installation Script: The main installer (install-cove.sh) is now architecture-aware, correctly using /opt/homebrew/bin on Apple Silicon and /usr/local/bin on Intel Macs. It will also offer to install Homebrew if it's not detected and attempt to create the installation directory if it doesn't exist.
  • Robust MariaDB Setup: The cove install command now first attempts an automatic, non-interactive sudo mysql command to create the database user. If this fails, it falls back to the interactive prompt for root credentials, improving the initial setup experience.
  • Resilient Site Creation: The cove add command for WordPress sites is now more robust. It will automatically clean up the site directory and database if the installation process fails, preventing partial sites. It also now deletes the default "Hello Dolly" and "Akismet" plugins for a cleaner start.

[1.2] - 2025-08-22

New Features

  • Site Renaming: A new cove rename <old-name> <new-name> command has been added to fully rename a site. This includes updating the directory name, database name, and running a search-and-replace on the site's URL within the database.
  • Path & URL Commands:
    • Added cove path <name> to quickly get the full system path to a site's public directory.
    • Added cove url <name> to print the full https://<name>.localhost URL for a site.

Improvements & Changes

  • Increased Upload Limits: The default PHP upload_max_filesize and post_max_size have been increased to 512M to allow for larger file and database imports.
  • Enhanced list Command: The cove list command now includes a "Path" column, displaying the path to each site's public directory.

[1.1] - 2025-08-02

New Features

  • Interactive Web UI: A new web-based dashboard has been introduced at cove.localhost for managing sites. This interface allows users to:

    • Add and delete sites directly from the browser.
    • View a list of all managed sites with links to each.
    • See the current database user and password configuration.
    • Toggle between light and dark themes.
  • FrankenPHP Support: The script now detects and prefers a frankenphp installation, falling back to caddy if it's not found. This allows Cove to leverage the performance benefits of FrankenPHP.

  • One-Time Login URLs: When creating a new WordPress site, a one-time login URL is now generated and displayed, allowing for quick and easy access to the new site's admin area without needing to manually enter the generated password.

  • Database Listing: A new command, cove db list, has been added. It provides a formatted table of all WordPress sites and their associated database credentials and size.

  • Sizing Information in Site List: The cove list command now includes a --totals flag to display the disk usage of each site's public directory.

  • Upgrade Command: A new cove upgrade command allows users to automatically fetch and install the latest version of Cove from GitHub.

Improvements & Changes

  • Enhanced list Command: The cove list command now outputs a neatly formatted and styled table for better readability, replacing the previous plain text list.

  • Persistent Mailpit Storage: Mailpit is now launched with a persistent database file (mailpit.db), ensuring that emails are not lost when the service is restarted.

  • Adminer Auto-Login: The Adminer setup now includes an auto-login feature, pre-filling the database credentials from the Cove configuration file for a more seamless experience. A custom theme has also been applied.

  • Improved Output and Styling: The use of gum has been expanded across various commands to provide more consistent and visually appealing feedback, including styled tables, prompts, and messages.

  • Refined Site Creation and Deletion:

    • The site creation process now validates against a list of protected names (cove, mailpit, adminer).
    • Site names are now restricted to lowercase letters, numbers, and hyphens.
    • The cove add command now accepts a --no-reload flag to prevent the server from reloading, which is used by the new web UI to manage the process.
  • Better Service Management:

    • The cove enable command now ensures that any running instances of Mailpit are stopped before starting a new one to prevent conflicts.
    • The cove status command now provides more readable, color-coded output.
  • Robust Dependency Checks: The installation script now checks for conflicting services running on ports 80 and 443 and warns the user.

  • Help Command Enhancements: The help text for all commands has been updated to be more descriptive and now includes subcommand details for db and directive.

Bug Fixes

  • MariaDB Connection Wait: The installation script now correctly waits for the MariaDB service to be fully available before attempting to create the database user, preventing a common installation failure.

[1.0] - 2025-07-12

Added

  • Initial Release of Cove, a command-line tool for local development.
  • Core Service Management: Commands to enable, disable, and check the status of background services (Caddy, MariaDB, Mailpit).
  • Site Management:
    • cove add <name>: Create new WordPress sites.
    • cove add <name> --plain: Create new plain/static HTML sites.
    • cove delete <name>: Delete sites and their associated databases.
    • cove list: List all currently managed local sites.
  • Web Dashboard: A GUI at https://cove.localhost to view, add, and delete sites. It also provides quick links to Adminer and Mailpit.
  • Database Features:
    • cove db backup: Command to create a .sql backup for every WordPress site.
    • Integrated Adminer for web-based database management.
  • Caddy Integration:
    • cove reload: Regenerates the master Caddyfile and gracefully reloads the Caddy server.
    • cove directive: Sub-commands (add, update, delete, list) to manage site-specific Caddyfile rules.
    • Automatic HTTPS for all local sites using internal certificates.
  • Development Environment:
    • cove install: Installs and configures all required dependencies like Caddy, MariaDB, and Mailpit using Homebrew.
    • Built-in Mailpit service to catch all outgoing application emails.
    • Integrated Whoops for informative PHP error pages.
  • Build System:
    • compile.sh: Script to combine all source files into a single, distributable shell script.
    • watch.sh: A helper script using fswatch to automatically re-compile the project on file changes.
  • Versioning:
    • cove version command to display the current version of the tool.
  • License: The project is licensed under the MIT License.