@respira/wordpress-mcp-server 8.3.4 → 8.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ All notable changes to Respira WordPress MCP Server will be documented in this f
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [8.3.5] - 2026-08-19
9
+
10
+ ### Fixed
11
+
12
+ - **An update to a host that silently drops PUT now completes instead of hanging forever.** 8.1.5 taught the client to retry a write as `POST` when a host *rejects* `PUT`, which fires on a status code. This host does not reject it, it drops it: the connection stays open and expires with no response and no status at all. `isRetryableAsPost()` only ever looked at the response status, and a timeout has no response, so the fallback that would have fixed it never ran. The error handler was also discarding the transport code on that branch, so there was nothing left to test even if it had looked. Both are fixed, the seven `PUT` write paths now go through one helper rather than seven hand-rolled attempts, which picked up two that had no fallback at all, and exactly one `POST` follows, never a second `PUT`. Reported by O.Q., who also reported and verified the original 8.1.5 fix on the same site.
13
+ - **The fallback cannot execute a write twice.** The plugin's idempotency cache keys on the HTTP method, so a `PUT` that reached PHP and executed, and whose response was then dropped, would not have deduplicated against the retry. The fallback now sends `X-Respira-Original-Method: PUT` and the plugin keys on that, so both attempts land in the same bucket and the second is served from the first one's result. Requires plugin 8.6.31. A `DELETE` and a `PUT` sharing one key still get separate buckets, which is unchanged.
14
+ - **`diagnose_connection` no longer reports a dropped request as "not blocked".** It probed with `OPTIONS` and scored the result by status code, and a probe that times out has no status, so the comparison came out false and the verdict came back clear. That is why this customer's own diagnostic reported every check passing while nothing could be written. It now probes `PUT` directly and reports three states rather than two, so a dropped probe reads as unknown instead of fine, and the recommendation names the dropped-verb case and the way around it.
15
+
16
+ ### Added
17
+
18
+ - **`forceWriteMethod: "post"` per site**, alongside `forceRestRoute`, so a host that blocks `PUT` can be worked around in one line of config without waiting for a release.
19
+ - **`purge_cache`.** Purges one page or the whole site and reports which caching layers it found and exactly what it called, which it looked for and did not find, and what it skipped and why. Requires plugin 8.6.31.
20
+ - **WooCommerce order reads carry `customer_ip_address`, `customer_user_agent` and `meta_data`**, with credential-looking meta keys withheld, counted and named. Requires the WooCommerce add-on 4.0.4.
21
+
8
22
  ## [8.3.4] - 2026-08-15
9
23
 
10
24
  ### Added
package/README.md CHANGED
@@ -548,13 +548,14 @@ Add any widget to a page in one call:
548
548
  | `respira_list_terms` / `respira_get_term` / `respira_create_term` / `respira_update_term` / `respira_delete_term` | Term CRUD |
549
549
  | `respira_list_post_types` / `respira_get_post_type` | Post type info |
550
550
 
551
- ### Site & Plugins (14 tools)
551
+ ### Site & Plugins (15 tools)
552
552
  | Tool | Description |
553
553
  |---|---|
554
554
  | `respira_get_site_context` | WordPress version, theme, plugins, URL |
555
555
  | `respira_get_theme_docs` | Theme documentation and structure |
556
556
  | `respira_list_plugins` / `respira_install_plugin` / `respira_activate_plugin` / `respira_deactivate_plugin` / `respira_update_plugin` / `respira_delete_plugin` | Plugin management |
557
557
  | `respira_list_options` / `respira_get_option` / `respira_update_option` / `respira_delete_option` | WordPress options |
558
+ | `respira_purge_cache` | Purge page and object caches and report which caching layers were touched. Pass `post_id` for one page, omit it for the whole site. Every Respira write already purges what it changed; this is the manual lever for changes Respira did not make |
558
559
  | `respira_validate_security` | Security audit |
559
560
  | `respira_get_server_compatibility` | Plugin/MCP version check |
560
561
 
package/TOOL_CATALOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- Generated by scripts/check-tool-registry-parity.mjs. Do not edit by hand. -->
4
4
 
5
- Generated catalog: **186 core tools**, **105 WooCommerce tools**, **291 total**.
5
+ Generated catalog: **187 core tools**, **105 WooCommerce tools**, **292 total**.
6
6
 
