@respira/wordpress-mcp-server 7.6.0 → 7.6.2

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/README.md CHANGED
@@ -35,15 +35,23 @@ Other WordPress MCP servers wrap the REST API. They can create posts and pages,
35
35
 
36
36
  Respira includes a WordPress plugin that gives AI **native access** to 16 page builders, plus element-level precision, full page creation from structure, HTML-to-builder conversion, storefront design intelligence, stock image search, and bulk operations across hundreds of pages.
37
37
 
38
- ### New in v7.5.5: path-safe multi-site routing and custom Elementor guidance
38
+ ### New in v7.6.2: clearer failures and trustworthy quality signals
39
39
 
40
- - **Subdirectory WordPress sites now have distinct identities.** `https://example.com` derives `example-com`, while `https://example.com/blog` derives `example-com-blog`; non-default ports are included too. Legacy automatic collisions self-heal, and ambiguous duplicate explicit IDs fail clearly instead of silently replacing one site in memory.
41
- - **Custom Elementor widgets have a safe targeted workflow.** Respira reads Elementor's live widget registry, including controls registered by themes and third-party plugins. Agents are instructed to list widgets, fetch the exact runtime schema, find the existing element, patch only its changed settings by stable ID, and re-read it—never replace the full `_elementor_data` document for one widget.
40
+ - **PageSpeed failures keep their real machine-readable reason.** Rate limits, upstream outages, proxy HTML responses, and other structured WordPress errors no longer collapse into a generic failure, so agents can distinguish “retry later” from a Respira defect.
41
+ - **PageSpeed tools reject incomplete requests before touching WordPress.** Both PageSpeed schemas require either `page_id` or `url`, preventing avoidable calls that could only fail.
42
+ - **Every transport attempt has its own identity.** The logical call id remains stable for replay-safe writes, while `attempt_id` preserves each network attempt so a retry can never overwrite the evidence from the first timeout.
43
+ - **Privacy remains metadata-only.** Retry detection uses a process-secret target hash. Respira never sends prompts, raw arguments, tool results, or WordPress content.
44
+ - **The admin quality dashboard now separates operational health from task completion.** Expected approval/safety blocks, caller mistakes, customer setup, upstream services, product errors, unknown failures, and incomplete attempts are measured independently. Alerts use comparable site cohorts and require failures across multiple sites, reducing false alarms caused by one unusual customer setup.
45
+ - **The npm package no longer publishes private repository metadata.** Support and product links point to respira.press.
42
46
 
43
- ### Also shipped since v7.5.2
47
+ ### Reliability and builder additions since v7.5.2
44
48
 
45
- - **v7.5.3:** Windows absolute paths and `file://` URIs are recognized during media upload; `delete_media` now forwards its approval token and force flag so confirmation can complete.
46
- - **v7.5.4:** `tools/list` uses one shared, cached, two-second-bounded site-context fetch instead of three sequential WordPress calls. A slow or unreachable site can no longer hold the initial tool catalog open through multiple retry windows.
49
+ - **v7.5.3:** Windows media paths and `file://` uploads work correctly; `delete_media` approval tokens now reach the confirmation call.
50
+ - **v7.5.4:** `tools/list` shares one cached, two-second-bounded context fetch instead of making three sequential WordPress checks, preventing slow-site handshake disconnects.
51
+ - **v7.5.5:** subdirectory WordPress installs on the same hostname receive distinct site identities; custom Elementor widget guidance now uses live control schemas and targeted stable-ID updates.
52
+ - **v7.5.6:** a successful `?rest_route=` diagnostic fallback becomes sticky for the rest of the MCP session.
53
+ - **v7.6.0:** WPML translation tools and Divi Theme Builder header, footer, and body-template tools.
54
+ - **v7.6.1:** `wordpress_build_mega_menu` creates a complete native Divi 4 or Divi 5 mega-menu hierarchy in one call.
47
55
 
48
56
  ### v7.5.2: reconnect-safe writes and drop diagnostics
49
57
 
