=== Hafen Core ===
Contributors: hafenstudios
Tags: ai, ai-crawler, schema, structured-data, blocks
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

The companion plugin for the Hafen theme. JSON-LD schema, answer blocks, AI crawler policy, local AI traffic stats, Markdown delivery and llms.txt.

== Description ==

**The companion plugin to the [Hafen theme](https://wordpress.org/themes/hafen/).**
Following the principle "theme = presentation, plugin = functionality", Hafen
Core carries the functionality that, per the WordPress.org guidelines, does
not belong in a theme: a schema engine, five answer blocks, an AI crawler
policy for robots.txt, a local AI traffic dashboard, Markdown delivery for
agent clients, a citability linter, an under-construction gate and an
llms.txt file. It works with any theme, but it is built and tested as the
functional half of Hafen.

**Access rules and measurement in one plugin.** Most plugins in this field do
one of the two: they either block AI crawlers, or they report on AI visibility
from an external service. Hafen Core does both in the same place and can
therefore relate them to each other, for example: "Perplexity is not crawling
you, and PerplexityBot is on your block list." Everything runs on your own
installation; no account and no external service are required for it.

**No invented scores.** This plugin does not calculate a visibility score
and does not promise you a placement in ChatGPT. Where the evidence is thin, it
says so: llms.txt is labeled as speculative, every rule in the citability
linter states its evidence strength and its source, and where a provider
publishes no IP ranges we do not present a user agent as proof. The most honest
sentence first: the strongest documented factor for citations is mentions of
your brand elsewhere. On-page is the smaller lever. Everything this plugin does
works on that smaller lever – but it does so cleanly and verifiably.

**Schema engine.** Automatically embeds valid JSON-LD without you writing
anything: Organization, WebSite (including the search action), Article (on
posts) and BreadcrumbList. Plus FAQPage and HowTo generated from the answer
blocks. Everything in a single @graph in the document head.

**Answer engine blocks.** Five blocks that render nicely for humans while
being machine-readable and privacy-friendly:

* Hafen FAQ — emits FAQPage schema.
* Hafen HowTo — emits HowTo schema.
* Hafen TL;DR — highlighted short answer.
* Hafen Definition — a term in what-is-X format.
* Hafen Video (2-click) — privacy-friendly YouTube embed that loads only
  after a click, via youtube-nocookie.com.

**Access gate (Under Construction).** Protect the whole website with a
password while it is being built – without an extra plugin. Three bundled
templates (light, dark, accent gradient) automatically pick up your logo, your
site name and your accent color. Logged-in users see the website normally, the
gate page sends HTTP 503 + noindex (safe for SEO), and the WordPress logo on
login pages is replaced with your site logo.

**AI crawler policy.** The whole market treats AI crawlers as a threat to be
locked out. Hafen Core does the opposite: it helps you get found and cited. To
do that, it cleanly separates what almost everyone conflates: training (GPTBot,
ClaudeBot, CCBot), search/index (OAI-SearchBot, Claude-SearchBot,
PerplexityBot, Googlebot) and live retrieval by a human in a chat
(ChatGPT-User, Claude-User, Perplexity-User). Blocking training costs NO
visibility. Blocking search costs all citability. The interface prevents
exactly that mistake, with plain-language warnings instead of fine print.
Default: nothing blocked. This is not a blocker plugin.

**AI traffic dashboard, entirely local.** Shows which AI bots fetch your
content, which pages they crawl the most, how many visitors come back from AI
answers, and the key figure: crawl-to-refer, i.e. how many pages a provider
fetches before it sends you one visitor. No account, no cloud, no IP addresses
in the database. If you enable the optional OpenAI bot verification, hits from
GPTBot & Co. are checked against the official IP ranges; where a provider
publishes none (Anthropic, Perplexity, Meta), the dashboard says so openly
instead of presenting a user agent string as proof.

**IndexNow.** Reports new and changed content immediately to Bing and
participating search engines instead of waiting for the next crawl. Relevant
because ChatGPT's web answers are backed by the Bing index. Off by default
(opt-in).

**Markdown for agents.** Agentic clients (Claude Code, Cursor, OpenCode)
request pages with "Accept: text/markdown". Hafen Core answers with a clean
Markdown version of your content, alternatively via ?format=md or the .md
suffix. That saves the model the layout, navigation and script ballast. The
Markdown version is sent with "X-Robots-Tag: noindex", and "Vary: Accept" is
placed specifically on the responses that can also be served as Markdown, so
no page cache serves the Markdown version to browsers – and on no other
response, so proxy caches do not fragment unnecessarily. Only published,
publicly visible, non-password-protected content is served.

**Citability linter in the editor.** Checks the post against 15 rules and
shows, per rule, whether it passes and how well it is supported by evidence
(strong / medium / weak), including the source. Deliberately WITHOUT a 0–100
score: nobody knows a citation probability, and we do not pretend to. It also
includes a check for prompt injection and cloaking, because that is a penalty
issue, not an optimization issue. The optional AI deep check uses the AI
assistant and is not a requirement: all rules run without AI as well.

**Abilities API and WebMCP.** Where WordPress ships the Abilities API (6.9+),
Hafen Core registers read-only abilities (page as Markdown, search content) as
well as the AI assistant's generators; only the read-only ones are exposed to
MCP. On top of that come read-only WebMCP browser tools. Honest framing:
WebMCP is a Chrome experiment and only has an effect while the tab is open.
Crawlers see none of it; it does nothing for visibility. A tiny snippet loads
the script only in browsers that actually have the API; everyone else pays 0
additional requests. Both are pure feature detection, not a dependency.

**llms.txt generator.** Publishes a curated content map at /llms.txt (and
/llms-full.txt). Honest framing: Google states that it ignores llms.txt, and
measurements show AI systems practically never fetch the file. Useful for
coding agents, not for visibility in AI search. We ship it because it costs
nothing, and we promise nothing for it.

**Performance status.** Speed is a core commitment of the Hafen family. The
dashboard (Settings > AI Traffic) therefore shows honestly what your setup
delivers: page cache detected or not, compression via self-test, the theme's
font mode (variable/static/system) – each with a plain-language
recommendation. Plus an option to disable the WordPress emoji script (~26 KB
and one external request to s.w.org saved; off by default). Cache and
compression are server matters no plugin can solve from the inside. That is
exactly why we display them instead of making promises.

Everything runs without a build step and is GDPR-friendly. Schema, blocks and
llms.txt work entirely locally. External connections only occur for features
you explicitly enable or trigger: the optional AI assistant (through the
WordPress AI client, provider and key configured under Settings > Connectors,
only on click), the optional OpenAI bot verification (IP ranges, off by
default), IndexNow (opt-in) and the video block (YouTube, only after a
click). Details under "External services".

== Installation ==

1. Upload and activate the plugin (Plugins > Add New > Upload).
2. After activation, /llms.txt is immediately available and the schema is active.
3. Under Settings > Hafen Core, adjust the organization name, logo and the
   switches for schema, llms.txt, traffic measurement and IndexNow.
4. Under Settings > AI Crawler Policy, define which AI bots are allowed.
   Recommended: "Do not train, but cite". Default: everything allowed.
5. Under Settings > AI Traffic, see who fetches your content and who sends
   visitors back in return.

== Frequently Asked Questions ==

= Do I need the Hafen theme? =
No. The blocks, the schema and llms.txt work with any theme. With the Hafen
theme they share design tokens and look like one consistent whole.

= Does the schema collide with an SEO plugin? =
No. In auto mode (default), Hafen Core detects common SEO plugins (Yoast,
Rank Math, SEOPress, All in One SEO, The SEO Framework, Slim SEO, Squirrly)
and steps back where schema overlaps: it leaves Organization, WebSite, Article
and Breadcrumb to the SEO plugin and only outputs FAQPage/HowTo generated from
the Hafen answer blocks. The mode can be changed under Settings > Hafen Core
(Auto / Full / Answer schema only / Off). Fine-grained control via the
hafen_core_schema_nodes filter.

= Are external services contacted? =
Schema, llms.txt, crawler policy, Markdown delivery, the citability linter
(without the deep check) and the traffic dashboard work entirely locally.
External connections only occur for features you explicitly enable: the AI
assistant including the linter's optional AI deep check (through the
WordPress AI client and the connector you configured), IndexNow (opt-in),
the optional OpenAI bot verification (Settings > AI Traffic; when enabled it
fetches OpenAI's public IP ranges weekly) and the video block (YouTube, only
after a click). Without these consents the plugin makes not a single
external call on its own. Details under "External services".