7
7
  The runtime applies site context and per-site governance, so an individual connection may expose a smaller relevant subset.
8
8
 
@@ -146,6 +146,7 @@ The runtime applies site context and per-site governance, so an individual conne
146
146
  - `wordpress_make_responsive` — read; hosted/stdio
147
147
  - `wordpress_mint_design_preview` — read; native + hosted
148
148
  - `wordpress_move_element` — write; native + hosted
149
+ - `wordpress_purge_cache` — write; native + hosted
149
150
  - `wordpress_read_page` — read; native + hosted
150
151
  - `wordpress_read_post` — read; native + hosted
151
152
  - `wordpress_read_theme_file` — read; hosted/stdio
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Ticket e2d884cb — `respira_update_post` hung forever on
3
+ * linvestisseurantifragile.com (Apache) while `respira_read_post` (GET) and
4
+ * `respira_create_post_duplicate` (POST) worked. Reproducible 3/3 on two
5
+ * different posts, no write ever applied.
6
+ *
7
+ * The verb was the only difference. The host DROPS PUT rather than rejecting
8
+ * it: the connection is held and never answered, so the client's own timeout
9
+ * is the only thing that ends the call. The PUT->POST fallback that would have
10
+ * saved the write existed already (ticket 2b3a706b, same customer, same host,
11
+ * one behaviour earlier) but fired on status codes only — and a dropped
12
+ * request has no status. `handleError` rebuilt the failure as
13
+ * `respira_write_outcome_unknown` with no `response`, so
14
+ * `isRetryableAsPost()` returned false and the PUT error was rethrown.
15
+ *
16
+ * The dangerous half of the fix is the retry itself. A PUT that DID reach PHP,
17
+ * executed, and only lost its response on the way back must not run a second
18
+ * time as a POST: the plugin's idempotency cache key and fingerprint both
19
+ * include the HTTP method (class-respira-mcp-reliability.php), and update_post
20
+ * is not idempotent in every branch — the duplicate-first path mints a draft
21
+ * duplicate of the customer's page. So the fallback POST carries the PUT's
22
+ * Idempotency-Key AND declares `X-Respira-Original-Method: PUT`, and the plugin
23
+ * keys on the declared method. The companion PHP proof that the plugin honours
24
+ * the header lives at
25
+ * wordpress-plugin/respira-for-wordpress/tests/standalone/e2d884cb-idempotency-dedupe-across-verb.php
26
+ *
27
+ * These tests run a real HTTP server so the whole interceptor chain runs,
28
+ * including the `.response`-stripping codedError() step that made the first
29
+ * version of this fallback a no-op. The drop is simulated by destroying the
30
+ * socket mid-request, which is what a WAF that discards the verb looks like to
31
+ * Node (`socket hang up`, code ECONNRESET) and is the same no-response,
32
+ * no-status shape as the customer's timeout without costing a test 120s.
33
+ */
34
+ export {};
35
+ //# sourceMappingURL=e2d884cb-put-dropped-post-fallback.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2d884cb-put-dropped-post-fallback.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/e2d884cb-put-dropped-post-fallback.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG"}
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Ticket e2d884cb — `respira_update_post` hung forever on
3
+ * linvestisseurantifragile.com (Apache) while `respira_read_post` (GET) and
4
+ * `respira_create_post_duplicate` (POST) worked. Reproducible 3/3 on two
5
+ * different posts, no write ever applied.
6
+ *
7
+ * The verb was the only difference. The host DROPS PUT rather than rejecting
8
+ * it: the connection is held and never answered, so the client's own timeout
9
+ * is the only thing that ends the call. The PUT->POST fallback that would have
10
+ * saved the write existed already (ticket 2b3a706b, same customer, same host,
11
+ * one behaviour earlier) but fired on status codes only — and a dropped
12
+ * request has no status. `handleError` rebuilt the failure as
13
+ * `respira_write_outcome_unknown` with no `response`, so
14
+ * `isRetryableAsPost()` returned false and the PUT error was rethrown.
15
+ *
16
+ * The dangerous half of the fix is the retry itself. A PUT that DID reach PHP,
17
+ * executed, and only lost its response on the way back must not run a second
18
+ * time as a POST: the plugin's idempotency cache key and fingerprint both
19
+ * include the HTTP method (class-respira-mcp-reliability.php), and update_post
20
+ * is not idempotent in every branch — the duplicate-first path mints a draft
21
+ * duplicate of the customer's page. So the fallback POST carries the PUT's
22
+ * Idempotency-Key AND declares `X-Respira-Original-Method: PUT`, and the plugin
23
+ * keys on the declared method. The companion PHP proof that the plugin honours
24
+ * the header lives at
25
+ * wordpress-plugin/respira-for-wordpress/tests/standalone/e2d884cb-idempotency-dedupe-across-verb.php
26
+ *
27
+ * These tests run a real HTTP server so the whole interceptor chain runs,
28
+ * including the `.response`-stripping codedError() step that made the first
29
+ * version of this fallback a no-op. The drop is simulated by destroying the
30
+ * socket mid-request, which is what a WAF that discards the verb looks like to
31
+ * Node (`socket hang up`, code ECONNRESET) and is the same no-response,
32
+ * no-status shape as the customer's timeout without costing a test 120s.
33
+ */
34
+ import { test, after } from 'node:test';
35
+ import assert from 'node:assert/strict';
36
+ import http from 'node:http';
37
+ import { WordPressClient, isRetryableAsPost } from '../wordpress-client.js';
38
+ const servers = [];
39
+ after(() => {
40
+ for (const s of servers)
41
+ s.close();
42
+ });
43
+ /**
44
+ * A fake site that answers GET, drops PUT, and (unless told otherwise)
45
+ * answers POST — the customer's exact fingerprint.
46
+ *
47
+ * It also implements the plugin's replay contract the way
48
+ * class-respira-mcp-reliability.php does, keyed on the DECLARED original
49
+ * method, so `executions` counts real writes rather than requests.
50
+ */
51
+ async function startDroppedPutSite(opts) {
52
+ const hits = [];
53
+ const replayCache = new Map();
54
+ let executions = 0;
55
+ const execute = (dedupeKey) => {
56
+ const cached = replayCache.get(dedupeKey);
57
+ if (cached)
58
+ return { ...cached, replayed: true };
59
+ executions += 1;
60
+ const result = { status: 200, body: JSON.stringify({ success: true, executions }) };
61
+ replayCache.set(dedupeKey, result);
62
+ return { ...result, replayed: false };
63
+ };
64
+ const server = http.createServer((req, res) => {
65
+ const chunks = [];
66
+ req.on('data', (c) => chunks.push(c));
67
+ req.on('end', () => {
68
+ const body = Buffer.concat(chunks).toString('utf8');
69
+ const idempotencyKey = String(req.headers['idempotency-key'] || '');
70
+ const originalMethod = String(req.headers['x-respira-original-method'] || '');
71
+ hits.push({ method: req.method || '', url: req.url || '', idempotencyKey, originalMethod, body });
72
+ const path = (req.url || '').split('?')[0];
73
+ if (req.method === 'GET' && path === '/wp-json/respira/v2/status') {
74
+ res.writeHead(200, { 'Content-Type': 'application/json' });
75
+ res.end(JSON.stringify({ status: 'ok' }));
76
+ return;
77
+ }
78
+ // The plugin keys on X-Respira-Original-Method when present, exactly as
79
+ // Respira_MCP_Reliability::dedupe_method() does.
80
+ const dedupeMethod = originalMethod || req.method || '';
81
+ const dedupeKey = [dedupeMethod, path, body, idempotencyKey].join('|');
82
+ if (path === opts.droppedPath && req.method === 'PUT') {
83
+ // The write may or may not have run before the reply was discarded.
84
+ if (opts.putExecutesBeforeDrop)
85
+ execute(dedupeKey);
86
+ req.socket.destroy();
87
+ return;
88
+ }
89
+ if (path === opts.droppedPath && req.method === 'POST') {
90
+ if (opts.postBehaviour === 'drop') {
91
+ req.socket.destroy();
92
+ return;
93
+ }
94
+ if (opts.postBehaviour === '500') {
95
+ res.writeHead(500, { 'Content-Type': 'application/json' });
96
+ res.end(JSON.stringify({ code: 'internal', message: 'boom' }));
97
+ return;
98
+ }
99
+ const outcome = execute(dedupeKey);
100
+ res.writeHead(outcome.status, {
101
+ 'Content-Type': 'application/json',
102
+ ...(outcome.replayed ? { 'X-Respira-Idempotent-Replay': 'true' } : {}),
103
+ });
104
+ res.end(outcome.body);
105
+ return;
106
+ }
107
+ res.writeHead(404, { 'Content-Type': 'application/json' });
108
+ res.end(JSON.stringify({ code: 'rest_no_route', message: 'No route' }));
109
+ });
110
+ });
111
+ servers.push(server);
112
+ await new Promise((resolve) => server.listen(0, resolve));
113
+ const { port } = server.address();
114
+ const client = new WordPressClient({
115
+ id: 'e2d884cb',
116
+ name: 'e2d884cb',
117
+ url: `http://127.0.0.1:${port}`,
118
+ apiKey: 'respira_test_key',
119
+ ...(opts.forceWriteMethod ? { forceWriteMethod: opts.forceWriteMethod } : {}),
120
+ });
121
+ return { client, hits, executions: () => executions };
122
+ }
123
+ const scoped = (hits, method, path) => hits.filter((h) => h.method === method && h.url.split('?')[0] === path);
124
+ // ---------------------------------------------------------------------------
125
+ // 1. The predicate itself. A dropped request has no response and no status;
126
+ // only the transport code says what happened, and handleError now carries
127
+ // it across the rewrite that renames the error.
128
+ // ---------------------------------------------------------------------------
129
+ test('isRetryableAsPost: a dropped PUT (no response, connection code) is retryable', () => {
130
+ for (const code of ['ECONNABORTED', 'ETIMEDOUT', 'ECONNRESET']) {
131
+ const err = new Error('no response');
132
+ err.name = 'respira_write_outcome_unknown';
133
+ err.code = code;
134
+ assert.equal(isRetryableAsPost(err), true, `${code} should fall back to POST`);
135
+ }
136
+ });
137
+ test('isRetryableAsPost: a host that is simply not there is NOT retried as POST', () => {
138
+ // ECONNREFUSED / ENOTFOUND mean nothing reached a listening socket, so the
139
+ // verb cannot be the discriminator and a POST would only burn a second
140
+ // timeout. Deliberately a strict subset of RETRYABLE_CONNECTION_CODES.
141
+ for (const code of ['ECONNREFUSED', 'ENOTFOUND', 'EHOSTUNREACH', 'EAI_AGAIN']) {
142
+ const err = new Error('no response');
143
+ err.name = 'respira_write_outcome_unknown';
144
+ err.code = code;
145
+ assert.equal(isRetryableAsPost(err), false, `${code} should not fall back to POST`);
146
+ }
147
+ });
148
+ test('isRetryableAsPost: a real answer still wins over the connection code', () => {
149
+ const err = new Error('nope');
150
+ err.code = 'ECONNRESET';
151
+ err.response = { status: 500 };
152
+ assert.equal(isRetryableAsPost(err), false, 'a 500 with a body is not a verb problem');
153
+ });
154
+ // ---------------------------------------------------------------------------
155
+ // 2. The customer's call, end to end.
156
+ // ---------------------------------------------------------------------------
157
+ test('updatePost: a PUT the host drops falls back to POST exactly once', async () => {
158
+ const { client, hits } = await startDroppedPutSite({
159
+ droppedPath: '/wp-json/respira/v2/posts/42',
160
+ });
161
+ const result = await client.updatePost(42, { title: 'Nouveau titre' });
162
+ assert.deepEqual(result, { success: true, executions: 1 });
163
+ assert.equal(scoped(hits, 'PUT', '/wp-json/respira/v2/posts/42').length, 1, 'one PUT, never a second');
164
+ assert.equal(scoped(hits, 'POST', '/wp-json/respira/v2/posts/42').length, 1, 'exactly one POST fallback');
165
+ });
166
+ test('callRestV2: a PUT the host drops falls back to POST exactly once', async () => {
167
+ const { client, hits } = await startDroppedPutSite({
168
+ droppedPath: '/wp-json/respira/v2/design-tokens',
169
+ });
170
+ const result = await client.callRestV2('PUT', '/design-tokens', { tokens: { color: '#000' } });
171
+ assert.deepEqual(result, { success: true, executions: 1 });
172
+ assert.equal(scoped(hits, 'PUT', '/wp-json/respira/v2/design-tokens').length, 1);
173
+ assert.equal(scoped(hits, 'POST', '/wp-json/respira/v2/design-tokens').length, 1);
174
+ });
175
+ // ---------------------------------------------------------------------------
176
+ // 3. The correctness caveat: a PUT that ALREADY EXECUTED before its response
177
+ // was discarded must not run a second time. This is the whole reason the
178
+ // fallback POST carries the PUT's Idempotency-Key and declares
179
+ // X-Respira-Original-Method — the plugin's dedupe material includes the
180
+ // method, so without the header the retry lands in a different bucket and
181
+ // update_post's duplicate-first branch mints a second draft duplicate of
182
+ // the customer's page.
183
+ // ---------------------------------------------------------------------------
184
+ test('the fallback POST carries the PUT idempotency key and declares the original method', async () => {
185
+ const { client, hits } = await startDroppedPutSite({
186
+ droppedPath: '/wp-json/respira/v2/posts/7',
187
+ });
188
+ await client.updatePost(7, { title: 'Titre' });
189
+ const put = scoped(hits, 'PUT', '/wp-json/respira/v2/posts/7')[0];
190
+ const post = scoped(hits, 'POST', '/wp-json/respira/v2/posts/7')[0];
191
+ assert.ok(put.idempotencyKey, 'the PUT carried an idempotency key');
192
+ assert.equal(post.idempotencyKey, put.idempotencyKey, 'the POST reuses the PUT key, it does not mint a new one');
193
+ assert.equal(post.originalMethod, 'PUT', 'the POST declares the verb it is standing in for');
194
+ assert.equal(put.body, post.body, 'same payload, so the plugin fingerprint matches too');
195
+ });
196
+ test('a dropped PUT that already executed server-side dedupes to ONE execution', async () => {
197
+ const { client, hits, executions } = await startDroppedPutSite({
198
+ droppedPath: '/wp-json/respira/v2/posts/99',
199
+ putExecutesBeforeDrop: true,
200
+ });
201
+ const result = await client.updatePost(99, { title: 'Deja ecrit' });
202
+ assert.equal(scoped(hits, 'PUT', '/wp-json/respira/v2/posts/99').length, 1);
203
+ assert.equal(scoped(hits, 'POST', '/wp-json/respira/v2/posts/99').length, 1);
204
+ assert.equal(executions(), 1, 'the write ran once, not twice — no second duplicate draft');
205
+ assert.deepEqual(result, { success: true, executions: 1 }, 'the caller gets the original result replayed');
206
+ });
207
+ test('without the original-method header the same retry would execute twice (the bug being prevented)', async () => {
208
+ // Guards the reason the header exists rather than the header itself: if the
209
+ // fallback ever stops declaring the original verb, the plugin's method-keyed
210
+ // cache misses and the non-idempotent branch runs again. Proven against the
211
+ // same replay rule the plugin uses.
212
+ const replay = new Map();
213
+ let executions = 0;
214
+ const run = (dedupeMethod, key) => {
215
+ const k = `${dedupeMethod}|/posts/99||${key}`;
216
+ if (replay.has(k))
217
+ return;
218
+ executions += 1;
219
+ replay.set(k, 1);
220
+ };
221
+ run('PUT', 'call-1');
222
+ run('POST', 'call-1'); // naive retry: same key, different bucket
223
+ assert.equal(executions, 2, 'method-keyed dedupe misses when the verb changes silently');
224
+ executions = 0;
225
+ replay.clear();
226
+ run('PUT', 'call-2');
227
+ run('PUT', 'call-2'); // fallback declaring X-Respira-Original-Method: PUT
228
+ assert.equal(executions, 1, 'declaring the original verb keeps both attempts in one bucket');
229
+ });
230
+ // ---------------------------------------------------------------------------
231
+ // 4. Boundedness. One POST, no loop, no second PUT, whatever the POST does.
232
+ // ---------------------------------------------------------------------------
233
+ test('a dropped PUT followed by a dropped POST does not loop', async () => {
234
+ const { client, hits } = await startDroppedPutSite({
235
+ droppedPath: '/wp-json/respira/v2/posts/13',
236
+ postBehaviour: 'drop',
237
+ });
238
+ await assert.rejects(() => client.updatePost(13, { title: 'x' }));
239
+ assert.equal(scoped(hits, 'PUT', '/wp-json/respira/v2/posts/13').length, 1, 'still exactly one PUT');
240
+ assert.equal(scoped(hits, 'POST', '/wp-json/respira/v2/posts/13').length, 1, 'exactly one POST, no retry ladder');
241
+ });
242
+ test('a dropped PUT followed by a 500 POST does not loop', async () => {
243
+ const { client, hits } = await startDroppedPutSite({
244
+ droppedPath: '/wp-json/respira/v2/posts/14',
245
+ postBehaviour: '500',
246
+ });
247
+ await assert.rejects(() => client.updatePost(14, { title: 'x' }));
248
+ assert.equal(scoped(hits, 'PUT', '/wp-json/respira/v2/posts/14').length, 1);
249
+ // A 500 on an unsafe method is not replay-safe (isReplaySafeRetry), so the
250
+ // interceptor's retry ladder must not stack on top of the fallback.
251
+ assert.equal(scoped(hits, 'POST', '/wp-json/respira/v2/posts/14').length, 1);
252
+ });
253
+ // ---------------------------------------------------------------------------
254
+ // 5. The support escape hatch.
255
+ // ---------------------------------------------------------------------------
256
+ test("forceWriteMethod: 'post' skips the PUT entirely", async () => {
257
+ const { client, hits } = await startDroppedPutSite({
258
+ droppedPath: '/wp-json/respira/v2/posts/21',
259
+ forceWriteMethod: 'post',
260
+ });
261
+ const result = await client.updatePost(21, { title: 'Direct' });
262
+ assert.deepEqual(result, { success: true, executions: 1 });
263
+ assert.equal(scoped(hits, 'PUT', '/wp-json/respira/v2/posts/21').length, 0, 'no PUT was ever sent');
264
+ assert.equal(scoped(hits, 'POST', '/wp-json/respira/v2/posts/21').length, 1);
265
+ assert.ok(scoped(hits, 'POST', '/wp-json/respira/v2/posts/21')[0].idempotencyKey, 'still an idempotent write');
266
+ });
267
+ test("forceWriteMethod: 'post' also covers the shared REST callers", async () => {
268
+ const { client, hits } = await startDroppedPutSite({
269
+ droppedPath: '/wp-json/respira/v2/bricks/theme-styles',
270
+ forceWriteMethod: 'post',
271
+ });
272
+ await client.callRestV2('PUT', '/bricks/theme-styles', { value: { spacing: 'md' } });
273
+ assert.equal(scoped(hits, 'PUT', '/wp-json/respira/v2/bricks/theme-styles').length, 0);
274
+ assert.equal(scoped(hits, 'POST', '/wp-json/respira/v2/bricks/theme-styles').length, 1);
275
+ });
276
+ // ---------------------------------------------------------------------------
277
+ // 6. The diagnostic must not read green on a site whose PUT is dropped. This
278
+ // is the silent-guard half of the ticket: the customer ran
279
+ // diagnose_connection themselves and it said everything was fine.
280
+ // ---------------------------------------------------------------------------
281
+ test('diagnose_connection reports a dropped PUT as unknown, not as not-blocked', async () => {
282
+ const server = http.createServer((req, res) => {
283
+ const path = (req.url || '').split('?')[0];
284
+ if (req.method === 'PUT') {
285
+ req.socket.destroy();
286
+ return;
287
+ }
288
+ if (path === '/wp-json/respira/v1/ping' || path === '/wp-json/respira/v1/diagnostic/report') {
289
+ res.writeHead(200, { 'Content-Type': 'application/json' });
290
+ res.end(JSON.stringify({ ok: true }));
291
+ return;
292
+ }
293
+ res.writeHead(200, { 'Content-Type': 'application/json' });
294
+ res.end(JSON.stringify({ ok: true }));
295
+ });
296
+ servers.push(server);
297
+ await new Promise((resolve) => server.listen(0, resolve));
298
+ const { port } = server.address();
299
+ const client = new WordPressClient({
300
+ id: 'e2d884cb-diag',
301
+ name: 'e2d884cb-diag',
302
+ url: `http://127.0.0.1:${port}`,
303
+ apiKey: 'respira_test_key',
304
+ });
305
+ const report = await client.diagnoseConnection({ probe_timeout_ms: 5000 });
306
+ assert.equal(report.write_method_verdict, 'unknown');
307
+ assert.equal(report.write_method_blocked, null, 'null, never false — a dropped probe is not a passing probe');
308
+ assert.equal(report.write_method_probe.put_dropped, true);
309
+ assert.ok(report.recommendations.some((r) => r.includes('DROPPED') && r.includes('PUT')), 'the recommendation names the dropped-PUT case');
310
+ assert.ok(report.recommendations.some((r) => r.includes('"forceWriteMethod": "post"')), 'the recommendation names the one-line workaround');
311
+ });
312
+ test('diagnose_connection still reports a healthy site as not blocked', async () => {
313
+ const server = http.createServer((req, res) => {
314
+ // WordPress answers PUT /ping with a JSON rest_no_route 404: the verb
315
+ // reached PHP, which is the whole question being asked.
316
+ if (req.method === 'PUT') {
317
+ res.writeHead(404, { 'Content-Type': 'application/json' });
318
+ res.end(JSON.stringify({ code: 'rest_no_route', message: 'No route was found' }));
319
+ return;
320
+ }
321
+ res.writeHead(200, { 'Content-Type': 'application/json' });
322
+ res.end(JSON.stringify({ ok: true }));
323
+ });
324
+ servers.push(server);
325
+ await new Promise((resolve) => server.listen(0, resolve));
326
+ const { port } = server.address();
327
+ const client = new WordPressClient({
328
+ id: 'e2d884cb-diag-ok',
329
+ name: 'e2d884cb-diag-ok',
330
+ url: `http://127.0.0.1:${port}`,
331
+ apiKey: 'respira_test_key',
332
+ });
333
+ const report = await client.diagnoseConnection({ probe_timeout_ms: 5000 });
334
+ assert.equal(report.write_method_verdict, 'not_blocked');
335
+ assert.equal(report.write_method_blocked, false);
336
+ assert.equal(report.write_method_probe.put_reached_wordpress, true);
337
+ });
338
+ test('diagnose_connection reports an edge that answers PUT with an HTML 403 as blocked', async () => {
339
+ const server = http.createServer((req, res) => {
340
+ if (req.method === 'PUT') {
341
+ res.writeHead(403, { 'Content-Type': 'text/html' });
342
+ res.end('<!DOCTYPE html><html><head><title>403 Forbidden</title></head><body>Forbidden</body></html>');
343
+ return;
344
+ }
345
+ res.writeHead(200, { 'Content-Type': 'application/json' });
346
+ res.end(JSON.stringify({ ok: true }));
347
+ });
348
+ servers.push(server);
349
+ await new Promise((resolve) => server.listen(0, resolve));
350
+ const { port } = server.address();
351
+ const client = new WordPressClient({
352
+ id: 'e2d884cb-diag-403',
353
+ name: 'e2d884cb-diag-403',
354
+ url: `http://127.0.0.1:${port}`,
355
+ apiKey: 'respira_test_key',
356
+ });
357
+ const report = await client.diagnoseConnection({ probe_timeout_ms: 5000 });
358
+ assert.equal(report.write_method_verdict, 'blocked');
359
+ assert.equal(report.write_method_blocked, true);
360
+ assert.ok(report.recommendations.some((r) => r.includes('"forceWriteMethod": "post"')));
361
+ });
362
+ //# sourceMappingURL=e2d884cb-put-dropped-post-fallback.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2d884cb-put-dropped-post-fallback.test.js","sourceRoot":"","sources":["../../src/__tests__/e2d884cb-put-dropped-post-fallback.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -3217,7 +3217,15 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
3217
3217
  type: { type: 'string', enum: ['color', 'typography', 'spacing', 'breakpoints'] },
