PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.11.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.11.0
2.11.0 2.10.0 2.9.0 2.8.0 2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 All 52 releases
← All changes | includes/abilities/settings/class-update-llms-txt-settings.php +27 -2 1.30.0 → 2.11.0 View file →
@@ -34,8 +34,9 @@
34 34 /**
35 35 * String-typed llms.txt keys (multi-line content preserved).
36 36 */
37 37 private const STRING_KEYS = [
38 + 'delivery_mode',
38 39 'site_name',
39 40 'website_description',
40 41 'key_features',
41 42 'target_audience',
@@ -55,9 +56,9 @@
55 56 */
56 57 public function __construct() {
57 58 $this->id = 'thinkrank/update-llms-txt-settings';
58 59 $this->label = __( 'Update ThinkRank llms.txt Settings', 'thinkrank' );
59 - $this->description = __( 'Update ThinkRank llms.txt settings, which describe the site to AI language models via the llms.txt file.', 'thinkrank' );
60 + $this->description = __( 'Update ThinkRank llms.txt settings, which describe the site to AI language models via the llms.txt file. Read the current values with get-llms-txt-settings first, then publish-llms-txt to write the file.', 'thinkrank' );
60 61 }
61 62
62 63 /**
63 64 * {@inheritDoc}
@@ -66,9 +67,16 @@
66 67 */
67 68 public function get_annotations() {
68 69 return [
69 70 'readonly' => false,
70 - 'destructive' => true,
71 + // Settings writes are recoverable: the matching get-* ability reads
72 + // the previous value, so nothing is lost that cannot be put back.
73 + // `destructive` is reserved for calls that lose data or reach
74 + // outside the site, and marking routine configuration with it made
75 + // MCP clients demand a human approval for every save — which users
76 + // reported as a permission bug, because the client's refusal reads
77 + // as "No approval received" (#675).
78 + 'destructive' => false,
71 79 'idempotent' => true,
72 80 'priority' => 2.0,
73 81 'openWorldHint' => false,
74 82 ];
@@ -88,8 +96,15 @@
88 96 foreach ( self::STRING_KEYS as $key ) {
89 97 $props[ $key ] = [ 'type' => 'string' ];
90 98 }
91 99
100 + $props['delivery_mode']['enum'] = [ 'auto', 'static', 'dynamic' ];
101 + $props['delivery_mode']['description'] = __( 'How /llms.txt is served: "static" writes a physical file the web server answers, "dynamic" keeps the document in WordPress and serves it from PHP as UTF-8, "auto" prefers static on Apache/LiteSpeed but falls back to dynamic when the published file turns out to be served without a character set.', 'thinkrank' );
102 +
103 + // The delimiter is not guessable from the field name, and getting it
104 + // wrong publishes mangled bullets to the file AI crawlers read (#765).
105 + $props['key_features']['description'] = __( 'Key features of the site, one per line. A newline separates features; a comma is treated as part of a feature, so "Collect reviews from Trustpilot, Google, and Etsy" stays one feature rather than becoming three.', 'thinkrank' );
106 +
92 107 return $props;
93 108 }
94 109
95 110 /**
@@ -177,8 +192,18 @@
177 192 return [
178 193 'success' => true,
179 194 'file_unpublished' => false,
180 195 'message' => __( 'Settings were saved, but the published llms.txt file could not be removed and may still be served. Please remove it manually.', 'thinkrank' ),
196 + ];
197 + }
198 +
199 + // Likewise for a delivery-mode switch that could not move the published
200 + // document — /llms.txt is still on the old path.
201 + $delivery_warning = $mgr->delivery_switch_warning();
202 + if ( $result && '' !== $delivery_warning ) {
203 + return [
204 + 'success' => true,
205 + 'message' => $delivery_warning,
181 206 ];
182 207 }
183 208
184 209 return [