= Does the plugin block AI bots? =
Only if you explicitly configure it to. The default blocks nothing.
Recommended is "Do not train, but cite": turn away training bots, leave
search and retrieval bots open. And the honest limitation right away:
robots.txt is a request, not a lock. Whoever ignores it is not stopped by it;
real protection requires a WAF or a CDN. Agentic browsers (ChatGPT Agent,
Perplexity Comet, Claude for Chrome) send no bot token at all and cannot be
addressed via robots.txt in principle.

= Does Google-Extended prevent the AI Overviews? =
No, and this is the most widespread misconception in this field.
Google-Extended is purely an opt-out token for Gemini training. The AI
Overviews draw from the regular Googlebot index.

= Why are my bot numbers lower than in my server logs? =
Because a full-page cache (WP Rocket, LiteSpeed, W3 Total Cache, WP Super
Cache, Varnish, Nginx FastCGI, Cloudflare APO) serves the finished page
without PHP running. No WordPress plugin sees those hits, not even a
mu-plugin. The dashboard detects common cache plugins, displays the
measurement quality openly (three states, including "INCOMPLETE") and sets up
the required user agent exception – automatically for WP Rocket, otherwise
with a ready-made list to paste. The only gap-free method remains analyzing
the server access logs; this plugin cannot and does not try to do that.