3218
3218
  id: { type: 'string' },
3219
3219
  name: { type: 'string' },
3220
- value: {},
3220
+ value: {
3221
+ // Typed on purpose. An empty schema is valid JSON Schema and a
3222
+ // strict MCP validator rejects it: ChatGPT refused the whole
3223
+ // catalogue over this, so one untyped property took every tool
3224
+ // down. The plugin's own ability schema was fixed in 8.6.6; this
3225
+ // is the same fix in the npm lane, which still shipped it.
3226
+ type: ['string', 'number', 'object'],
3227
+ description: 'Token value: a CSS string for color and spacing ("#0f7b5f", "1.5rem"), a number, or an object for typography (fontFamily, fontSize, fontWeight, lineHeight).',
3228
+ },
3221
3229
  expected_fingerprint: { type: 'string', description: 'Optional document revision returned by wordpress_list_design_tokens.' },
3222
3230
  approval_token: { type: 'string' },
3223
3231
  dry_run: { type: 'boolean' },
@@ -3235,7 +3243,15 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
3235
3243
  type: { type: 'string', enum: ['color', 'typography', 'spacing', 'breakpoints'] },
3236
3244
  id: { type: 'string' },
3237
3245
  name: { type: 'string' },
3238
- value: {},
3246
+ value: {
3247
+ // Typed on purpose. An empty schema is valid JSON Schema and a
3248
+ // strict MCP validator rejects it: ChatGPT refused the whole
3249
+ // catalogue over this, so one untyped property took every tool
3250
+ // down. The plugin's own ability schema was fixed in 8.6.6; this
3251
+ // is the same fix in the npm lane, which still shipped it.
3252
+ type: ['string', 'number', 'object'],
3253
+ description: 'Token value: a CSS string for color and spacing ("#0f7b5f", "1.5rem"), a number, or an object for typography (fontFamily, fontSize, fontWeight, lineHeight).',
3254
+ },
3239
3255
  expected_fingerprint: { type: 'string' },
