@respira/wordpress-mcp-server 8.3.21 → 8.3.22

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.
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Tickets dfe2d236, 6e94282d, addc289e, 77aae005, c2dd9d87 (staging3.naa.edu,
3
+ * mcp 8.3.20, plugin 8.8.13).
4
+ *
5
+ * The configured URL was the bare host. The web server 301s every request on
6
+ * it to the www host. Every read worked and every write failed, in 190 to
7
+ * 600ms, with "Could not connect ... no response received" and
8
+ * `respira_write_outcome_unknown`. diagnose_connection called the site fine.
9
+ *
10
+ * Mechanism (reproduced here against the real client, no adapter mocking):
11
+ *
12
+ * 1. guardAgainstMethodDowngrade() (ticket 1b0eda46, mcp 8.3.18) runs as the
13
+ * `beforeRedirect` hook and throws for a write that meets a 301/302/303.
14
+ * 2. follow-redirects catches that throw in `_processResponse`, wraps it as a
15
+ * RedirectionError (code ERR_FR_REDIRECTION_FAILURE, the guard's error as
16
+ * `.cause`) and emits it as a request 'error'.
17
+ * 3. axios turns a request 'error' into an AxiosError with `.request` and NO
18
+ * `.response`.
19
+ * 4. handleError's no-response branch therefore described a clean, immediate
20
+ * 301 answer as a dropped connection and a write of unknown outcome.
21
+ *
22
+ * Reads follow the redirect (the guard ignores them), which is why reads
23
+ * worked. And a 307/308 was followed for writes too, which re-sent the write,
24
+ * API key header included, to whatever host the Location named.
25
+ *
26
+ * The "www" host here is a second local server on a different port. Host and
27
+ * port together are what a URL's `host` compares, so this exercises the same
28
+ * code path as staging3.naa.edu -> www.staging3.naa.edu.
29
+ */
30
+ import { test, after } from 'node:test';
31
+ import assert from 'node:assert/strict';
32
+ import http from 'node:http';
33
+ import { WordPressClient } from '../wordpress-client.js';
34
+ const servers = [];
35
+ after(() => {
36
+ for (const s of servers)
37
+ s.close();
38
+ });
39
+ const WRITE_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
40
+ function routeOf(rawUrl) {
41
+ const url = new URL(rawUrl, 'http://placeholder');
42
+ return url.searchParams.get('rest_route') || url.pathname.replace(/^\/wp-json/, '') || '/';
43
+ }
44
+ async function listen(server) {
45
+ servers.push(server);
46
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
47
+ const { port } = server.address();
48
+ return `http://127.0.0.1:${port}`;
49
+ }
50
+ /** The canonical host: answers like WordPress with the Respira plugin. */
51
+ function wordpressLike(hits) {
52
+ return http.createServer((req, res) => {
53
+ req.resume();
54
+ req.on('end', () => {
55
+ hits.push({ method: req.method || '', url: req.url || '' });
56
+ const route = routeOf(req.url || '/');
57
+ const json = (status, body) => {
58
+ res.writeHead(status, { 'Content-Type': 'application/json' });
59
+ res.end(req.method === 'HEAD' ? undefined : JSON.stringify(body));
60
+ };
61
+ if (route === '/respira/v2/status')
62
+ return json(200, { status: 'ok' });
63
+ if (route === '/respira/v1/ping' && (req.method === 'GET' || req.method === 'HEAD')) {
64
+ return json(200, { ok: true, plugin: 'respira-for-wordpress' });
65
+ }
66
+ if (req.method === 'OPTIONS')
67
+ return json(200, {});
68
+ if (req.method === 'GET' || req.method === 'HEAD')
69
+ return json(200, { read: true, route });
70
+ // /ping registers no write handler, exactly like the plugin.
71
+ if (route === '/respira/v1/ping') {
72
+ return json(404, { code: 'rest_no_route', message: 'No route was found matching the URL and request method.', data: { status: 404 } });
73
+ }
74
+ return json(200, { written: true, method: req.method, route });
75
+ });
76
+ });
77
+ }
78
+ /**
79
+ * staging3.naa.edu: every request on the configured host is redirected to the
80
+ * www host, same path and query.
81
+ */
82
+ async function startCanonicalRedirectPair(status = 301) {
83
+ const wwwHits = [];
84
+ const bareHits = [];
85
+ const wwwOrigin = await listen(wordpressLike(wwwHits));
86
+ const bareOrigin = await listen(http.createServer((req, res) => {
87
+ req.resume();
88
+ req.on('end', () => {
89
+ bareHits.push({ method: req.method || '', url: req.url || '' });
90
+ res.writeHead(status, { Location: `${wwwOrigin}${req.url}`, 'Content-Type': 'text/html' });
91
+ res.end('<html><body>Moved</body></html>');
92
+ });
93
+ }));
94
+ const client = new WordPressClient({
95
+ id: 'dfe2d236',
96
+ name: 'dfe2d236',
97
+ url: bareOrigin,
98
+ apiKey: 'respira_test_key',
99
+ });
100
+ const wwwWrites = () => wwwHits.filter((h) => WRITE_METHODS.has(h.method) && !h.url.includes('/server/compatibility'));
101
+ return { client, wwwOrigin, bareOrigin, wwwHits, bareHits, wwwWrites };
102
+ }
103
+ const escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
104
+ async function captureRejection(p) {
105
+ try {
106
+ const value = await p;
107
+ assert.fail(`expected a rejection, got a result: ${JSON.stringify(value)}`);
108
+ }
109
+ catch (err) {
110
+ if (err?.code === 'ERR_ASSERTION')
111
+ throw err;
112
+ return err;
113
+ }
114
+ }
115
+ function assertSiteUrlRedirect(err, wwwOrigin) {
116
+ assert.equal(err.name, 'respira_site_url_redirects', `unexpected error name ${err.name}: ${err.message}`);
117
+ assert.doesNotMatch(err.message, /no response received/i, 'a clean 301 answer is not a dropped connection');
118
+ assert.doesNotMatch(err.message, /may have completed/i, 'the outcome is known: nothing ran');
119
+ assert.match(err.message, new RegExp(`redirects to ${escapeRe(wwwOrigin)}`));
120
+ assert.match(err.message, /update the URL for this site in your Respira config/i);
121
+ const envelope = err.respiraErrorEnvelope;
122
+ assert.ok(envelope, 'structured fields reach the tool result');
123
+ assert.equal(envelope.suggested_url, wwwOrigin);
124
+ assert.ok(String(envelope.redirect_location).startsWith(wwwOrigin));
125
+ }
126
+ test('control: reads follow the redirect and keep working', async () => {
127
+ const site = await startCanonicalRedirectPair(301);
128
+ const result = await site.client.callRestV1('GET', '/ping');
129
+ assert.deepEqual(result, { ok: true, plugin: 'respira-for-wordpress' });
130
+ });
131
+ test('delete_page on a host that 301s to www names the redirect instead of "no response received"', async () => {
132
+ const site = await startCanonicalRedirectPair(301);
133
+ const err = await captureRejection(site.client.deletePage(5));
134
+ assertSiteUrlRedirect(err, site.wwwOrigin);
135
+ assert.equal(site.bareHits.filter((h) => h.method === 'DELETE').length, 1, 'one DELETE, answered by the redirect');
136
+ assert.equal(site.wwwWrites().length, 0, 'the write was never re-sent to the other host');
137
+ });
138
+ test('a PUT write (update_bricks_global_class) meets the same redirect: no POST fallback, no replay', async () => {
139
+ const site = await startCanonicalRedirectPair(301);
140
+ const err = await captureRejection(site.client.callRestV2('PUT', '/bricks/global-classes/zzprobe1', { name: 'zzprobe1' }));
141
+ assertSiteUrlRedirect(err, site.wwwOrigin);
142
+ const writesOnBare = site.bareHits.filter((h) => WRITE_METHODS.has(h.method) && h.url.includes('/bricks/global-classes/'));
143
+ assert.deepEqual(writesOnBare.map((h) => h.method), ['PUT'], 'no PUT->POST or method-override retry');
144
+ assert.equal(site.wwwWrites().length, 0);
145
+ });
146
+ test('a POST write meets the same redirect and says so', async () => {
147
+ const site = await startCanonicalRedirectPair(301);
148
+ const err = await captureRejection(site.client.callRestV1('POST', '/pages', { title: 'x' }));
149
+ assertSiteUrlRedirect(err, site.wwwOrigin);
150
+ assert.equal(site.wwwWrites().length, 0);
151
+ });
152
+ test('a 307 to another host is not followed for a write (it would replay the write there)', async () => {
153
+ const site = await startCanonicalRedirectPair(307);
154
+ const err = await captureRejection(site.client.deletePage(6));
155
+ assertSiteUrlRedirect(err, site.wwwOrigin);
156
+ assert.equal(site.wwwWrites().length, 0, 'the DELETE must not be replayed on the www host');
157
+ });
158
+ test('control: a same-host 307 on a write is still followed', async () => {
159
+ const hits = [];
160
+ const inner = wordpressLike(hits);
161
+ let origin = '';
162
+ const server = http.createServer((req, res) => {
163
+ if ((req.url || '').startsWith('/wp-json/respira/v1/old/')) {
164
+ req.resume();
165
+ req.on('end', () => {
166
+ res.writeHead(307, { Location: `${origin}${(req.url || '').replace('/old/', '/pages/')}` });
167
+ res.end();
168
+ });
169
+ return;
170
+ }
171
+ inner.emit('request', req, res);
172
+ });
173
+ origin = await listen(server);
174
+ const client = new WordPressClient({ id: 'same-host-307', name: 'same-host-307', url: origin, apiKey: 'respira_test_key' });
175
+ const result = await client.callRestV1('DELETE', '/old/9');
176
+ assert.equal(result.written, true);
177
+ assert.equal(result.route, '/respira/v1/pages/9');
178
+ });
179
+ test('diagnose_connection reports the canonical-host redirect instead of grading writes as fine', async () => {
180
+ const site = await startCanonicalRedirectPair(301);
181
+ const report = await site.client.diagnoseConnection({ probe_timeout_ms: 5000 });
182
+ assert.ok(report.site_url_redirect, 'site_url_redirect must be reported');
183
+ assert.equal(report.site_url_redirect.status, 301);
184
+ assert.ok(String(report.site_url_redirect.location).startsWith(site.wwwOrigin));
185
+ assert.equal(report.site_url_redirect.suggested_url, site.wwwOrigin);
186
+ assert.equal(report.write_method_verdict, 'site_url_redirects');
187
+ assert.equal(report.write_method_blocked, true, 'every write is refused, so writes are not fine');
188
+ assert.match(String(report.recommendations[0] || ''), new RegExp(escapeRe(site.wwwOrigin)));
189
+ assert.match(String(report.recommendations[0] || ''), /Respira config/i);
190
+ });
191
+ //# sourceMappingURL=dfe2d236-site-url-redirects-on-write.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dfe2d236-site-url-redirects-on-write.test.js","sourceRoot":"","sources":["../../src/__tests__/dfe2d236-site-url-redirects-on-write.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The shape of one entry in `operations` for update_site_template,
3
+ * update_site_pattern and update_site_navigation.
4
+ *
5
+ * All three route to Respira_FSE_Templates::apply_operations() in the plugin
6
+ * (class-respira-fse-templates.php), and every field below is a key that
7
+ * function reads. Nothing here is aspirational: if a field is added, the
8
+ * plugin has to read it first.
9
+ *
10
+ * Until ticket 303ad1de each operation was published as a bare
11
+ * `{ type: 'object' }`. The description listed the operation names but never
12
+ * said which key carries them, so agents guessed. The first guess is `type`,
13
+ * which the plugin refused with 422 "Operation 1: unsupported operation type".
14
+ * The plugin now also accepts `op` and `type`, but `operation` is the key this
15
+ * schema names, and it wins when more than one is sent.
16
+ */
17
+ /** The names apply_operations() dispatches on, in the plugin's order. */
18
+ export declare const FSE_OPERATION_TYPES: readonly ["set_attributes", "replace_block", "insert_before", "insert_after", "insert_inside", "remove_block", "move_block"];
19
+ export declare const FSE_OPERATION_ITEM_SCHEMA: Record<string, unknown>;
20
+ //# sourceMappingURL=fse-operation-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fse-operation-schema.d.ts","sourceRoot":"","sources":["../src/fse-operation-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,8HAQtB,CAAC;AA4BX,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA6B7D,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * The shape of one entry in `operations` for update_site_template,
3
+ * update_site_pattern and update_site_navigation.
4
+ *
5
+ * All three route to Respira_FSE_Templates::apply_operations() in the plugin
6
+ * (class-respira-fse-templates.php), and every field below is a key that
7
+ * function reads. Nothing here is aspirational: if a field is added, the
8
+ * plugin has to read it first.
9
+ *
10
+ * Until ticket 303ad1de each operation was published as a bare
11
+ * `{ type: 'object' }`. The description listed the operation names but never
12
+ * said which key carries them, so agents guessed. The first guess is `type`,
13
+ * which the plugin refused with 422 "Operation 1: unsupported operation type".
14
+ * The plugin now also accepts `op` and `type`, but `operation` is the key this
15
+ * schema names, and it wins when more than one is sent.
16
+ */
17
+ /** The names apply_operations() dispatches on, in the plugin's order. */
18
+ export const FSE_OPERATION_TYPES = [
19
+ 'set_attributes',
20
+ 'replace_block',
21
+ 'insert_before',
22
+ 'insert_after',
23
+ 'insert_inside',
24
+ 'remove_block',
25
+ 'move_block',
26
+ ];
27
+ const blockPath = (description) => ({
28
+ type: 'array',
29
+ items: { type: 'integer', minimum: 0 },
30
+ minItems: 1,
31
+ description,
32
+ });
33
+ const FSE_BLOCK_SCHEMA = {
34
+ type: 'object',
35
+ description: 'A block in the shape get_site_template returns in `blocks`. WordPress saves a block from innerContent, not innerHTML.',
36
+ properties: {
37
+ blockName: { type: 'string', description: 'Block name, for example core/html or core/paragraph.' },
38
+ attrs: { type: 'object', description: 'Block attributes stored in the block comment.' },
39
+ innerContent: {
40
+ type: 'array',
41
+ items: { type: ['string', 'null'] },
42
+ description: 'What WordPress saves: markup strings, plus one null per inner block, in order. For core/html send the markup as ["<div>...</div>"]. When omitted it is taken from innerHTML (a block with no inner blocks) or set to one null per inner block.',
43
+ },
44
+ innerHTML: { type: 'string', description: 'Markup of a block with no inner blocks. Used only when innerContent is omitted.' },
45
+ innerBlocks: { type: 'array', items: { type: 'object' }, description: 'Child blocks, each in this same shape.' },
46
+ },
47
+ required: ['blockName'],
48
+ };
49
+ export const FSE_OPERATION_ITEM_SCHEMA = {
50
+ type: 'object',
51
+ description: 'One path-addressed block operation. Name it with `operation`. set_attributes needs path and attributes; replace_block, insert_before, insert_after and insert_inside need path and block; remove_block needs path; move_block needs from_path and to_path.',
52
+ properties: {
53
+ operation: {
54
+ type: 'string',
55
+ enum: [...FSE_OPERATION_TYPES],
56
+ description: 'Which operation to apply. `op` and `type` are accepted as the same key, but `operation` wins when several are sent.',
57
+ },
58
+ path: blockPath('Indexes into `blocks` from the get_site_template read, top level first, then innerBlocks. Top-level indexes count the whitespace entries (blockName null) that WordPress keeps between blocks.'),
59
+ expected_block_name: {
60
+ type: 'string',
61
+ description: 'Optional guard. The operation is refused with respira_fse_wrong_target if the block at path has a different blockName.',
62
+ },
63
+ attributes: { type: 'object', description: 'set_attributes: merged into the block attrs. Attributes not listed are kept.' },
64
+ block: {
65
+ ...FSE_BLOCK_SCHEMA,
66
+ description: 'replace_block: the block that replaces the one at path. insert_before and insert_after: the block to add next to it. insert_inside: the block to add as a child. ' +
67
+ FSE_BLOCK_SCHEMA.description,
68
+ },
69
+ position: { type: 'integer', minimum: 0, description: 'insert_inside: index among the children. Omit to append.' },
70
+ from_path: blockPath('move_block: path of the block to move. Defaults to path.'),
71
+ to_path: blockPath('move_block: the moved block lands before the block at this path, indexed after the block is removed from from_path.'),
72
+ },
73
+ required: ['operation'],
74
+ };
75
+ //# sourceMappingURL=fse-operation-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fse-operation-schema.js","sourceRoot":"","sources":["../src/fse-operation-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,gBAAgB;IAChB,eAAe;IACf,eAAe;IACf,cAAc;IACd,eAAe;IACf,cAAc;IACd,YAAY;CACJ,CAAC;AAEX,MAAM,SAAS,GAAG,CAAC,WAAmB,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;IACtC,QAAQ,EAAE,CAAC;IACX,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,uHAAuH;IACzH,UAAU,EAAE;QACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sDAAsD,EAAE;QAClG,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;QACvF,YAAY,EAAE;YACZ,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnC,WAAW,EACT,gPAAgP;SACnP;QACD,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iFAAiF,EAAE;QAC7H,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,wCAAwC,EAAE;KACjH;IACD,QAAQ,EAAE,CAAC,WAAW,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAA4B;IAChE,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,4PAA4P;IAC9P,UAAU,EAAE;QACV,SAAS,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,GAAG,mBAAmB,CAAC;YAC9B,WAAW,EAAE,qHAAqH;SACnI;QACD,IAAI,EAAE,SAAS,CACb,gMAAgM,CACjM;QACD,mBAAmB,EAAE;YACnB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wHAAwH;SACtI;QACD,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8EAA8E,EAAE;QAC3H,KAAK,EAAE;YACL,GAAG,gBAAgB;YACnB,WAAW,EACT,mKAAmK;gBACnK,gBAAgB,CAAC,WAAW;SAC/B;QACD,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,0DAA0D,EAAE;QAClH,SAAS,EAAE,SAAS,CAAC,0DAA0D,CAAC;QAChF,OAAO,EAAE,SAAS,CAAC,qHAAqH,CAAC;KAC1I;IACD,QAAQ,EAAE,CAAC,WAAW,CAAC;CACxB,CAAC"}
@@ -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
@@ -18,6 +18,7 @@ import { getBricksTools, dispatchBricksTool } from './bricks-tools.js';
18
18
  import { getElementorTools, dispatchElementorTool } from './elementor-tools.js';