== External services ==

The optional AI assistant generates suggestions (meta description, TL;DR,
FAQ) from your post content. All requests run through the WordPress AI
client (WordPress 7.0+): which provider receives the data, and with which
key, is configured centrally under Settings > Connectors. The plugin itself
does not contact any AI provider directly. Data is sent ONLY if you (a)
enable the assistant under Settings > Hafen Core and (b) click a suggestion
button in the editor; the post's title and text then go to the connector you
configured. The same applies to the optional AI deep check of the citability
linter: only if you explicitly tick "AI deep check" in the editor and start
the check, an excerpt of the post (at most 5,000 characters) is sent to your
configured connector. Without that checkbox the linter runs entirely locally
and rule-based. On installations without a configured WordPress AI client,
both features stay inactive.

The "Hafen Video (2-click)" block embeds YouTube videos in a
privacy-friendly way: before the click, nothing is loaded from YouTube (no
thumbnail, no request). Only when visitors click the play area is an iframe
loaded from https://www.youtube-nocookie.com; at that point data is
transmitted to Google. The notice text on the play area informs about this.

YouTube terms of service: https://www.youtube.com/t/terms
Google privacy policy: https://policies.google.com/privacy

IndexNow (Microsoft Bing): if you enable IndexNow under Settings > Hafen Core
(off by default), the plugin reports the affected URL to
https://api.indexnow.org/indexnow when content is published or updated. Sent
are exclusively: the URL of the public content, your hostname, the locally
generated IndexNow key and the location of the key file. No content, no user
data and no visitor data are transmitted. Without this activation nothing is
sent.

