# Changelog

All notable changes to Waypoint Agent are documented here.

---

## [Unreleased]

## [0.7.6] - 2026-08-30

### Added
- **WP-CLI allow-list REST route** — `POST /wp-json/waypoint-agent/v1/wp-cli`, HMAC-only, for Skymarshal's Phase 6 allow-listed WP-CLI actions (`statenweb/skymarshal`, `packages/core/src/actions/wp-cli-commands.ts`). Implements the exact 11 commands from that spec directly against WP core functions (no `wp` binary involved) — `plugin.list`/`theme.list` reuse `Status_Data`'s existing reflection logic (now public), `plugin.activate`/`plugin.deactivate` resolve a slug to its plugin file the same way `Status_Data::plugin_list()` reports slugs, `core.update_db`/`cache.flush`/`rewrite.flush`/`transient.delete_all` call the same core functions those `wp` subcommands call under the hood. An unknown command id is rejected with 400 independently of whatever Skymarshal itself validated — this route re-validates every command id and argument from scratch rather than trusting the caller.

## [0.7.5] - 2026-08-30

### Changed
- **Login page** — logo link now points to the site's home URL instead of wordpress.org (`login_headerurl`); tooltip updated to the site name (`login_headertext`).
- **Login page** — "Powered by Waypoint" attribution line with a link to waypointagency.com added below the login form via `login_footer`.

## [0.7.4] - 2026-08-19

### Fixed
- **Login logo fallback** — removed dark-mode SVG variant; final fallback now always uses `assets/images/normal-mode.svg` regardless of OS color scheme.

## [0.7.3] - 2026-08-19

### Added
- **One-time trusted-domain user sweep** — on the first admin page load after the plugin is active, sweeps all existing users and grants `waypoint_super_admin` to anyone with a `@waypoint.agency`, `@waypointagency.com`, or `@statenweb.com` email who doesn't already have it. Guarded by a versioned option (`waypoint_trusted_domain_sweep_v1`) so it only runs once; bumping the version suffix forces a fresh sweep after role changes. Activation already ran this sweep — this handles sites that were active before the trusted-domain feature shipped.
- **Login logo replacement** — replaces the WordPress logo on the login page with a configurable logo. Priority: ① **Customizer setting** — a new "Login Page Logo" image upload control under _Appearance → Customize → Site Identity_; ② **Site Icon** — falls back to the site's configured Site Icon; ③ **Waypoint logo** — bundled `assets/images/normal-mode.svg` (or `dark-mode.svg` when the visitor's OS is in dark mode via `prefers-color-scheme`).

## [0.7.2] - 2026-08-13

### Added
- **Rank Math Pro update-chain guard — Parts 2 & 3** (extends v0.7.1):
  - **Part 2 — loopback guard**: On non-ajax admin loads where `rank_math_pro_version` is behind the installed `RANK_MATH_PRO_VERSION`, adds a `pre_http_request` filter that short-circuits any loopback POST to `admin-ajax.php` (returning a fake `200 OK`). This prevents Rank Math's background `dispatch()` call from re-entering `do_updates()` and dying mid-chain before the version option is written. With the loopback neutralised, `perform_updates()` runs to completion and `rank_math_pro_version` is recorded. The filter is removed at `PHP_INT_MAX` priority on `admin_init` after the update chain finishes at priority 10. A 5-minute transient prevents concurrent requests from stacking.
  - **Part 3 — daily schema check**: Hooks `waypoint_monitor_daily_heartbeat` to verify that Rank Math Pro's five Link Genius tables (`rank_math_link_genius_audit/history/snapshots/maps/map_variations`) exist, using Rank Math's own `Table_Extension::ensure_all_pro_tables_exist()`. Guards with a version-keyed option (`waypoint_rm_schema_ok`) so the check re-runs exactly once after each Rank Math Pro upgrade rather than daily every time. Define `WAYPOINT_FORCE_RM_SCHEMA_CHECK` to force a check regardless of the stored version. Falls back to `Table_Extension::initialize_schema()` on older Pro versions that lack `ensure_all_pro_tables_exist`.

## [0.7.1] - 2026-06-22

### Added
- **Rank Math Pro update-chain guard** — prevents `RankMathPro\Updates::do_updates()` from running during admin-ajax requests. The update chain calls `check_ajax_referer()` internally, which `wp_die(-1, 403)`s on any ajax request that isn't its own, killing every unrelated admin-ajax call site-wide and self-perpetuating (the version option never records, so it re-runs forever). Guard hooks `admin_init` at priority 0 and removes the callback only when `wp_doing_ajax()` is true, so the update still runs and completes on the next normal `/wp-admin/` page load. Complete no-op on sites without Rank Math Pro.