3240
3256
  approval_token: { type: 'string' },
3241
3257
  dry_run: { type: 'boolean' },
@@ -5159,6 +5175,26 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
5159
5175
  },
5160
5176
  destructiveHint: true,
5161
5177
  },
5178
+ {
5179
+ name: 'wordpress_purge_cache',
5180
+ description: 'Purge page and object caches, and report exactly which caching layers were touched.\n\nEvery Respira write already purges what it changed, so you rarely need this. Reach for it when something changed outside Respira (a plugin update, a theme edit, a CDN holding a copy) or when a page still looks stale after an edit.\n\nPass post_id to purge one page or post. Omit it for a site-wide purge. The response lists every caching plugin Respira knows, split into `purged` (with the exact function or hook called) and `not_found` (with what was looked for), so a quiet result is never ambiguous.',
5181
+ inputSchema: {
5182
+ type: 'object',
5183
+ properties: {
5184
+ post_id: {
5185
+ type: 'number',
5186
+ description: 'Purge just this page or post. Omit for a site-wide purge.',
5187
+ },
5188
+ scope: {
5189
+ type: 'string',
5190
+ enum: ['post', 'site'],
5191
+ description: 'Force a scope. Defaults to post when post_id is given, site otherwise.',
5192
+ },
5193
+ },
5194
+ required: [],
5195
+ },
5196
+ idempotentHint: true,
5197
+ },
5162
5198
  // Media enhancements