IndexNow terms of use: https://www.indexnow.org/terms
Microsoft privacy statement: https://privacy.microsoft.com/privacystatement

OpenAI IP ranges (bot verification, opt-in): OFF by default. Only if you
explicitly enable the OpenAI bot verification under Settings > AI Traffic
does the plugin fetch the public IP lists https://openai.com/gptbot.json,
https://openai.com/searchbot.json and https://openai.com/chatgpt-user.json
weekly via cron, to check whether a hit really comes from OpenAI and does not
merely fake its user agent. This is a pure download; no data of yours is
transmitted in the process. The check itself runs locally. Without this
activation not a single fetch is made.

OpenAI terms of use: https://openai.com/policies/terms-of-use
OpenAI privacy policy: https://openai.com/policies/privacy-policy

== Privacy ==

The AI traffic measurement writes to its own table ({prefix}hafen_ai_hits).
It stores exclusively: timestamp, bot or source identifier, purpose
(training, search, live retrieval, referral), the ID of the requested post, a
hash of the path and a yes/no verification field.

Explicitly NOT stored: IP addresses, user agent strings, cookies, session
identifiers or any other personal data. The IP address is only checked in
memory against the official provider IP ranges and discarded afterwards.
Logged-in users are not recorded at all. Retention is limited to 90 days by
default (configurable between 7 and 365 days); a daily cron run deletes older
entries. No data is transmitted to hafenstudios or third parties.

== Copyright ==

Hafen Core, (C) 2026 hafenstudios.
Hafen Core is distributed under the GNU General Public License v2 or later.

All bundled assets are GPL-compatible:

* assets/mascot/captain-*.webp — brand mascot "Kapitän Ahoi": original work by
  hafenstudios, created with AI assistance (OpenAI ChatGPT/DALL·E). No
  third-party templates or stock images were used. (C) 2026 hafenstudios,
  released under GPLv2 or later.
* All icons are inline SVG, an original set, (C) 2026 hafenstudios, GPLv2 or
  later.
* No font files, libraries or third-party assets are bundled.

== Screenshots ==

1. Settings > Hafen Core – schema mode, organization, llms.txt and performance switches.
2. AI crawler policy – the bot matrix by purpose (training, search/index, live retrieval) with plain-language warnings before every block.
3. AI traffic dashboard – hits per bot, crawl-to-refer ratio per provider and the measurement quality indicator.
4. Access gate (Under Construction) – one of the three bundled templates with automatically applied logo and accent color.
5. The four answer engine blocks in the editor: FAQ, HowTo, TL;DR and Definition.
6. The optional AI assistant in the editor sidebar (meta description, TL;DR and FAQ suggestions).

== Changelog ==

= 1.0.0 =
The WordPress.org release.

* The AI assistant now runs exclusively through the WordPress AI client
  (Settings > Connectors, WordPress 7.0+). The former bring-your-own-key
  path with direct provider requests has been removed.
* English is now the source language: all admin and frontend strings, the
  readme, and the block metadata. Translations will be provided through
  translate.wordpress.org.
* Setup wizard no longer replaces an existing static homepage. If one is
  configured, it is kept and the wizard says so; switching remains a
  deliberate step under Settings > Reading.
* llms.txt: tags no longer glue words together, leftovers of unregistered
  shortcodes are removed, untitled posts fall back to their URL, and
  llms-full.txt now carries real content sections (up to 800 words per
  entry, filterable via hafen_core_llms_full_words) instead of the same
  24-word excerpts as llms.txt.
* robots.txt: the Content-Signal line now joins the existing
  "User-agent: *" group instead of opening a second one, which some
  parsers discard.
* Schema: no more BreadcrumbList on the front page, where position 1 and
  the last entry were identical.
* AI assistant prompts follow the site language instead of being
  hard-coded German.
* New: a review link in the plugin row and a one-time review request
  after the first recorded AI visit or the first served llms.txt — one
  link for everyone, no rating filter.