19
19
  import { getAcfTools, resolveAcfToolName } from './acf-tools.js';
20
20
  import { getUsageEmitter, deriveToolKind } from './usage-emitter.js';
21
+ import { FSE_OPERATION_ITEM_SCHEMA } from './fse-operation-schema.js';
21
22
  import { collapseLauncherProcesses, validateApiKeyShape, describeConfigOrigin, configOriginKey } from './config.js';
22
23
  // Process-local secret keeps target hashes useful for same-session retry
23
24
  // detection without making low-entropy WordPress ids reversible centrally.
@@ -3713,7 +3714,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
3713
3714
  id: { type: 'string' },
3714
3715
  kind: { type: 'string', enum: ['template', 'template_part'] },
3715
3716
  expected_fingerprint: { type: 'string' },
3716
- operations: { type: 'array', items: { type: 'object' }, maxItems: 50 },
3717
+ operations: { type: 'array', items: FSE_OPERATION_ITEM_SCHEMA, maxItems: 50 },
3717
3718
  verification_marker: { type: 'string' },
3718
3719
  dry_run: { type: 'boolean' },
3719
3720
  edit_target: { type: 'string', enum: ['approval', 'live'] },
@@ -3824,7 +3825,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
3824
3825
  properties: {
3825
3826
  id: { type: 'string' },
3826
3827
  expected_fingerprint: { type: 'string' },
3827
- operations: { type: 'array', items: { type: 'object' }, maxItems: 50 },
3828
+ operations: { type: 'array', items: FSE_OPERATION_ITEM_SCHEMA, maxItems: 50 },
3828
3829
  verification_marker: { type: 'string' },
3829
3830
  dry_run: { type: 'boolean' },
3830
3831
  edit_target: { type: 'string', enum: ['approval', 'live'] },
@@ -3940,7 +3941,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
3940
3941
  properties: {
3941
3942
  id: { type: 'string' },
3942
3943
  expected_fingerprint: { type: 'string' },
3943
- operations: { type: 'array', items: { type: 'object' }, maxItems: 50 },
3944
+ operations: { type: 'array', items: FSE_OPERATION_ITEM_SCHEMA, maxItems: 50 },
3944
3945
  verification_marker: { type: 'string' },
3945
3946
  dry_run: { type: 'boolean' },
3946
3947
  edit_target: { type: 'string', enum: ['approval', 'live'] },
@@ -11191,7 +11192,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
11191
11192
  },
11192
11193
  options: {
11193
11194
  type: 'object',
11194
- description: 'Conversion options: {status, title, preserve_tokens, font_substitution, responsive}. preserve_tokens (default TRUE): registers the document\'s :root CSS custom properties as the builder\'s own global tokens (Elementor globals, Bricks palette/variables, theme.json, ...) and keeps converted content referencing them, so the design system stays a set of named tokens instead of copied literals. Existing site tokens are never overwritten. Pass preserve_tokens: false to resolve every var() to its literal value and leave the site\'s global stores untouched.',
11195
+ description: 'Conversion options: {status, title, mode, preserve_tokens, font_substitution, responsive}. mode (plugin 8.8.34+): "fidelity" is the default when the document has a stylesheet on Divi 5 and Bricks: the file\'s structure is kept one to one, every leaf keeps its markup, and the stylesheet travels verbatim scoped to the page, so the page looks like the file and the site\'s design direction is not applied; "restyle" re-types the page in the builder\'s own settings and site tokens. preserve_tokens (default TRUE): registers the document\'s :root CSS custom properties as the builder\'s own global tokens (Elementor globals, Bricks palette/variables, theme.json, ...) and keeps converted content referencing them, so the design system stays a set of named tokens instead of copied literals. Existing site tokens are never overwritten. Pass preserve_tokens: false to resolve every var() to its literal value and leave the site\'s global stores untouched.',
11195
11196
  },
11196
11197
  },
11197
11198
  required: ['html'],