### Fixed
- `WPOSES_HIDE_VERIFIED already defined` warning when WP Offload SES defines the constant before the plugin loads; wrapped in `defined()` guard.

## [0.7.0] - 2026-06-22

### Added
- **Disable Admin Email Confirmation Prompt** — new toggleable setting (default on) that suppresses the periodic "Is this your admin email?" screen via `admin_email_check_interval`, and applies admin email changes immediately without the confirmation email step (hooks `add_option_new_admin_email` / `update_option_new_admin_email` to flush the pending state instantly).

## [0.6.9] - 2026-07-28

### Added
- **Override Admin Email Setting** — added a new setting (default enabled) that uses the `pre_option_admin_email` filter to dynamically override the WordPress administration email to `admin@waypoint.agency` without modifying the underlying database option.
- **Plugin update status in `plugin_list`** — each plugin entry now carries `update_available` (bool) and `new_version` (string|null), read from the `update_plugins` transient. Package Monitor uses these to show which plugins WordPress reports as outdated on the Sites page WP Updates tab.

## [0.6.8] - 2026-07-08

### Added
- **Trusted-domain auto-assignment for Waypoint Super Admin** — users with an `@waypoint.agency`, `@waypointagency.com`, or `@statenweb.com` email are now automatically granted the `waypoint_super_admin` role (additive; existing roles are untouched). Triggers on new user registration, profile updates, and role changes, plus a sweep on plugin activation and the daily heartbeat cron to catch existing users. WordPress's `set_role()` replaces a user's entire role list, so this also fixes a silent-loss bug where changing a trusted-domain user's role via the Users admin screen would drop `waypoint_super_admin`.
- **`wp waypoint-agent sync-trusted-admins`** — WP-CLI command to manually re-run the trusted-domain sweep.

## [0.6.7] - 2026-06-22

### Changed
- Release workflow now triggers `statenweb/satis-file-statenweb` (`rsync-satis.yml`) via `workflow_dispatch` after each dist release, reusing `DIST_REPO_TOKEN`.

## [0.6.6] - 2026-06-22

### Fixed
- **Slack notification** — multi-line TEXT= assignment had continuation lines at column 0, which YAML parsed as aliases/anchors and rejected. Replaced with `+=` concatenation so every line stays within the block scalar indentation level.

## [0.6.5] - 2026-06-22

### Fixed
- **Slack notification** — replaced fragile `python3 -c "..."` block (YAML indentation caused block scalar to terminate early) with `jq` + `curl`; `jq --arg` handles JSON escaping of any special characters in the changelog text.

## [0.6.4] - 2026-06-22

### Changed
- **Slack release notifications** — switched from direct Slack API to the Waypoint Slack notifier service (`slack-notifier.apps.waypoint.agency`); uses `SLACK_NOTIFIER_KEY` secret and `SLACK_CHANNEL` repo variable. Message now includes full changelog entry, links to the release, full changelog, and commits since release.

## [0.6.3] - 2026-06-22

### Added
- **README** — rewrote from scratch to cover current plugin scope: WP-CLI commands, settings, roles/capabilities, authentication, integrations, and environment variables.
- **Slack release notifications** — `release.yml` now extracts the CHANGELOG entry for the tagged version and posts a formatted message to the configured Slack releases channel via bot token after the dist push completes. Requires `SLACK_BOT_TOKEN` and `SLACK_RELEASES_CHANNEL_ID` secrets in GitHub.

## [0.6.2] - 2026-06-20

### Added
- **`wp cache flush` hook** — after WP-CLI's native cache flush runs, Flush Everything fires automatically (WP Rocket, EWWW ExactDN, SpinupWP), with each step logged to the CLI output.

## [0.6.1] - 2026-06-20