* Third-party admin notices are removed on the plugin's own screens.
* The wizard's plugin step now offers only extensions that actually
  resolve in the WordPress.org directory (hafenstudios-ads today;
  others appear as they are approved).

= 0.9.0 =
WordPress.org submission: opt-in instead of automatism where it matters.
* Fix: The weekly fetch of the public OpenAI IP ranges (for bot verification)
  previously ran automatically as soon as AI traffic measurement was active
  (default: on) – an external call without explicit consent. New switch
  "OpenAI bot verification" under Settings > AI Traffic, OFF by default. The
  associated cron is only registered while the switch is active and is
  cleanly removed when it is turned off.
* New: The logo plate in the access gate now derives its color from the logo
  instead of hard-coding white (F10). Opaque near-white logos (e.g.
  Canva/Office exports with a background like #F5F5F1) previously produced a
  visible edge on the white plate. The color is sampled once per logo and
  cached; the fallback remains white (no image access possible or the logo is
  transparent). Filterable via hafen_core_gate_logo_plate_color.
* Updated: The AI assistant's model list (Claude Opus 5, Claude Sonnet 5,
  Claude Haiku 4.5); the default is now the lowest-cost model (Haiku 4.5)
  instead of the most expensive one, so a freshly enabled assistant does not
  cause high costs unasked.
* Cleanup: The remaining inline <style> outputs (login logo, access gate,
  accent color/footer credit in the frontend) now go through
  wp_add_inline_style() instead of a hand-built <style> tag; the access gate
  page loads its CSS from assets/gate.css. Table names in the plugin's own
  $wpdb queries are now bound via %i instead of interpolated.
* Display name shortened; slug and text domain (hafen-core) unchanged.
* New: languages/hafen-core.pot regenerated.

= 0.8.1 =
Security fix: the access gate only applied to normal page views. Everything
WordPress serves through other routes remained reachable unprotected, even
though the actual page correctly showed the under-construction page with
HTTP 503.
* Fix: The REST API (e.g. /wp-json/wp/v2/pages) served the full content of
  gated pages unchanged. A new latch using REST's own authentication signal
  now rejects REST requests with HTTP 503 while the access gate is active and
  the visitor has not yet passed it. Logged-in users and visitors with a
  valid access cookie are exempt, so nothing breaks in normal operation.
* Fix: llms.txt/llms-full.txt as well as the optional IndexNow key file ran
  ahead of the access gate in execution order and were therefore served
  before it could take effect. The access gate now checks first of all.
* Fix: The Markdown delivery for AI agents (Accept: text/markdown,
  ?format=md, .md suffix) had the same flaw for the same reason and served
  the complete page content despite the active access gate.
* Fix: /wp-json/wp/v2/users (and the plain ?rest_route= variant) exposed
  usernames. This route now stays closed additionally, even for visitors
  with a valid access cookie, while the access gate is active.
* New: Emergency off switch for the access gate, independent of the stored
  setting – constant HAFEN_CORE_GATE_DISABLED in wp-config.php or filter
  hafen_core_gate_disabled.
* Checked and unchanged: normal pages, RSS/Atom feeds, robots.txt,
  wp-sitemap.xml and the classic ?author=1 redirect were already correctly
  gated (they run only AFTER the branch point where the access gate ends the
  request).

= 0.8.0 =
First impressions: no more error message, no empty pages, no bare
"No data yet." lines.
* Fix: The assistant step "Recommended extensions" offered plugins that do
  not yet exist in the WordPress.org directory. The result was the same for
  every user: click, error message. The assistant now queries the directory
  first (response cached for 12 hours) and only shows what can actually be
  installed. If nothing is available, the step is skipped entirely; progress
  bar and step counter adjust automatically.
* Improvement: The starter pages are now built from the theme's real
  patterns. "Contact" previously got a bare heading and nothing else; now it
  contains the complete contact section with address, phone, e-mail and
  opening hours. The markup is inserted inline, not as a pattern reference:
  that way it can be edited normally in the editor and survives a theme
  switch.