@@ -53,13 +61,13 @@ Respira includes a WordPress plugin that gives AI **native access** to 16 page b
53
61
  - **The quality dashboard can separate exact retries from editing sweeps.** It records stable session/call identity, transport, incomplete calls, connector/plugin versions, total vs tool time, and privacy-safe stage durations. Target comparison uses a secret HMAC; arguments, results, prompts, and WordPress content are never sent.
54
62
  - **Native URL-connected clients gain timeout-safe writes.** Plugin 7.5.46 adds `_respira_async: true`, `respira_get_job_status`, stable `Mcp-Session-Id` responses, replay-safe `_respira_call_id`, and a native `respira_diagnose_connection` tool. The native endpoint is stateless HTTP—independent POST requests, not a persistent “write channel.”
55
63
 
56
- ### Also shipped since the README's previous v7.1 refresh
64
+ ### Also shipped between v7.1 and v7.5.1
57
65
 
58
66
  - **v7.2:** cascade session rollback; dropped-styling/no-op guidance; page-parent schemas; Oxygen 6 build guidance; completed live-edit confirmation parameters; bounded heavy-write/docs timeouts; and route-aware capability negotiation that hides tools an older plugin cannot execute.
59
67
  - **v7.3:** the WooCommerce add-on expanded from 21 to 56 tools across catalog, pricing, stock, storefront, brands, variations/attributes, coupons, customers, refunds, and AI-readiness.
60
68
  - **v7.4:** Agent-Ready Commerce expanded WooCommerce to 79 tools with feeds + store `llms.txt`, readiness fixes, signed cart links/attribution, and Subscriptions, Bookings, and Memberships writes. v7.4.1 then made newly connected dashboard sites self-heal into a running connector session.
61
69
  - **v7.5.0:** eight STAGGS configurator tools brought the WooCommerce total to 87.
62
- - **v7.5.1:** fixed normalized ACF tool routing and preserved dashboard-token 401 machine codes—the two fixes shipped immediately before this reliability release.
70
+ - **v7.5.1:** fixed normalized ACF tool routing and preserved dashboard-token 401 machine codes.
63
71
 
64
72
  ### New in v7.1 "Roots"
