=== SEO Agent ===
Contributors: seoagent
Tags: seo, ai, meta description, rank math, yoast
Requires at least: 6.2
Tested up to: 6.8
Requires PHP: 8.0
Stable tag: 0.6.1
License: GPLv2 or later

Finds on-page SEO problems and fixes them inside the SEO plugin you already use — with review, autopilot and one-click rollback.

== Description ==

SEO Agent works alongside Rank Math and Yoast SEO (or on its own when no SEO plugin is installed).

1. **Scan** — free, rule-based checks of what your pages actually output: missing, too long, too short or duplicate titles and meta descriptions, and images with missing or file-name alt text ("IMG_0921"). Posts are re-checked whenever they are saved.
2. **Generate** — for each problem the AI (Google Gemini, Anthropic Claude or OpenAI, your key) writes three candidates using only facts from the page.
3. **Validate** — every candidate is checked automatically: length, no invented numbers, no HTML or template variables, unique across the site, focus keyword present. Failing candidates are sent back once with the reasons.
4. **Review or autopilot** — approve, edit, or pick an alternative in the Review inbox. Autopilot only fills empty fields and never replaces text a person wrote.
5. **Image alt text** — fixed in both places it lives: the media library and every `<img>` already inside your posts. When good alt text exists in one place it is simply copied to the other (no AI needed); otherwise a small copy of the image is described by the AI in the context of the page. Decorative images are left alone.
6. **Google Search Console (optional)** — pages people actually see are fixed first; titles and descriptions that rank but don't get clicked (CTR under half the typical rate for their position) get a rewrite; empty focus keywords are filled with the top real search query that appears in the page text (no AI needed); the AI is told which searches the page appears for; and the dashboard shows pages losing traffic and whether applied changes improved CTR.
7. **Rollback** — every change is logged with its previous value. If someone edits a field after a proposal, SEO Agent will not overwrite it.

**In the post editor**, an “SEO Agent” panel sits next to Rank Math or Yoast: it shows the post's Google clicks, CTR and top searches, lists failed checks, and offers one-click fixes. After applying, the editor reloads so every panel (including Rank Math/Yoast) shows the new value and saving can't overwrite it.

When All in One SEO, SEOPress or The SEO Framework is active, SEO Agent stays read-only.

= WP-CLI =

    wp seo-agent status
    wp seo-agent audit [--post=<id>]
    wp seo-agent process [--limit=<n>]
    wp seo-agent patches [--status=pending]
    wp seo-agent apply <id>... | --all [--min-score=0.9]
    wp seo-agent reject <id>...
    wp seo-agent rollback <id>... [--force]
    wp seo-agent gsc oauth-client <oauth-client.json>
    wp seo-agent gsc connect <key.json> [--site=<property>]
    wp seo-agent gsc sync | report | disconnect

= Developers =

* `seo_agent_provider` — return any `SEOAgent\LLM\Provider` implementation.
* `seo_agent_rules` — add `SEOAgent\Audit\Rule` implementations.
* `seo_agent_generator` — supply a generator for a custom job type.
* `seo_agent_patch_applied`, `seo_agent_patch_reverted` — actions after a change.

= Privacy =

Page titles, headings and the first ~350 words of each page being fixed — and, for alt text, a 768px copy of each undescribed image — are sent to the AI provider you configure. Nothing is sent until you add a key and generate fixes. Search Console access is read-only; search data stays in your database.

== Installation ==

1. Upload the zip via Plugins → Add New → Upload.
2. Open **SEO Agent → Settings**, choose a provider and add an API key (or define `SEO_AGENT_API_KEY` in wp-config.php).
3. Dashboard → **Scan site** → **Generate fixes** → **Review**.

== Changelog ==

= 0.6.1 =
* OAuth client JSON is accepted under any file name; docs updated.
* Release builds refuse to package any file that contains a key or client secret (checked by content).

= 0.6.0 =
* Security: built-in <title> output escaped; encoded markup stripped from reviewer edits; LLM calls refuse private/loopback hosts; Search Console token endpoint pinned to Google; secrets never stored unencrypted; changing the OpenAI base URL drops the saved key; per-provider wp-config constants (SEO_AGENT_GEMINI_API_KEY, SEO_AGENT_ANTHROPIC_API_KEY, SEO_AGENT_OPENAI_API_KEY); media-library alt only changed for images the post's author may edit.
* Fixes: new problems on already-processed posts are queued again (e.g. low CTR after a sync); alt-text rollback restores only the tags it changed; edits made while the AI works discard the stale proposal; crashed items stop after 3 attempts; a value altered by the SEO plugin on save is rolled back; retryable failures in alt batches are retried; home-page mapping respects “latest posts”; every billed AI request counts toward the daily cap.
* Performance: duplicate checks use one grouped query per scan batch (1,500 posts scanned in under 2 s); Search Console rows are streamed.
* Uninstall cleans every site of a network.

= 0.5.0 =
* OpenAI provider (Responses API, strict structured outputs, image input for alt text; gpt-6-luna / sol / astra). Optional base URL for Azure OpenAI and other Responses-compatible services.
* One API key per provider — switching provider never sends one vendor's key to another. Existing keys are migrated automatically.

= 0.4.0 =
* Redesigned admin: Overview, Review, Search Console, History and Settings tabs; filter chips with counts; sectioned settings with a sticky save bar.
* Block editor panel with per-post checks, search metrics and one-click fixes.
* Gemini falls back to flash-lite on quota (429) as well as overload (503); failures are explained in the UI.

= 0.3.1 =
* “Connect with Google” (OAuth 2.0 with PKCE): sign in once; refresh token stored encrypted and revoked on disconnect. Service accounts remain supported.
* OAuth client can come from Settings, wp-config (`SEO_AGENT_GOOGLE_CLIENT_ID` / `SEO_AGENT_GOOGLE_CLIENT_SECRET`) or the `seo_agent_google_oauth_client` filter.

= 0.3.0 =
* Google Search Console via service account: daily sync, traffic-based priority, low-CTR rewrites with a 31-day cooldown, focus keywords from real queries, queries in prompts, decay and impact reports.
* Jobs that don't need AI (focus keywords) run without an API key.

= 0.2.0 =
* Image alt text job: media library + in-content images, vision descriptions, no-AI sync, per-image rollback.
* Gemini: `-latest` model aliases, low thinking (≈14× cheaper), automatic fallback to flash-lite on overload.
* API key field extracts the key from pasted snippets and rejects non-keys.
* New jobs are switched on automatically after upgrading.

= 0.1.0 =
* Meta title and meta description jobs; Rank Math, Yoast and built-in output; Gemini and Claude providers; review inbox, autopilot, rollback; WP-CLI.