* Improvement: The empty states in the AI traffic dashboard now explain what
  is measured, name a realistic time horizon and say that an empty report is
  normal for new sites. Previously the page showed "No data yet." three times
  in a row.
* Improvement: The reporting period (30 days) is now stated in the headings.
  Without it, no number on the page could be put into context.
* Improvement: New shared admin styles (assets/admin-tokens.css) group the
  sections into cards. They style exclusively the plugin's own Hafen classes,
  without overriding WordPress core elements.
* languages/hafen-core.pot regenerated: the strings from the access gate
  (class-access-gate.php) and the login logo (class-login-logo.php) had not
  been extracted before and were therefore not translatable.

= 0.7.2 =
Performance package (together with Hafen theme 0.3.1: variable font and
system font variation "Stapellauf").
* New: Performance status in the AI traffic dashboard. Shows honestly what
  the setup delivers: page cache detected/not detected, compression via
  self-test (gzip/Brotli, result cached for 12 h, never runs in the
  frontend) and the active theme's font mode (variable/static/system). With
  a plain-language recommendation per item, because cache and compression
  are server matters no plugin can solve from the inside.
* New: Option "Disable WordPress emoji script" (Settings > Hafen Core >
  Performance, also via REST). Saves ~26 KB and the external request to
  s.w.org. OFF by default, so WordPress behaves as usual.
* Performance: webmcp.js is no longer loaded unconditionally. An inline
  snippet (under 300 bytes) loads the script only in browsers that actually
  have the WebMCP API. For everyone else: 0 additional requests.
* Fix: The "Vary: Accept" header is now only sent on responses that can also
  serve the same URL as Markdown (servable single views) instead of on every
  frontend response. Vary on everything fragments LiteSpeed/proxy caches
  with no benefit. At the same time, moved from the too-early send_headers
  hook to template_redirect (priority 0).

= 0.7.1 =
* Access gate polish: the logo now sits on a white "plate" (which also makes
  logos without a transparent background look right on dark templates), a
  gentle fade-in animation (respects prefers-reduced-motion), a wave
  silhouette at the page footer, focus ring and button glow in the accent
  color, a shake animation on a wrong password. The dark template's second
  background glow now follows the accent color instead of fixed indigo.

= 0.7.0 =
* New: Access gate (Under Construction). Protects the whole website with a
  password and shows visitors one of three bundled templates (Helle Werft,
  Nachtfahrt, Horizont) – with your site logo, site name and your accent
  color, without an external password protection plugin. Logged-in users see
  the website normally; visitors with the password receive a cookie (3 days,
  filter `hafen_core_gate_cookie_days`). The password is stored only as a
  hash, honeypot + rate limit against brute-forcing, the gate page sends
  HTTP 503 + Retry-After + noindex (safe for SEO). Settings > Hafen Core,
  including an admin preview link.

= 0.6.1 =
* New: Login logo. If a site logo is set (Appearance > Site Logo), it
  replaces the WordPress logo on wp-login.php and on the login page of the
  "Password Protected" plugin; the logo links to the homepage instead of
  wordpress.org. Without a logo set, nothing changes. Can be disabled via
  the `hafen_core_login_logo` filter.

= 0.6.0 =
The core of this release: we help you get found and cited instead of locking
AI crawlers out. Without invented numbers, with clearly named limitations.

* New: AI crawler policy (Settings > AI Crawler Policy). All relevant bots,
  grouped by purpose: training, search/index, live retrieval by users. One
  switch each, default "everything allowed". Two presets: "Maximum
  visibility" and "Do not train, but cite" (recommended). Output via the
  robots_txt filter. Anyone who wants to block a search or retrieval bot is
  told in plain language beforehand what that destroys. An existing physical
  robots.txt is detected and reported openly, because the filter does not
  apply then.