65
73
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pagespeed-error-classification.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagespeed-error-classification.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pagespeed-error-classification.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from 'node:test';
3
+ import { WordPressClient } from '../wordpress-client.js';
4
+ const config = {
5
+ id: 'pagespeed-test',
6
+ name: 'PageSpeed test',
7
+ url: 'https://example.com',
8
+ apiKey: 'respira_test_key',
9
+ };
10
+ function fakeResponse(status, data) {
11
+ return {
12
+ isAxiosError: true,
13
+ message: `Request failed with status code ${status}`,
14
+ response: {
15
+ status,
16
+ statusText: 'Error',
17
+ headers: {},
18
+ data,
19
+ config: {},
20
+ },
21
+ config: { url: '/analyze/pagespeed', method: 'post' },
22
+ };
23
+ }
24
+ test('PageSpeed rate limits retain a stable upstream error code', async () => {
25
+ const client = new WordPressClient(config);
26
+ const error = await client.handleError(fakeResponse(429, {
27
+ code: 'respira_pagespeed_rate_limited',
28
+ message: 'Google PSI rate limited this request.',
29
+ data: { status: 429, retry_after: 60 },
30
+ }));
31
+ assert.equal(error.name, 'respira_pagespeed_rate_limited');
32
+ assert.deepEqual(error.respiraErrorEnvelope, {
33
+ code: 'respira_pagespeed_rate_limited',
34
+ retry_after: 60,
35
+ });
36
+ });
37
+ test('PageSpeed upstream 5xx responses do not become unclassified', async () => {
38
+ const client = new WordPressClient(config);
39
+ const error = await client.handleError(fakeResponse(503, {
40
+ code: 'respira_pagespeed_upstream_unavailable',
41
+ message: 'Google PSI is unavailable.',
42
+ data: { status: 503 },
43
+ }));
44
+ assert.equal(error.name, 'respira_pagespeed_upstream_unavailable');
45
+ assert.match(error.message, /WordPress server error \(503\)/);
46
+ });
47
+ test('non-WordPress proxy errors receive a specific machine code', async () => {
48
+ const client = new WordPressClient(config);
49
+ const error = await client.handleError(fakeResponse(502, '<!DOCTYPE html><html><title>Bad Gateway</title></html>'));
50
+ assert.equal(error.name, 'http_502_non_wordpress');
51
+ });
52
+ //# sourceMappingURL=pagespeed-error-classification.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagespeed-error-classification.test.js","sourceRoot":"","sources":["../../src/__tests__/pagespeed-error-classification.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,MAAM,GAAwB;IAClC,EAAE,EAAE,gBAAgB;IACpB,IAAI,EAAE,gBAAgB;IACtB,GAAG,EAAE,qBAAqB;IAC1B,MAAM,EAAE,kBAAkB;CAC3B,CAAC;AAEF,SAAS,YAAY,CAAC,MAAc,EAAE,IAAa;IACjD,OAAO;QACL,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,mCAAmC,MAAM,EAAE;QACpD,QAAQ,EAAE;YACR,MAAM;YACN,UAAU,EAAE,OAAO;YACnB,OAAO,EAAE,EAAE;YACX,IAAI;YACJ,MAAM,EAAE,EAAE;SACX;QACD,MAAM,EAAE,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAAE;KAC/C,CAAC;AACX,CAAC;AAED,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;IAC3E,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAO,MAAc,CAAC,WAAW,CAC7C,YAAY,CAAC,GAAG,EAAE;QAChB,IAAI,EAAE,gCAAgC;QACtC,OAAO,EAAE,uCAAuC;QAChD,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE;KACvC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,gCAAgC,CAAC,CAAC;IAC3D,MAAM,CAAC,SAAS,CAAE,KAAa,CAAC,oBAAoB,EAAE;QACpD,IAAI,EAAE,gCAAgC;QACtC,WAAW,EAAE,EAAE;KAChB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;IAC7E,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAO,MAAc,CAAC,WAAW,CAC7C,YAAY,CAAC,GAAG,EAAE;QAChB,IAAI,EAAE,wCAAwC;QAC9C,OAAO,EAAE,4BAA4B;QACrC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;KACtB,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,wCAAwC,CAAC,CAAC;IACnE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,gCAAgC,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;IAC5E,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAO,MAAc,CAAC,WAAW,CAC7C,YAAY,CAAC,GAAG,EAAE,wDAAwD,CAAC,CAC5E,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC"}
@@ -64,11 +64,11 @@ test('401 with a forwarded dashboard-introspect code (license_inactive) also sta
64
64
  }));
65
65
  assert.equal(err.name, 'respira_license_inactive');
66
66
  });