5163
5199
  {
5164
5200
  name: 'wordpress_get_media',
@@ -5913,7 +5949,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
5913
5949
  },
5914
5950
  {
5915
5951
  name: 'woocommerce_list_orders',
5916
- description: 'List WooCommerce orders.',
5952
+ description: 'List WooCommerce orders. Every order carries customer_ip_address and customer_user_agent (the request fingerprint WooCommerce recorded, null when it recorded nothing) plus meta_data as a key/value list, so a card-testing run can be triaged from one call. Meta keys whose name matches a credential pattern (token, secret, key, password, hash, nonce, auth) are withheld; meta_data_withheld_count and meta_data_withheld_keys say which. Meta values over 500 characters are cut and the entry is marked truncated. The fingerprint fields are personal data and stay in this response: Respira telemetry never records tool results.',
5917
5953
  inputSchema: {
5918
5954
  type: 'object',
5919
5955
  properties: {
@@ -5926,7 +5962,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
5926
5962
  },
5927
5963
  {
5928
5964
  name: 'woocommerce_get_order',
5929
- description: 'Get detailed information for a single WooCommerce order.',
5965
+ description: 'Get detailed information for a single WooCommerce order, including customer_ip_address, customer_user_agent and meta_data as a key/value list. Meta keys whose name matches a credential pattern (token, secret, key, password, hash, nonce, auth) are withheld and reported in meta_data_withheld_count and meta_data_withheld_keys, so filtered data never looks like missing data.',
5930
5966
  inputSchema: {
5931
5967
  type: 'object',
5932
5968
  properties: {
@@ -7950,6 +7986,8 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
7950
7986
  return await client.updateOption(args.option, args.value);
7951
7987
  case 'wordpress_delete_option':
7952
7988
  return await client.deleteOption(args.option, args.approval_token);
7989
+ case 'wordpress_purge_cache':
7990
+ return await client.purgeCache(args.post_id !== undefined ? Number(args.post_id) : undefined, args.scope);
7953
7991
  // Media enhancements
7954
7992
  case 'wordpress_get_media':
7955
7993
  return await client.getMedia(args.id);