* New: AI traffic dashboard (Settings > AI Traffic), 100% local, no account.
  Hits by bot and purpose, most-crawled content, visitors from AI answers
  (referrer and utm_source=chatgpt.com) and the crawl-to-refer ratio per
  provider, put into context with the known industry figures. Coupled to the
  policy: if a blocked search bot has zero hits, the dashboard says exactly
  that instead of leaving you guessing.
* New: Bot verification against spoofing. Hits from OpenAI are checked
  against the official IP ranges (fetched weekly via cron, cached locally),
  Googlebot and Applebot optionally via reverse DNS with forward
  confirmation. Where a provider publishes nothing (Anthropic, Perplexity,
  Meta), it openly says "not verifiable". A user agent string is not proof.
* New: Honest measurement quality indicator. With a full-page cache PHP does
  not run, and no plugin sees the bot hits. The dashboard detects WP Rocket,
  LiteSpeed, W3 Total Cache, WP Super Cache and Cloudflare, names the state
  (complete / complete with exception / INCOMPLETE) and sets up the user
  agent exception: automatically for WP Rocket via the
  rocket_cache_reject_ua filter, otherwise with a ready-made list to paste.
* New: IndexNow (opt-in). Reports new and changed content immediately to
  Bing and participating search engines, with a locally generated key at
  /{key}.txt, debounce against ping floods and a status display of the last
  ping.
* Privacy: own table {prefix}hafen_ai_hits without IP addresses and without
  personal data, retention 90 days by default, daily cleanup via cron. See
  the "Privacy" section.
* New: Markdown delivery for agents (content negotiation via
  "Accept: text/markdown", ?format=md and the .md suffix). Own HTML-to-
  Markdown converter without Composer; the Hafen blocks are rendered
  semantically, not via the HTML detour. "Vary: Accept" is sent on every
  response so a page cache does not serve the Markdown version to browsers;
  the Markdown response itself is sent with "X-Robots-Tag: noindex". Only
  published, publicly visible, non-password-protected content is served.
* New: Citability linter in the editor. 15 rules, each with evidence
  strength (strong / medium / weak) and source, explicitly WITHOUT a 0–100
  score. Includes a check for prompt injection and cloaking. The AI deep
  check for the two rules that are fuzzy under pure rules is optional and
  not a requirement.
* New: Abilities API (WordPress 6.9+, pure feature detection): read-only
  abilities (page as Markdown, search content) plus the AI assistant's
  generators. Only the read-only ones are exposed to MCP.
* New: WebMCP browser tools, strictly read-only (the contact form is at most
  prefilled, never submitted). Honestly framed: a Chrome experiment, only
  effective while the tab is open, does nothing for visibility.
* Honesty instead of marketing: llms.txt is now correctly framed in the
  interface (speculative standard, ignored by Google according to Google
  itself, practically never fetched, useful for coding agents). The feature
  stays; only the promise is dropped.
* Correction: /llms.txt could include password-protected posts along with an
  excerpt of the raw content. They are now excluded.

= 0.5.1 =
WordPress.org preparation.
* The footer credit is now true opt-in (guideline 10): the checkbox in the
  assistant is no longer pre-checked, the option's default value is "hide".
  The credit paragraph in the theme footer is hidden via CSS and only shown
  after explicit consent.
* Showcase opt-in: honest notice text. The setting is only stored locally,
  no data is transmitted (there is currently no receiving backend).
* Origin of the mascot artwork disclosed in the copyright section (original
  work by hafenstudios, created with AI assistance).
* Escaping: the SEO plugin notice now uses wp_kses_post( sprintf( ... ) )
  instead of sprintf( esc_html__( ... ) ).
* Cleanup: load_plugin_textdomain() removed (unnecessary for plugins from
  the .org directory since WordPress 4.6); the superfluous jQuery dependency
  of wizard.js is gone (the script only uses fetch and DOM APIs).
