All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Community maintenance release following a full review of every open issue and pull request. Accepted findings were reconciled against the current release base, with superseded or unsafe patches excluded. No breaking command changes. Full suite: 410 passing tests.
claude-seo run, /seo setup, and /seo doctor.
Plugin environments persist under Claude's plugin data directory, manual installs use an
isolated local environment, and bundled scripts no longer depend on the caller's working
directory or a hardcoded Python executable.Prompt-hygiene alignment to the Fable 5 prompt principles. No behavior, routing, or output changes.
Full-review maintenance pass (2026-07-09/10). 319 adversarially verified findings from a multi-engine review (7 Google research streams, 20 currency audit slices, 6 refuter slices); all fix bundles applied. No breaking changes.
scripts/gbp_deprecation_lint.py and
skills/seo/references/local-seo-signals.md (Google: Q&A is category/region-limited, not retired).scripts/presets.py / cost_tracker.py invocations repointed.hooks/validate-schema.py now supports the documented stdin hook-event contract.scripts/consistency_check.py: path-aware reference-graph gate (dead refs, routing tables,
FLOW lock, orphans) with CI coverage via tests/test_consistency_check.py.Google-currency refresh. Reconfirms the suite against the latest Google updates, verified against Google-primary sources via a multi-agent reconfirmation run. Documentation/data accuracy only — no code behavior change beyond two added IPTC vocabulary values. No breaking changes.
13.0 (Oct 2025) → 13.4.0 (June 2026, latest stable); corrected the 13.0 description (insight-based audits, not "reorganized scoring weights"); documented the new Agentic Browsing category (created 13.2.0, default 13.3.0, disabled in the PSI REST API in 13.4.0) as a fractional pass-ratio, not a 0–100 score. (agents/seo-performance.md, skills/seo/references/cwv-thresholds.md, skills/seo-technical/**)registered-webmcp-tools, forms-missing-declarative-webmcp, webmcp-schema-validity).1.5B → 2.5B+ MAU (I/O 2026); added that Google Search ignores llms.txt (docs, 2026-06-15); reconciled the unified AI-Search experience with the two-citation-engines model."version": "1.0" → date-based (current 2026-04-08) with canonical URLs; AP2 donated to FIDO (2026-04-28); Universal Cart / Native-vs-Embedded checkout / Lodging+Food verticals.data/google-updates.json (Feb 2026 Discover, March 2026 spam, May 2026 core completion, back-button policy, GSC gen-AI report, etc.); fixed the INP date and replaced 301'd ranking-update-history URLs with the Search Status Dashboard.seo-google: Search Console Generative AI performance report, GSC impressions logging-error caveat (2025-05-13 → 2026-04-27), GA4 AI Assistants channel.scripts/iptc_ai_label.py: algorithmicMedia and compositeWithTrainedAlgorithmicMedia DigitalSourceType values.Full audit of every /seo command + subcommand (25 skills + 8 extensions), via deterministic wiring checks + 5 Codex sub-agents; findings were folded into this release.
seo-sxo agent called parse_html.py "<url>" (script needs --url); seo-sxo and seo-local referenced DataForSEO tools not in the catalog (google_organic_serp/keyword_data/local_business_data/google_local_pack_serp/business_listings → serp_organic_live_advanced / kw_data_google_ads_search_volume / business_data_business_listings_search); content-brief used serp_google_organic_live_advanced → serp_organic_live_advanced; Bing submit-batch/verify-indexnow were missing the required --host flag.docs/COMMANDS.md google examples used non-existent command names (psi/gsc-queries/indexing-notify/ga4-organic/check) → real pagespeed/gsc/inspect/index/ga4; maps used geogrid/audit → grid/gbp; "7 specialist subagents" → "up to 15".seo-schema/seo-backlinks pointed at `references/...` as if local → repointed to the shared seo/references/ location.Reconciled the public docs/manifests with the v2.1.0–v2.2.1 code state via a parallel per-file pass with an independent verifier gate. No behavior change.
/seo commands and added the five missing extension commands (ahrefs, seranking, profound, bing, unlighthouse) to the table; corrected stale figures: DataForSEO 22 → 23 commands, manifest 14 → 15 assertions, audit fan-out "6 parallel" → "up to 15 core audit agents; optional extension agents such as seo-dataforseo may run in addition", and the v2 test narrative to 39 → 326 (url_safety suite = 91 cases); reworded the "zero-network" overclaim (audits still fetch target URLs) and the Playwright optional/auto-install wording.tests/test_url_safety.py count contradiction (52+ vs 122) to the verified 91 cases (31 functions) in both places.scripts/url_safety.py (validate_url() / safe_requests_session()), not google_auth.py (OAuth-only).seo-content-brief and seo-flow to the tree and command table.MIGRATION-v1-to-v2.md ("Three" → six rich-result types + v2.1–2.2.1 forward pointer), MCP-INTEGRATION.md (DataForSEO 22 → 23), TROUBLESHOOTING.md (schema false-positive note now covers the 2025 retirements + the 2026-05-07 FAQ retirement), INSTALLATION.md (Playwright wording), WORKFLOW-public-private.md (state section refreshed to v2.2.1 / 2026-06-22)..claude-plugin/marketplace.json: descriptions refreshed for the 2.1–2.2.1 currency + command audit, and both trimmed under the 500-char registry cap (the plugin-entry description was previously over cap at 573).extensions/dataforseo/: README.md, install.sh, and install.ps1 corrected 22 → 23 commands.Corrections from a live re-confirmation of every time-sensitive Google claim against Google-primary sources fetched 2026-06-22. Confirmed claims were updated and uncertain claims relabeled. All are precision/labeling fixes — the v2.2.1 currency substance was confirmed accurate.
agents/seo-content.md, skills/seo-content/SKILL.md, README, and this changelog.qapage doc).2025-06-19 → 2025-06-12 (announcement date) in data/google-updates.json and the deprecated-types reference.…/2023/09/structured-data-changes (HTTP 404) repointed to the real post …/2023/08/howto-faq-changes.Security, cross-platform, and data-accuracy release. Folds the v2.1.0 currency content into the first public ship and closes the full open-issue and PR backlog. No breaking changes.
python3 -c source string, allowing arbitrary code execution at install time when a credential contained '''. Credentials now pass as argv through a quoted heredoc, and the settings file is written atomically with 0600 permissions (shell installers plus the DataForSEO PowerShell installer). Found by an independent audit.url_safety.validate_url accepted authority-confusion URLs such as https://127.0.0.1:6666\@1.1.1.1, which requests connects to the internal host. The validator now rejects backslash and userinfo authority confusion, covering every caller. Reported by @Fushuling (#110).pagespeed_check, crux_history, nlp_analyze, and lcp_subparts put the API key in the request URL and echoed it on error. Keys now travel in the X-Goog-Api-Key header with redacted error output. Reported by @webgunnz (#122); header approach from #104 (@fayerman-source).PtrToStringAuto to PtrToStringBSTR so SecureString credentials decode correctly under PowerShell on Linux and macOS.ci.yml and v2.yml fails the build when any tracked file contains a high-signal credential pattern (Google, GitHub, AWS, Google OAuth, OpenAI, Slack); test fixtures and documented placeholders are allowlisted. .gitignore extended to cover more credential and key formats. Verified against the full history and tracked tree: no real secret present./dev/stdout, use a tempfile fetch-to-parse handoff with errors="replace", and handle the Microsoft Store Python alias (PRs #117, #128, #111, #115, #125).python3/py, fixing failures on macOS and Linux without a bare python (PR #101).<meta> charset deterministically when the server omits a charset.indexed field (#113). No longer surfaced (it always returned 0).analyzeEntities endpoint so Knowledge Graph mid/wikipedia_url and salience are returned./seo local and /seo maps instructed the model to load references/*.md from directories that do not exist; both now point to the shared skills/seo/references/ files they always intended.templates/cluster-map.html was excluded by an over-broad .gitignore rule, so installed users never received the interactive cluster visualization. It is now tracked.unlighthouse-cli); it now uses unlighthouse@0.13.5. The Ahrefs extension is pinned to @ahrefs/mcp@0.0.11 and invokes the package's real mcp binary.sync_flow.py now rewrites them to the flattened layout on every sync, and the existing files were repaired.--dry-run raised an uncaught network error when GitHub was unreachable; it now exits cleanly with an actionable message.claude-seo@agricidaniel-claude-seo, the CITATION.cff release date, the README test count (326), the AGENTS.md script count (50), and the README FAQ guidance.pyproject.toml authors and keywords (#118).python to python3; CLAUDE.md and AGENTS.md script inventory corrected to 50; README test count updated.user-invokable frontmatter key to user-invocable./seo content-brief command in the command reference and README, added /seo flow to the project command table, and reconciled the command count to the 25 the orchestrator routes.CODEOWNERS; CI compiles every scripts/*.py dynamically; marketplace extension count corrected from 7 to 8; dependency floor bumps (Dependabot #105 to #109, #116).branding/ preview tooling (it referenced deleted diagram assets) and the inactive npm Dependabot watcher (the repo ships no npm manifest). Hardened the Python hook probe against environment-specific EPERM, gave Banana validate_setup.py --help proper argument handling, and repaired stale internal documentation links. Full suite at 326 passing.Knowledge-currency refresh for Google's May 2026 wave: the May 2026 core update, Google I/O 2026 (Gemini 3.5 Flash now powers AI Mode globally; AI Mode past 1B monthly users), and the May 7 2026 retirement of FAQ rich results. No architecture, API, or command changes — every v2.0.0 entry point still works.
data/google-updates.json: four primary-source-verified entries — March 2026 Core Update (promoted from unverified[] after Google status-dashboard confirmation; Mar 27 to Apr 8 rollout), FAQ rich result retirement (May 7), Google I/O 2026 / Gemini 3.5 Flash in AI Mode (May 19), and the May 2026 Core Update (May 21). unverified[] is now empty; last_verified bumped to 2026-05-25.skills/seo-geo/SKILL.md: AI Mode is now modeled as a distinct citation engine from AI Overviews (Ahrefs: only 13.7% URL overlap across 540K query pairs), with its own row in the platform table, the Gemini 3.5 Flash + 1B-user stats, content recency as a citation lever (~3x for content under 3 months, SE Ranking), and the "~44% of AI citations come from the first 30% of the page" finding.skills/seo/references/schema-types.md: QAPage added as the active type for genuine user Q&A (the active type for real Q&A pages — not a replacement for FAQ rich results).tests/test_schema_v2.py: test_faq_rich_results_retirement_documented locks the May 7 2026 FAQ retirement + QAPage-for-Q&A guidance across the canonical schema references.schema-types.md, deprecated-types-2024-2026.md, seo-schema/SKILL.md, agents/seo-schema.md, seo/SKILL.md, seo-page/SKILL.md, seo-content/SKILL.md, seo-plan/assets/saas.md): FAQ rich results are fully retired for all sites as of May 7, 2026, superseding the Aug 2023 gov/health framing. FAQPage stays Info-priority as an AI/entity signal (never a Critical removal); QAPage is the type for genuine Q&A pages.skills/seo-content/SKILL.md: AI Mode description updated to the Gemini 3.5 Flash / 1B-user / two-citation-engine reality.2.1.0 across plugin.json, pyproject.toml, CITATION.cff, install.sh, install.ps1, and 32 SKILL.md files (seo-content-brief stays at 1.0.0 per COMMUNITY_OVERRIDES). Gated by tests/test_manifest_consistency.py.v2 is backward-compatible by design — every v1.x command, script signature, and skill entry point still works. The release lands a hardened SSRF + DNS-rebinding safety layer, shared headless rendering across every fetcher, QRG-aligned content gates, four new Schema.org generators, five new MCP extensions, and multi-platform portability. Full narrative in docs/MIGRATION-v1-to-v2.md.
scripts/url_safety.py (canonical SSRF + DNS-rebinding module, 83 test cases), scripts/render_page.py (shared Playwright Chromium renderer with --mode auto SPA detection, trafilatura extraction, htmldate publication-date extraction, 27 test cases). 8 fetcher subagents (seo-technical, seo-content, seo-schema, seo-geo, seo-local, seo-ecommerce, seo-backlinks, seo-sxo) now route through render_page.content_quality.py (QRG filler / AI-pattern / information-density scorer), content_humanize.py (40+ deterministic AI-phrasing replacements), content_verify.py (claim extraction + citation-gap detection), domain_history.py (WHOIS-driven expired-domain abuse check), seo_updates.py + data/google-updates.json (18 primary-source-verified Google updates, 1 documented-unverified gap-analysis claim).preload_check.py (Speculation Rules + bfcache + prerender + LCP preload audit), indexnow_submit.py (Bing/Yandex/Seznam/Naver IndexNow submitter), lcp_subparts.py (LCP decomposition via CrUX), unlighthouse_run.py (multi-page Lighthouse via Unlighthouse CLI).schema_generate.py (reservation, order, discussion, profile subcommands), schema_ecommerce_validate.py (Product schema policy validator: hasMerchantReturnPolicy, shippingDetails, MemberProgram, EU energyEfficiencyClass, ProductGroup), reference doc skills/seo-schema/references/deprecated-types-2024-2026.md.parasite_risk.py (site-reputation-abuse risk scanner per Nov 2024 Google policy), skills/seo-geo/references/llmstxt-evidence.md (evidence-based reframe of llms.txt as dev-tooling, not citation lever).gbp_deprecation_lint.py (retired GBP chat / .business.site / Q&A detector), skills/seo-google/references/dma-consent-mode-v2.md (EU CTR diagnostic + softened cookieless framing), skills/seo-hreflang/references/machine-translation-qa.md (untranslated-MT detection per Jan 2025 QRG §4.6.5).portability_check.py (cross-platform SKILL.md frontmatter lint), AGENTS.md tool-name compatibility table for Codex CLI, Cline, Aider.release_sign.py (SHA-256 manifest of every git-tracked file), verify_release.py (verify a checkout against a signed manifest)..github/CODEOWNERS, .github/dependabot.yml extended with npm ecosystem, .github/workflows/v2.yml (workflow_dispatch only), SECURITY.md uplift (threat model, 90-day coordinated disclosure timeline, residual risks).scripts/google_auth.py:validate_url now delegates to url_safety.validate_url. Strict variant available as url_safety.validate_url_strict.scripts/fetch_page.py exposes --render {auto,always,never}. Default auto runs raw fetch then renders if SPA signals detected; always forces Playwright; never preserves v1 behaviour.scripts/capture_screenshot.py uses url_safety.make_safe_playwright_route_handler as defense-in-depth against subresource SSRF (data: allowed, private resolutions aborted, AF_UNSPEC IPv6-aware).os.open(path, O_WRONLY|O_CREAT|O_TRUNC, 0o600) + explicit os.fchmod(fd, 0o600). Legacy 0o644 files are remediated in place on next _load_oauth_token.plugin.json / marketplace.json / pyproject.toml / CITATION.cff / install.sh / install.ps1 / 32 SKILL.md files: version bumped to 2.0.0. The 13-assertion manifest test (tests/test_manifest_consistency.py) gates this._pin_dns previously intercepted only the originally-pinned hostname; redirect targets fell through to the unpatched resolver. Patched socket.getaddrinfo now validates every resolution while pinned. Closed in a601268.validate_url. Decimal (2130706433), hex (0x7f000001), octal (017700000001), leading-zero (127.0.0.001, 0177.0.0.1), and mixed-radix (0x7f.0.0.1) forms all returned safe. New normalize_hostname() canonicalizes via socket.inet_aton. Closed in 3c595c2.metadata.google.internal. (single trailing dot) bypassed the exact-string blocklist. normalize_hostname now strips a single trailing dot. Closed in 3c595c2.AF_INET. Now uses AF_UNSPEC to catch dual-stack subresources whose AAAA record points at a private range. Closed in 3c595c2.os.open's mode argument is ignored if the file pre-existed. Explicit os.fchmod(fd, 0o600) on the open fd closes the race. Closed in 3c595c2.Two intentional behavioural breaks; full mitigation guidance in docs/MIGRATION-v1-to-v2.md.
scripts/backlinks_auth.py no longer ships a silent SSRF-disabled fallback. If url_safety cannot be imported, the module raises RuntimeError at import time.seo-schema flags six retired rich-result types as Critical findings (Vehicle, ClaimReview, EstimatedSalary, LearningVideo, SpecialAnnouncement, CourseInfo carousel). Replacements documented in skills/seo-schema/references/deprecated-types-2024-2026.md.| Suite | v1.9.9 | v2.0.0 |
|---|---|---|
| Pre-existing (manifest + lazy + sync FLOW) | 39 | 39 |
url_safety (new) |
— | 83 |
render_page (new) |
— | 27 |
| Content quality (new) | — | 25 |
| Technical depth (new) | — | 17 |
| Schema v2 (new) | — | 17 |
| Parasite risk + extensions (new) | — | 22 |
| GBP lint + polish (new) | — | 8 |
| Portability (new) | — | 10 |
| Total | 39 | 248 |
Final 1.x patch release. v2 is in design; this release leaves the v1.x branch in a clean, well-documented, dependency-current state.
Independently verified across 5 rounds of GPT-5.5 xhigh code review via the Codex CLI before each PR push. Issue #92 + issue #41 closed.
1.9.9 atomically. CI guard
extended from 9 to 13 assertions covering the orchestrator SKILL.md,
per-skill metadata.version, marketplace.json metadata.description + author
parity, and Sub-Skills/Subagents list consistency with disk.skills/seo/SKILL.md (issue #92): line 9
metadata.version: "1.9.6" was stale; descriptive headline at lines 19-21
still claimed "21 specialized sub-skills"; Sub-Skills numbered list at
176-199 included seo-firecrawl (which is an extension, not in skills/)
and was missing seo-content-brief (the PR #56 contribution). Subagents
bullet list had the same drift pattern (included seo-firecrawl, no agent
file on disk; missing seo-flow, file exists). Reconciled. Numbered list
now reaches 24 (the orchestrator itself is the 25th in skills/ but does
not orchestrate itself), seo-firecrawl moved to a new "Optional
Extensions" subsection, Subagents list now matches agents/seo-*.md set
exactly.marketplace.json drift (issue #92): metadata.description was
missing the "sub-agents" count claim that plugins[0].description carried;
plugin entry had no author object despite v1.9.8 release notes claiming
one was added in commit 8514999 (verification showed it was not). Both
fixed. v1.9.8 entry in this CHANGELOG corrected to reflect what actually
shipped.AGENTS.md:109 said "17 subagents"; disk has 18. Fixed.install.sh and install.ps1 default tag pinned to v1.9.0 across 4
missed release bumps (v1.9.5/.6/.7/.8). Anyone running
curl -fsSL .../install.sh | bash got the April 14 release, missing FLOW
integration, the security audit pass, doc reconciliation, the manifest CI
guard plus v1.9.8 Phase B bug fixes (Windows hook, OAuth refresh, missing
imports, None guards). Bumped to v1.9.9 atomically with this release.pyproject.toml had drifted to 1.9.6 while plugin.json + CITATION
shipped at 1.9.8. Bumped to 1.9.9 with the release.metadata.version fields were stuck at 1.9.6; 3
extension SKILL.md files were at 1.9.0/1.7.2. All bumped to 1.9.9.
seo-content-brief deliberately stays at 1.0.0 (community contribution,
CI allowlist).scripts/parse_html.py now classifies each
image's lazy-loading mechanism in a lazy_method field with five values:
native | perfmatters | ewww | js-generic | none. Sites running Perfmatters,
EWWW Image Optimizer, lazysizes, vanilla-lazyload, or jQuery lazy-loaders
are no longer mis-reported as "not lazy-loaded". skills/seo-page/SKILL.md
and skills/seo-images/SKILL.md are updated to consume the new field.tests/test_manifest_consistency.py:test_orchestrator_sub_skills_list_matches_disk: Sub-Skills list must
equal set(skills/*) - {seo}; no duplicates. Regex scoped to the
## Sub-Skills section via a new _extract_section() helper.test_orchestrator_subagents_list_matches_disk: Subagents bullet list
must equal set(agents/seo-*.md); no duplicates. Bullet-anchored regex.test_skill_metadata_versions_match_plugin_json: every
skills/*/SKILL.md and extensions/*/skills/*/SKILL.md metadata.version
must equal plugin.json version, with COMMUNITY_OVERRIDES allowlist
{"seo-content-brief": "1.0.0"}. Scoped to YAML frontmatter only via
a new _extract_frontmatter() helper, so a fenced code example showing
version: "..." cannot satisfy the check.test_marketplace_metadata_and_author_parity: marketplace.json
metadata.description includes both counts and they match plugin.json;
plugin entry author parities plugin.json author for name, email,
AND url.tests/test_lazy_detection.py (new): 11 unit tests covering all
_detect_lazy_method() branches plus an integration check on parse_html()..github/workflows/ci.yml): test job now installs
beautifulsoup4 alongside pytest, required by the new lazy-detection
test that exercises real BeautifulSoup parsing.| Package | Floor before | Floor after | Source PR |
|---|---|---|---|
playwright |
1.56.0 | 1.59.0 | #80 |
weasyprint |
61.0 | 68.1 | #78 |
openpyxl |
3.1.0 | 3.1.5 | #76 |
google-api-python-client |
2.100.0 | 2.196.0 | #77 |
google-auth-oauthlib |
1.0.0 | 1.4.0 | #79 |
All five upper bounds preserved. No CVE-driven escalations.
Caveat: google-auth-oauthlib 1.4.0 drops Python 3.9 support. This
repo's pyproject.toml requires Python >=3.10 already, so no impact for
the declared support matrix. External consumers still on 3.9 should pin
google-auth-oauthlib<1.4.0 themselves.
The following items are out of scope for v1.9.9 to keep this a clean patch release. v2 will be a separate design conversation:
seo-audit, seo-drift, seo-cluster)google_report.py --type full audit-schema handling (no regression
baseline fixture corpus exists; v2 will ship one with the bug fix)requirements.txt format as migration headroom)pip-system-certs is a new
dependency that violates v1.9.9's no-new-deps non-goal. v2 will land the
full macOS support story.seo-content-brief, removal of seo-firecrawl). Any downstream consumer
that referenced sub-skills by index rather than name would break;
grep found no such consumer in this repo, but third-party docs that
hard-coded "skill 21 is seo-firecrawl" would need updating./seo audit still does NOT persist subagent research/findings between
runs (this is the intentional v1.x contract; v2 will revisit per #51).seo-content-brief skill
was merged into v1.9.7 it added a 21st core skill, but the manifest
reconciliation in v1.9.7 had locked the canonical phrasing at "20 core" and
was not re-run after Phase C. Result: plugin.json, marketplace.json,
README.md, CLAUDE.md, AGENTS.md, and docs/ARCHITECTURE.md all under-claimed
by one. Reconciled to "25 sub-skills (21 core + 1 orchestrator + 1 framework
integration + 2 extension mirrors)".tests/test_manifest_consistency.py: pytest suite that asserts
plugin.json + marketplace.json claimed counts match the actual on-disk
count of skills/*/SKILL.md and agents/seo-*.md, that plugin.json and
marketplace.json descriptions agree on the canonical math, that user-visible
docs (README, CLAUDE.md, AGENTS.md) reference the same skill count, and that
plugin.json version and CITATION.cff version triangulate. Closes the
systemic gap that allowed two skill-count drift incidents in v1.9.7.pytest tests/ job in .github/workflows/ci.yml: runs the new manifest
consistency suite on every push to main and every pull request, gating
future skill additions behind matching documentation updates.uninstall.sh and uninstall.ps1 now use glob enumeration rather than a
hardcoded skill list. The previous scripts had been frozen at v1.4.0-era
state and missed 12 sub-skills and 11 sub-agents added between v1.5 and
v1.9.8 (seo-backlinks, seo-cluster, seo-content-brief, seo-dataforseo,
seo-drift, seo-ecommerce, seo-flow, seo-google, seo-image-gen,
seo-local, seo-maps, seo-sxo and the corresponding agents). Anyone who
ran the old uninstaller got half a cleanup. Glob enumeration auto-tracks
future skill additions without requiring uninstaller maintenance. Sandbox
test confirms the new scripts remove every seo and seo-* skill plus
every seo-*.md agent while leaving sibling skills (e.g. blog-writer,
security) untouched.8514999: marketplace metadata polish (added category: "marketing",
homepage: https://claude-seo.md, and a 14-keyword array to the
marketplace.json plugin entry). The author object for the plugin entry
was intentionally scoped here too but did not land in this commit; it
lands in v1.9.9 (issue #92).66a7485: em-dash sweep on user-visible AGENTS.md and CHANGELOG.md
Both were intentionally scoped at v1.9.7 but landed post-tag. v1.9.8 captures
them properly.plugin.json ("20 core sub-skills"),
marketplace.json ("21 core sub-skills"), CLAUDE.md line 7 ("21 core sub-skills"),
AGENTS.md line 8 ("20 core sub-skills") + line 84 ("23 skills"), and README.md
line 7 ("21 core sub-skills") all contradicted each other. Reconciled to canonical
phrasing: "24 sub-skills (20 core + 1 orchestrator + 1 framework integration +
2 extension mirrors)".CLAUDE.md claimed "16 core subagents (+ 2 extension
agents, 18 total)" while AGENTS.md claimed "15 core subagents (+ 2 extension
agents, 17 total)". Reconciled to: "18 sub-agents (15 core + 1 framework integration +
2 extension mirrors)".CLAUDE.md self-contradiction: line 23 stated plugin.json (v1.9.0); updated
to current v1.9.7.marketplace.json description fields: both metadata.description (top-level)
and plugins[0].description now use canonical phrasing.CITATION.cff version drift: was stuck at 1.8.2 (six minor versions behind);
bumped to match plugin.json at 1.9.7 with current release date..github/dependabot.yml: weekly Dependabot updates for pip and GitHub Actions
ecosystems (closes supply-chain hygiene gap).CODE_OF_CONDUCT.md: Contributor Covenant 2.1, closing GitHub Community
Standards gap..github/workflows/ci.yml permissions: block: restricts GITHUB_TOKEN to
contents: read at workflow root (least-privilege; was previously default scope).translations/uk/: the Ukrainian localization (originally contributed by
@edocltd in PR #50, shipped in v1.9.0) has been retired. The translation drifted
across v1.9.0 to v1.9.7 with no maintenance signal, and a partially translated set
is worse than no translation at all when readers cannot tell what is current.
@edocltd's contribution remains credited in CONTRIBUTORS.md. If a maintained
translation is desired in the future, it should land via a contributor who can
commit to keeping it in sync release over release.Bash from seo-flow agent tool grant, agent no
longer has shell access, eliminating prompt-injection-to-shell attack surfacesync_flow.py to anonymous-first GitHub API
requests; PAT only used as 403-triggered fallback, eliminates token-on-redirect leakPath.resolve() containment check in record_write(),
blocks path-traversal writes outside the skill reference directoryflow-prompts.lock SHA-256 baseline file; sync now
diffs against baseline and reports upstream drift before writinggh CLI absence now degrades to anonymous API rather than
hard-exiting, sync works without gh CLI on public reposapi.github.com
over HTTPS, blocks SSRF if API_ROOT constant is modifiedreferences/prompts/README.mdskills/seo-flow/references/prompts/ (find:5, leverage:1, optimize:21, win:3, local:11). Commands: /seo flow [find|leverage|optimize|win|local|prompts|sync]./seo flow optimize selects 2-3 most relevant prompts from 21 based on URL industry signals and prior skill output, not a full dump.scripts/sync_flow.py: GitHub API sync script, pulls latest FLOW prompts, framework doc, and bibliography from AgriciDaniel/flow. Supports --dry-run and --ref <sha> pinning. Outputs JSON summary.agents/seo-flow.md: FLOW subagent, applies stage prompts to target URLs, returns structured evidence-tagged findings.sync_flow.py). Claude SEO's MIT license unchanged, applies to skill code only.scripts/dataforseo_costs.py with threshold-based approval, session budget tracking, daily spend summaries. references/cost-tiers.md pricing table. Contributed by Matej Marjanovic.schema/templates.json/seo cluster, /seo sxo, /seo drift baseline|compare|history, /seo ecommerce/seo backlinks, /seo firecrawl, /seo dataforseo, /seo image-genirm | iex pattern from docs/INSTALLATION.md, replaced with safe git clone + powershell -File method>=3.11 to >=3.10 (matches README and install scripts)/seo dataforseo serp-images <keyword> command for competitive image search analysis/seo images serp <keyword> cross-skill command combining DataForSEO image results with on-page audit/seo images optimize <path> for WebP/AVIF conversion, IPTC/XMP metadata injection, responsive variants, and compressionserp.items.images filter with 10 SEO-relevant fields (type, rank, title, alt, url, source_url, image_url, domain, encoded_url)skills/seo-dataforseo/references/tool-catalog.md for 35+ utility MCP tools (moved from inline list)seo-image-gen/references/prompt-engineering.md (326 lines, per >300 line standard)image-serp, google-images added to plugin.jsonskills/seo/references/backlink-quality.md (shared reference)~/.claude/skills/ from agents/seo-visual.md, agents/seo-schema.md, skills/seo-image-gen/SKILL.md, and banana extension copy (now use plugin-relative paths)extensions/firecrawl/)skills/seo-backlinks/SKILL.md with /seo backlinks commandskills/seo/references/backlink-quality.md with 30 toxic link patterns, anchor text benchmarks by industry--format xlsx option in scripts/google_report.pyxlsx, all (pdf+html+xlsx)/seo backlinks and /seo firecrawl commandsmap used for URL discovery when availablerequirements.txt: added openpyxl>=3.1.0 for Excel exportseo/ corrected to skills/seo/ (h/t @hieu-e via #39)seo/ fallback path, uses skills\seo directlyskills/seo-google/SKILL.md with 21 commands across 4 credential tiersagents/seo-google.md for enriched audit data (CWV field data, indexation status, organic traffic)scripts/google_report.py with enterprise A4 template, WeasyPrint + matplotlib charts, post-generation quality reviewvalidate_url() blocks private IPs, loopback, and GCP metadata endpoints in all Google API scripts.gitignore hardened with 8 credential patterns: .env, client_secret*.json, oauth-token.json, service_account*.jsonclient_secret (reads from client_secret.json file only).claude-plugin/marketplace.json for plugin marketplace submission. Users can now install via /plugin marketplace add AgriciDaniel/claude-seomodel: sonnet and maxTurns (15-25) for predictable cost and behaviorplugin.json for marketplace searchabilityseo/ orchestrator to skills/seo/ for auto-discovery compliance. Extension skills (seo-dataforseo, seo-image-gen) and agents copied to standard skills/ and agents/ directoriesentry_point field and individual file-path arrays for skills/agents. All 17 skills and 11 agents now rely on directory auto-discovery per Anthropic plugin speclicense: MIT and metadata: block (author, version, category) to all SKILL.md frontmattersseo/references/ to skills/seo/references/claude plugin validate . now passes cleanly (previously would fail on non-standard fields)skills/seo-local/SKILL.md for GBP, NAP, citations, reviews, and map pack analysisskills/seo-maps/SKILL.md for geo-grid rank tracking, GBP auditing, review intelligence, competitor radius mappingagents/seo-maps.md for parallel maps analysis during auditsagents/seo-local.md for parallel local SEO analysisuser-invokable, argument-hint, and allowed-tools added to all SKILL.md files per Anthropic best practices.claude-plugin/plugin.json updated with all skills and agents registeredpyproject.toml with project metadata<!-- Updated: ... --> comments from SKILL.md files that preceded the YAML frontmatter delimiterirm | iex Windows PowerShell one-liner with git clone + powershell -File as primary install method. Claude Code's own security guardrails flagged the old pattern as a supply chain risk (reported by community member). Added collapsible "review before running" section for Unix curl method.install.sh and install.ps1 now clone a specific release tag (v1.3.0) by default rather than main, preventing silent updates. Override with CLAUDE_SEO_TAG=main.PSNativeCommandUseErrorActionPreference handling in Invoke-External wrapper (fixes Windows git clone stderr false-positive termination, from PR #13 + PR #15).agents/seo-geo.md created -- /seo audit now spawns 7 parallel agents (was 6). GEO analysis covers AI crawler access, llms.txt, passage-level citability, brand mention signals, platform-specific scoring (Google AI Overviews, ChatGPT, Perplexity, Bing Copilot).--googlebot flag in fetch_page.py: Detect prerender/dynamic rendering services by comparing response size with default UA vs Googlebot UA. First phase of SPA/CSR support (Issue #11).capture_screenshot.py and analyze_visual.py now accept bare domains (example.com -> https://example.com) via shared normalize_url() helper (from PR #16 by @shuofengzhang).seo/SKILL.md, agents/seo-schema.md, seo/references/schema-types.md.seo-geo to uninstall.sh and uninstall.ps1 removal lists.3.8+ to 3.10+ in README.md and docs/INSTALLATION.md..gitignore: Added generated audit artifacts (charts/, PDFs, report.html, firebase-debug.log, generated-schema.json)extensions/ directory convention for self-contained add-ons with install/uninstall scripts./extensions/dataforseo/install.sh.claude-plugin/plugin.json for official plugin directory submissioncapture_screenshot.py (defense-in-depth, matching fetch_page.py)allowed-tools from main SKILL.mdClaudeSEO/1.0 to Chrome-like string with ClaudeSEO/1.2 suffix. SSR frameworks (Next.js, Nuxt, Angular) now pre-render properly instead of serving empty client-side shells (#9)--user-agent flag to fetch_page.py for configurable UA stringscurl install.cat/AgriciDaniel/claude-seo | bash to README (#10)fetch_page.py and analyze_visual.pycapture_screenshot.py and file validation to parse_html.py--break-system-packages, switched to venv-based pip install~/.claude/skills/seo/ for user retry--- delimiter in 8 files (skills: seo-content, seo-images, seo-programmatic, seo-schema, seo-technical; agents: seo-content, seo-performance, seo-technical). Thanks @kylewhirl for identifying this in the codex-seo fork.python3 -m pip, py -3 launcher fallback, requirements.txt persistence, non-fatal subagent copy, better error diagnostics (PR #6)~/.claude/skills/seo/.venv/ with --user fallback (#2)Resolve-Python helper for robust Python detection (#5)scripts/, references/, assets/claude (not claude-code)