67
- test('401 without a machine code falls back to the default Error name (no crash)', async () => {
67
+ test('401 without a machine code receives a stable HTTP classification', async () => {
68
68
  const client = new WordPressClient(buildConfig());
69
69
  const err = await client.handleError(fakeAxios401({ message: 'Invalid API key' }));
70
70
  assert.ok(err instanceof Error);
71
- assert.equal(err.name, 'Error');
71
+ assert.equal(err.name, 'http_401');
72
72
  assert.match(err.message, /Authentication failed: Invalid API key/);
73
73
  });
74
74
  //# sourceMappingURL=site-token-401-error-classification.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"site-token-401-error-classification.test.js","sourceRoot":"","sources":["../../src/__tests__/site-token-401-error-classification.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,SAAS,WAAW,CAAC,SAAuC,EAAE;IAC5D,OAAO;QACL,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,qBAAqB;QAC1B,MAAM,EAAE,kBAAkB;QAC1B,GAAG,MAAM;KACV,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAS;IAC7B,OAAO;QACL,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,qCAAqC;QAC9C,QAAQ,EAAE;YACR,MAAM,EAAE,GAAG;YACX,UAAU,EAAE,cAAc;YAC1B,OAAO,EAAE,EAAE;YACX,IAAI;YACJ,MAAM,EAAE,EAAE;SACX;QACD,MAAM,EAAE,EAAE,GAAG,EAAE,4BAA4B,EAAE,MAAM,EAAE,MAAM,EAAE;KACvD,CAAC;AACX,CAAC;AAED,IAAI,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;IAC9G,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,MAAO,MAAc,CAAC,WAAW,CAC3C,YAAY,CAAC;QACX,IAAI,EAAE,4BAA4B;QAClC,OAAO,EAAE,mFAAmF;QAC5F,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;KACtB,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,EAAE,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0FAA0F,EAAE,KAAK,IAAI,EAAE;IAC1G,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,MAAO,MAAc,CAAC,WAAW,CAC3C,YAAY,CAAC;QACX,IAAI,EAAE,0BAA0B;QAChC,OAAO,EAAE,iFAAiF;QAC1F,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;KACtB,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;IAC5F,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,MAAO,MAAc,CAAC,WAAW,CAC3C,YAAY,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAC7C,CAAC;IAEF,MAAM,CAAC,EAAE,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,wCAAwC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"site-token-401-error-classification.test.js","sourceRoot":"","sources":["../../src/__tests__/site-token-401-error-classification.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,SAAS,WAAW,CAAC,SAAuC,EAAE;IAC5D,OAAO;QACL,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,qBAAqB;QAC1B,MAAM,EAAE,kBAAkB;QAC1B,GAAG,MAAM;KACV,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAS;IAC7B,OAAO;QACL,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,qCAAqC;QAC9C,QAAQ,EAAE;YACR,MAAM,EAAE,GAAG;YACX,UAAU,EAAE,cAAc;YAC1B,OAAO,EAAE,EAAE;YACX,IAAI;YACJ,MAAM,EAAE,EAAE;SACX;QACD,MAAM,EAAE,EAAE,GAAG,EAAE,4BAA4B,EAAE,MAAM,EAAE,MAAM,EAAE;KACvD,CAAC;AACX,CAAC;AAED,IAAI,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;IAC9G,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,MAAO,MAAc,CAAC,WAAW,CAC3C,YAAY,CAAC;QACX,IAAI,EAAE,4BAA4B;QAClC,OAAO,EAAE,mFAAmF;QAC5F,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;KACtB,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,EAAE,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0FAA0F,EAAE,KAAK,IAAI,EAAE;IAC1G,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,MAAO,MAAc,CAAC,WAAW,CAC3C,YAAY,CAAC;QACX,IAAI,EAAE,0BAA0B;QAChC,OAAO,EAAE,iFAAiF;QAC1F,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;KACtB,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;IAClF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,MAAO,MAAc,CAAC,WAAW,CAC3C,YAAY,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAC7C,CAAC;IAEF,MAAM,CAAC,EAAE,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,wCAAwC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,kBAAkB,CAAC;AAsQzE,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,mBAAmB,CAAS;IACpC,iFAAiF;IACjF,OAAO,CAAC,iBAAiB,CAAK;IAC9B,iFAAiF;IACjF,OAAO,CAAC,mBAAmB,CAAgC;IAE3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IAEhE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;gBA4Bb,WAAW,EAAE,mBAAmB,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE;IAiVvE,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IA4BrB,gEAAgE;IAChE,OAAO,CAAC,aAAa;IAUrB;;;;;;OAMG;YACW,UAAU;IA2CxB;;;;;;;;;;;;;;OAcG;YACW,WAAW;IAiJzB;;;;;;;;;OASG;YACW,kBAAkB;IAiHhC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;YACW,qBAAqB;YAiBrB,kBAAkB;IA6FhC,yFAAyF;IACzF,OAAO,CAAC,gBAAgB;IASxB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,6BAA6B;IA0BrC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,yBAAyB;IA+BjC,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,aAAa;YAmQP,kBAAkB;YA6BlB,yBAAyB;IASvC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;YAyBd,QAAQ;IAm1FtB;;;;;;OAMG;IACH;;;;;;;;;;;;;oDAagD;IAChD,OAAO,CAAC,mBAAmB,CAAoD;IAC/E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAU;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAS;IAC1D;;mDAE+C;IAC/C,OAAO,CAAC,0BAA0B,CAAoC;IAEtE;;;;;;;;OAQG;YACW,0BAA0B;YAyC1B,oBAAoB;YA6CpB,2BAA2B;IAQzC;;;;OAIG;YACW,cAAc;IAQ5B,OAAO,CAAC,mBAAmB;IA2uC3B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAe3C;IAEF;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;YAmCpB,cAAc;IA4G5B,oEAAoE;IACpE,OAAO,CAAC,iBAAiB;IAoBzB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,eAAe;YAuCT,gBAAgB;IAsoC9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwUzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6UxB,GAAG;CAyCV"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,kBAAkB,CAAC;AAsQzE,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,YAAY,CAA4B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,mBAAmB,CAAS;IACpC,iFAAiF;IACjF,OAAO,CAAC,iBAAiB,CAAK;IAC9B,iFAAiF;IACjF,OAAO,CAAC,mBAAmB,CAAgC;IAE3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IAEhE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;gBA4Bb,WAAW,EAAE,mBAAmB,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE;IAiVvE,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IA4BrB,gEAAgE;IAChE,OAAO,CAAC,aAAa;IAUrB;;;;;;OAMG;YACW,UAAU;IA2CxB;;;;;;;;;;;;;;OAcG;YACW,WAAW;IAiJzB;;;;;;;;;OASG;YACW,kBAAkB;IAiHhC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;YACW,qBAAqB;YAiBrB,kBAAkB;IA6FhC,yFAAyF;IACzF,OAAO,CAAC,gBAAgB;IASxB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,6BAA6B;IA0BrC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,yBAAyB;IA+BjC,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,aAAa;YAmQP,kBAAkB;YA6BlB,yBAAyB;IASvC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;YAyBd,QAAQ;IA82FtB;;;;;;OAMG;IACH;;;;;;;;;;;;;oDAagD;IAChD,OAAO,CAAC,mBAAmB,CAAoD;IAC/E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAU;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAS;IAC1D;;mDAE+C;IAC/C,OAAO,CAAC,0BAA0B,CAAoC;IAEtE;;;;;;;;OAQG;YACW,0BAA0B;YAyC1B,oBAAoB;YA6CpB,2BAA2B;IAQzC;;;;OAIG;YACW,cAAc;IAQ5B,OAAO,CAAC,mBAAmB;IA2uC3B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAe3C;IAEF;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;YAmCpB,cAAc;IA4G5B,oEAAoE;IACpE,OAAO,CAAC,iBAAiB;IAoBzB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,eAAe;YAuCT,gBAAgB;IA+oC9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwUzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6UxB,GAAG;CAyCV"}
package/dist/server.js CHANGED
@@ -1981,7 +1981,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
1981
1981
  },
1982
1982
  {
1983
1983
  name: 'wordpress_list_theme_builder_templates',
1984
- description: 'List the Divi Theme Builder global templates on the site (headers, footers, and body layouts). Each entry carries a layout_id you pass to update_theme_builder_template or apply_builder_patch to edit it, its kind (header/footer/body), name, and where it is assigned. Use this to find a global header before editing it (e.g. to build a mega menu). Divi 5 only.',
1984
+ description: 'List the Divi Theme Builder global templates on the site (headers, footers, and body layouts). Each entry carries a layout_id you pass to update_theme_builder_template or apply_builder_patch to edit it, its kind (header/footer/body), name, and where it is assigned. Use this to find a global header before editing it (e.g. to build a mega menu). Works on Divi 4 and Divi 5.',
1985
1985
  inputSchema: {
1986
1986
  type: 'object',
1987
1987
  properties: {},
@@ -1989,7 +1989,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
1989
1989
  },
1990
1990
  {
1991
1991
  name: 'wordpress_create_theme_builder_template',
1992
- description: 'Create a Divi global header, footer, or body Theme Builder template, with optional page assignments. Snapshot-protected (reversible within a session). Pass structure as a Divi 4 shortcode string, or a Divi 5 block/node array. Divi 5 only.',
1992
+ description: 'Create a Divi global header, footer, or body Theme Builder template, with optional page assignments. Snapshot-protected (reversible within a session). Pass structure as a Divi 4 shortcode string, or a Divi 5 block/node array. Works on Divi 4 and Divi 5.',
1993
1993
  inputSchema: {
1994
1994
  type: 'object',
1995
1995
  properties: {
@@ -2006,7 +2006,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
2006
2006
  },
2007
2007
  {
2008
2008
  name: 'wordpress_update_theme_builder_template',
2009
- description: 'Replace the content of an existing Divi Theme Builder layout (a global header, footer, or body) by its layout_id (from list_theme_builder_templates). Snapshot-protected. For a targeted single-module edit, use apply_builder_patch on the same layout_id instead. Divi 5 only.',
2009
+ description: 'Replace the content of an existing Divi Theme Builder layout (a global header, footer, or body) by its layout_id (from list_theme_builder_templates). Snapshot-protected. For a targeted single-module edit, use apply_builder_patch on the same layout_id instead. Works on Divi 4 and Divi 5.',
2010
2010
  inputSchema: {
2011
2011
  type: 'object',
2012
2012
  properties: {
@@ -2016,6 +2016,24 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
2016
2016
  required: ['layout_id', 'structure'],
2017
2017
  },
2018
2018
  },
2019
+ {
2020
+ name: 'wordpress_build_mega_menu',
2021
+ description: 'Build a complete Divi mega menu in one call. Creates (or reuses) a nav menu, adds a top-level item carrying Divi\'s "mega-menu" CSS class, turns each column into a child item and each link into a grandchild, and optionally assigns the menu to a theme location. Divi then renders the top item as a full-width mega menu. Works on Divi 4 and Divi 5.',
2022
+ inputSchema: {
2023
+ type: 'object',
2024
+ properties: {
2025
+ menu_name: { type: 'string', description: 'Name of the menu to create or reuse.' },
2026
+ top_label: { type: 'string', description: 'Label of the top-level mega-menu item (e.g. "Products").' },
2027
+ top_url: { type: 'string', description: 'Optional URL for the top item. Defaults to "#".' },
2028
+ columns: {
2029
+ type: 'array',
2030
+ description: 'The mega-menu columns: [ { "label": "Plugins", "url": "#", "links": [ { "label": "Respira", "url": "/respira" } ] } ].',
2031
+ },
2032
+ location: { type: 'string', description: 'Optional theme menu location slug to assign, e.g. "primary-menu".' },
2033
+ },
2034
+ required: ['menu_name', 'top_label', 'columns'],
2035
+ },
2036
+ },
2019
2037
  {
2020
2038
  name: 'wordpress_update_post',
2021
2039
  description: 'Update a post. Supports author reassignment, taxonomy terms (categories/tags/custom), and featured media. When direct editing is enabled and you target an original post, Respira returns a confirmation_required preflight by default so you can choose live/original or duplicate.',
@@ -2785,6 +2803,10 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
2785
2803
  fresh: { type: 'boolean', default: false, description: 'Bypass the 1h transient cache.' },
2786
2804
  site_id: { type: 'string', description: 'Per-call site override.' },
2787
2805
  },
2806
+ anyOf: [
2807
+ { required: ['page_id'] },
2808
+ { required: ['url'] },
2809
+ ],
2788
2810
  },
2789
2811
  readOnlyHint: true,
2790
2812
  },
@@ -2804,6 +2826,10 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
2804
2826
  fresh: { type: 'boolean', default: false, description: 'Bypass the 1h cache.' },
2805
2827
  site_id: { type: 'string', description: 'Per-call site override.' },
2806
2828
  },
2829
+ anyOf: [
2830
+ { required: ['page_id'] },
2831
+ { required: ['url'] },
2832
+ ],
2807
2833
  },
2808
2834
  readOnlyHint: true,
2809
2835
  },
@@ -6210,6 +6236,14 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
6210
6236
  layout_id: args.layout_id,
6211
6237
  structure: args.structure,
6212
6238
  });
6239
+ case 'wordpress_build_mega_menu':
6240
+ return await client.buildMegaMenu({
6241
+ menu_name: args.menu_name,
6242
+ top_label: args.top_label,
6243
+ top_url: args.top_url ?? undefined,
6244
+ columns: args.columns,
6245
+ location: args.location ?? undefined,
6246
+ });
6213
6247
  case 'wordpress_update_post': {
6214
6248
  const approvalsUrl = client.getApprovalsUrl();
6215
6249
  const post = await client.updatePost(args.id, args);