### Fixed
- **RankMath: Disable Content AI** — replaced `unset($modules['content-ai'])` with `$modules['content-ai']['disabled'] = true`; Rank Math re-inserts `content-ai` at position 0 after the filter runs, leaving a null entry that caused a fatal `TypeError` in `Admin_Menu::register_pages()`. Using the `disabled` flag causes `Module::is_active()` to return false without removing the key.
- Removed non-existent `rank_math/content_ai/disable` filter (dead code — the hook does not exist in Rank Math's codebase).

## [0.6.0] - 2026-06-20

### Added
- **Waypoint Super Admin role** — new `waypoint_super_admin` role with `set_waypoint_helper_settings` capability. Settings page and key notice are now gated on this capability instead of `manage_options`.
- Auto-assigns the role to the first user who registers; on plugin activation, seeds the oldest administrator if no super admin exists yet.
- **`wp waypoint-agent waypoint-admin <user_id>`** — WP-CLI command to grant the Waypoint Super Admin role to any user.
- **RankMath: Disable Content AI** — new toggleable setting (default on) that disables the Rank Math Content AI module via `$args['disabled'] = true`.

## [0.5.9] - 2026-06-14

### Fixed
- Waypoint dashboard widget now renders first (top-left) by prepending it to the normal column meta box order

## [0.5.8] - 2026-06-14

### Added
- **Waypoint Dashboard Widget** — adds a branded widget (logo, version, agent key status) to the WP admin dashboard; also removes Activity, Site Health, Quick Draft, and WordPress News widgets while keeping At a Glance. Toggleable via settings.

## [0.5.7] - 2026-06-14

### Added
- **RankMath: Homepage OG Image Fallback** — new toggleable feature that uses the global Default Social Share Image on the homepage when no explicit Rank Math social image or featured image is set; respects explicit homepage-level, page-level, and featured image overrides in priority order
- `WPOSES_HIDE_VERIFIED` constant added to suppress WP Offload SES verified-sender notice

---

## [0.5.6] - 2026-06-14

### Fixed
- Admin notice for missing `WAYPOINT_AGENT_KEY` now shows `wp waypoint-agent rotate-key` instead of the raw `openssl` command

---

## [0.5.5] - 2026-06-14

### Added
- **Settings page redesign** — card layout, CSS toggle switches with live Enabled/Disabled badge (updates without page reload), footer save bar
- **Admin notice** — red `admin_notices` error when `WAYPOINT_AGENT_KEY` is not set, shown only to admins, disappears once the key is configured

---

## [0.5.4] - 2026-06-13

### Fixed
- ACF Pro now installs into `vendor/wpengine/advanced-custom-fields-pro/` via `installer-paths` override — previously `composer/installers` routed it to `wp-content/plugins/`
- `wp-content/` directory excluded from dist rsync so the dist stays clean

---

## [0.5.3] - 2026-06-13

### Fixed
- Dist `composer.json` no longer declares `wpengine/advanced-custom-fields-pro` as a requirement — consumers were getting a "could not be found" error because they don't have ACF repo auth
- CI strips `repositories`, `require[wpengine/...]`, and `config` from `composer.json` via `jq` before syncing to dist

---

## [0.5.2] - 2026-06-13

### Fixed
- `composer/installers` plugin now allowed in CI via `allow-plugins` config
- `composer.lock` committed so CI installs are reproducible

---

## [0.5.1] - 2026-06-13

### Fixed
- Release pipeline corrections after initial dist push

---

## [0.5.0] - 2026-06-13

### Added
- **PSR-4 Victoria-pattern refactor** — monolithic `waypoint-agent.php` split into namespaced classes under `src/`, each registering its own hooks via `attach_hooks()`
- **ACF Pro bundled** — `wpengine/advanced-custom-fields-pro` included in dist via Composer; `Acf\Loader` bootstraps it only if ACF isn't already active
- **Settings page** — `Tools > Waypoint Agent` with per-feature toggles (all default on)
- **Disable Comments** — removes comment support sitewide, closes REST comments endpoint, hides comment UI in admin
- **Default Content cleanup** — deletes the "Hello world!" post on first run (one-shot, guarded by option flag)
- **RankMath integration** — suppresses `slack_enhanced_data` from OpenGraph output
- **GitHub Actions release pipeline** — builds dist into `statenweb/site-agent-dist` with `vendor/` committed and ACF auth; consumers install without needing ACF credentials
- **Package rename** — `statenweb/waypoint-helper` (replaces deprecated `statenweb-plugin/waypoint-monitor`)
- **`wp waypoint-agent rotate-key`** WP-CLI command — generates and writes `WAYPOINT_AGENT_KEY` to `.env` in one step

---

## [0.4.1] - 2026-05-21

### Changed
- Minor SEO handling updates

---

## [0.4.0] - 2026-05-16

### Added
- SEO / metadata handling

---

## [0.3.3] - 2026-04-30

### Changed
- Force-serve REST response body; DRY namespace constants

---

## [0.3.2] - 2026-04-29

### Added
- Bypass WPO365 SSO for `waypoint-monitor` and `waypoint-agent` REST endpoints

---

## [0.3.1] - 2026-04-29

### Changed
- Prefer Bedrock-canonical `.env` location (one directory above web root)

---

## [0.3.0] - 2026-04-29

### Added
- Initial REST routing and HMAC auth

---

## [0.2.3] - 2026-04-29

### Fixed
- Permission check stability improvements

---

## [0.2.1] - 2026-04-28

### Changed
- Enhanced permission checks

---

## [0.2.0] - 2026-04-28

### Added
- Bearer token auth alongside HMAC

---

## [0.1.0] - 2026-04-27

### Added
- Initial release — site registration, status endpoint, Composer package