* New: languages/hafen-core.pot.

= 0.5.0 =
Source of this release: hands-on feedback from the real-world project
vielfalt-begleiten.nrw.

* Assistant: free accent color via color picker and hex field in addition to
  the six presets (F1). The color is now also written into the user global
  styles (complete brand palette including brand-dark, brand-light and
  gradient) so it applies in the block and site editor too, not only in the
  frontend. The inline CSS remains as a fallback with identical values.
* Assistant: the contact page is now preselected in the starter pages step,
  like the homepage and blog (F2).
* Showcase reminder: a discreet, dismissible admin notice at the earliest 14
  days after setup and only from three published pages onward, instead of
  only the (too early) question directly in the assistant (F3).
* New block "Hafen Video (2-click)": privacy-friendly YouTube embed via
  youtube-nocookie.com. Before the click only a brand-colored area with a
  play symbol and notice text, no external request.
* Robustness: protection against wptexturize damage to inline scripts in
  template parts ("&&" became "&#038;&#038;", SyntaxError in the frontend).
  Script segments are masked during part rendering and restored unchanged
  afterwards; wptexturize stays globally active (F6).
* REST: the settings (schema_mode, enable_llms_txt, organization_name,
  organization_logo) and the accent color are now readable and writable via
  /wp-json/wp/v2/settings (F9).

= 0.4.1 =
* Final brand mascot (Captain "Ahoi"): replaces the placeholder SVG with
  real artwork, with its own pose per assistant step (welcome, extensions,
  brand, starter pages, done) and in the welcome notice.
* Correction: real umlauts (ä/ö/ü/ß) throughout instead of ASCII
  substitutes in all visible texts, block descriptions and AI prompts.

= 0.4.0 =
* AI assistant (bring your own key): generates suggestions for meta
  description, TL;DR and FAQ from the post content in the editor. Uses your
  own Anthropic key, requests go directly to Anthropic (no middleman).
  Selectable model (default Claude Opus 4.8). Off by default, opt-in.

= 0.3.0 =
* Setup assistant (onboarding): guides you after activation through
  recommended extensions (opt-in, WordPress.org), brand (logo + accent color
  colors the theme), starter pages and completion. Dismissible welcome
  notice, no obligation. With the brand mascot (captain) as companion
  (placeholder artwork).
* The accent color is applied live to the theme via a :root variable.
* Footer credit ("Built with Hafen") can be shown/hidden via the assistant.

= 0.2.0 =
* SEO plugin coexistence: detects common SEO plugins (Yoast, Rank Math,
  SEOPress, AIOSEO, The SEO Framework, Slim SEO, Squirrly) and automatically
  steps back where schema overlaps. New schema mode (Auto/Full/Answer
  only/Off) replaces the simple on-off switch.

= 0.1.0 =
* Schema engine (Organization, WebSite, Article, BreadcrumbList, FAQPage,
  HowTo).
* Answer engine blocks: FAQ, HowTo, TL;DR, Definition (server-rendered, no
  build).
* llms.txt / llms-full.txt generator with rewrite endpoint.
* Settings page for organization, schema and llms.txt switches.

== Upgrade Notice ==

= 1.0.0 =
First WordPress.org release. Source language is now English; translations
arrive via translate.wordpress.org. The AI assistant runs through the
WordPress AI client. The setup wizard no longer replaces an existing
homepage. Review the AI crawler policy after updating.

= 0.9.0 =
The weekly OpenAI IP range fetch previously ran automatically with the AI
traffic measurement; it is now its own opt-in switch (Settings > AI
Traffic), OFF by default. Anyone who wants to use bot verification must
enable it once after the update.

= 0.8.1 =
Security fix: the access gate did not apply to the REST API, llms.txt, the
IndexNow key file and the Markdown delivery. Update recommended if the
access gate is in use.
