@respira/wordpress-mcp-server 8.3.13 → 8.3.15

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,18 @@ 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.15] - 2026-08-29
9
+
10
+ Companion release to plugin 8.8.0: a customer named Bronko rebuilt a 16-page site with Respira and sent a measured field report. These are the client-side pieces of the answer.
11
+
12
+ ### Fixed
13
+
14
+ - **The phantom "4KB limit" is gone.** Nested Divi 5 payloads over roughly 4KB appeared to arrive truncated, failing with a generic validation error that forced batches to be split and pushed one build toward literal hex colors instead of global-color variables. There was never a size limit. The inject tool's schema declared `content` as an object while every canonical payload shape is an array, so strict validators rejected the array form, and larger payloads are simply more often the nested-array shape. The schema now accepts both.
15
+ - **find_builder_targets works on Divi 5.** Agents pass the generation string the builder info reports (`divi5`), which resolved no adapter, so the tool walked nothing and answered "this page is empty" with a success flag. The generation strings now alias to the right adapter.
16
+ - **get_page_outline accepts `id`.** Every sibling read tool calls it `id`; this one demanded `page_id` and rejected the rest. Both work now.
17
+ - **batch_update stops advertising a duplicate action the server rejects.** The schema promised it, the server 400ed the entire batch. The schema now tells the truth and points at duplicate_element.
18
+ - **Every add_* shortcut states its contract up front.** They append at the end of the page, always. That used to be revealed only after a positioning parameter was silently ignored; the tool descriptions now say it before you build, along with the move_element recipe.
19
+
8
20
  ## [8.3.12] - 2026-08-25
9
21
 
10
22
  ### Fixed
package/SOUL.md CHANGED
@@ -48,6 +48,7 @@ What agents always and never do.
48
48
  - **Never edit theme PHP, `wp_postmeta`, or the WordPress database directly.** All edits go through the builder-native tools. If the customer asks for a direct edit, refuse and explain why the safer path produces the same outcome.
49
49
  - **Always pass `site_id` per call in Cowork and multi-site contexts.** Switching context silently is how cross-site mistakes happen.
50
50
  - **Always read `inline_schemas` before injecting WPBakery, Uncode, or Visual Composer shortcodes.** The schemas are the contract. Guessing produces broken output.
51
+ - **When the customer asks for a preview link to a staged change, quote `preview_url`, never the plain page url.** Every duplicate and staged write returns a signed `preview_url` (and repeats it in the response message): it renders that one draft to anyone, no WordPress login, and dies when the change is rejected. The plain `url` field is login-gated while the post is a draft, so handing it to a client is handing them a 404.
51
52
  - **When stuck: retry once with the structured hint, then run `respira_diagnose_connection`, then ASK the customer if they want to file a bug via `respira_report_issue`.** Never auto-file. The customer decides what to surface.
52
53
  - **Beautiful, accurate, fast.** Every output is judged on three axes in this order. Beautiful means it reads well and the page renders well. Accurate means it does exactly what was asked. Fast means it consumed the minimum tokens necessary.
53
54
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli-reports-effective-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-reports-effective-config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/cli-reports-effective-config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,102 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { readFileSync, existsSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, join } from 'node:path';
6
+ /**
7
+ * --test, --list and --doctor exist to answer "is my setup working". They were
8
+ * answering about a config that was not in effect.
9
+ *
10
+ * The server resolves through RESPIRA_CONFIG_B64, then RESPIRA_CONFIG_FILE, then
11
+ * ~/.respira/config.json, then WORDPRESS_URL/WORDPRESS_API_KEY, with
12
+ * normalization and placeholder detection on top. setup.ts had its own
13
+ * loadConfig() that read ~/.respira/config.json literally and swallowed every
14
+ * error. So the diagnostic and the server could disagree about the same machine.
15
+ *
16
+ * Reported by StudyCivilService (2026-08-26): the site diagnostic showed one site
17
+ * resolved from the default file, while `--test` in the same shell said
18
+ * "No sites configured". They guessed npx was resolving a different copy of the
19
+ * package. The real split was two loaders inside the same copy.
20
+ *
21
+ * Demonstrated with an inline config set and a file also present:
22
+ * server resolves -> the inline site
23
+ * --test, before -> 16 unrelated sites read from the file on disk
24
+ * --test, after -> the inline site, and names the origin
25
+ *
26
+ * Under-reporting was never the worst case. Confidently reporting a DIFFERENT
27
+ * set of sites than the server is using is, and that is what it did.
28
+ *
29
+ * setup.ts is a CLI module with work at import time, so these assertions are on
30
+ * its source rather than its exports.
31
+ */
32
+ /*
33
+ * Resolve setup.ts from source, whichever directory this test is executed from.
34
+ * `npm test` runs the compiled copy out of dist/__tests__/, where '../setup.ts'
35
+ * is dist/setup.ts and does not exist; running it directly with tsx executes
36
+ * from src/__tests__/, where it does. Try both rather than assuming one.
37
+ */
38
+ const HERE = dirname(fileURLToPath(import.meta.url));
39
+ const SETUP_CANDIDATES = [
40
+ join(HERE, '..', 'setup.ts'), // src/__tests__/
41
+ join(HERE, '..', '..', 'src', 'setup.ts'), // dist/__tests__/
42
+ ];
43
+ const SETUP_PATH = SETUP_CANDIDATES.find(p => existsSync(p));
44
+ if (!SETUP_PATH) {
45
+ throw new Error(`could not locate setup.ts from ${HERE}; looked in ${SETUP_CANDIDATES.join(', ')}`);
46
+ }
47
+ const SETUP_SRC = readFileSync(SETUP_PATH, 'utf-8');
48
+ /** Body of a top-level function declaration, by brace matching. */
49
+ function functionBody(src, name) {
50
+ const start = src.indexOf(`function ${name}(`);
51
+ assert.notEqual(start, -1, `function ${name} not found in setup.ts`);
52
+ const open = src.indexOf('{', start);
53
+ let depth = 0;
54
+ for (let i = open; i < src.length; i++) {
55
+ if (src[i] === '{')
56
+ depth++;
57
+ if (src[i] === '}') {
58
+ depth--;
59
+ if (depth === 0)
60
+ return src.slice(start, i + 1);
61
+ }
62
+ }
63
+ assert.fail(`unbalanced braces reading ${name}`);
64
+ }
65
+ describe('CLI commands report the config the server actually uses', () => {
66
+ it('imports the real loader rather than re-implementing one', () => {
67
+ assert.match(SETUP_SRC, /import \{[^}]*loadConfig as loadEffectiveConfig[^}]*\} from '\.\/config\.js'/);
68
+ assert.match(SETUP_SRC, /describeConfigOrigin/);
69
+ });
70
+ it('has no bare loadConfig() call left, which is the shape of the bug', () => {
71
+ // A bare loadConfig() in this file means the naive local loader is back.
72
+ assert.equal(/[^a-zA-Z]loadConfig\(\)/.test(SETUP_SRC.replace(/loadConfig as loadEffectiveConfig/g, '')), false, 'setup.ts calls a local loadConfig() again; reporting commands must use loadReportedConfig()');
73
+ });
74
+ for (const fn of ['testDefaultSite', 'listSites', 'runDoctor']) {
75
+ it(`${fn} resolves via loadReportedConfig`, () => {
76
+ const body = functionBody(SETUP_SRC, fn);
77
+ assert.match(body, /loadReportedConfig\(\)/, `${fn} must use the effective config`);
78
+ assert.doesNotMatch(body, /loadConfigFileForEditing\(\)/, `${fn} must not read the file directly`);
79
+ });
80
+ }
81
+ for (const fn of ['testDefaultSite', 'listSites']) {
82
+ it(`${fn} names the config source in its output`, () => {
83
+ // "No sites configured" alone sends people to re-run setup when the real
84
+ // answer is usually that a different config won.
85
+ assert.match(functionBody(SETUP_SRC, fn), /describeConfigOrigin\(\)/);
86
+ });
87
+ }
88
+ it('the doctor reports the config in effect as its own check', () => {
89
+ assert.match(functionBody(SETUP_SRC, 'runDoctor'), /Config in effect/);
90
+ });
91
+ it('the setup wizard still edits the file on disk, not the resolved view', () => {
92
+ // The wizard rewrites ~/.respira/config.json. It must keep reading that
93
+ // literal file, or it would merrily persist an inline config back to disk.
94
+ assert.match(functionBody(SETUP_SRC, 'runSetupWizard'), /loadConfigFileForEditing\(\)/);
95
+ });
96
+ it('a malformed config surfaces the reason instead of reporting emptiness', () => {
97
+ const body = functionBody(SETUP_SRC, 'loadReportedConfig');
98
+ assert.match(body, /catch \(error\)/, 'must not swallow the error silently');
99
+ assert.match(body, /Could not read the effective configuration/);
100
+ });
101
+ });
102
+ //# sourceMappingURL=cli-reports-effective-config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-reports-effective-config.test.js","sourceRoot":"","sources":["../../src/__tests__/cli-reports-effective-config.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
@@ -3077,8 +3077,12 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
3077
3077
  type: 'number',
3078
3078
  description: 'Page or post ID',
3079
3079
  },
3080
+ id: {
3081
+ type: 'number',
3082
+ description: 'Alias for page_id (every sibling read tool calls it id, so both are accepted).',
3083
+ },
3080
3084
  },
3081
- required: ['page_id'],
3085
+ required: [],
3082
3086
  },
3083
3087
  annotations: {
3084
3088
  title: "Page Outline",
@@ -3129,8 +3133,14 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
3129
3133
  description: 'Page ID',
3130
3134
  },
3131
3135
  content: {
3132
- type: 'object',
3133
- description: 'Structured content to inject in simplified format. In "replace" mode (default), this REPLACES all existing content. In "append" mode, this is added after existing content. For Gutenberg: array of blocks [{type: "core/heading", attrs: {level: 2}, content: "Hello"}, {type: "core/paragraph", attrs: {}, content: "Text here"}]. For Beaver Builder: {rows: [{cols: [{modules: [{type: "rich-text", settings: {text: "..."}}]}]}]}. For Elementor: array of widget objects. For Divi: Divi shortcode or block structure. Use extract_builder_content to see the format for any builder.',
3136
+ // F5 (Bronko's field report): this was `type: 'object'`, while the
3137
+ // canonical Divi 5 / Gutenberg / Elementor payloads are ARRAYS.
3138
+ // Strict client-side validators rejected the array shape with a
3139
+ // generic InputValidationError that looked like a size limit
3140
+ // (larger payloads are simply more often the nested-array form,
3141
+ // so the failures correlated with ~4KB and read as truncation).
3142
+ type: ['array', 'object'],
3143
+ description: 'Structured content to inject in simplified format. In "replace" mode (default), this REPLACES all existing content. In "append" mode, this is added after existing content. For Gutenberg: array of blocks [{type: "core/heading", attrs: {level: 2}, content: "Hello"}, {type: "core/paragraph", attrs: {}, content: "Text here"}]. For Beaver Builder: {rows: [{cols: [{modules: [{type: "rich-text", settings: {text: "..."}}]}]}]}. For Elementor: array of widget objects. For Divi 5: array of section nodes (see the canonical nested shape in this tool\'s description). Use extract_builder_content to see the format for any builder.',
3134
3144
  },
3135
3145
  mode: {
3136
3146
  type: 'string',
@@ -9644,8 +9654,15 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
9644
9654
  return await client.extractBuilderContent(args.builder, args.page_id);
9645
9655
  case 'wordpress_find_builder_targets':
9646
9656
  return await client.findBuilderTargets(args.builder, args.page_id, args.query, args.limit, args.offset);
9647
- case 'wordpress_get_page_outline':
9648
- return await client.getPageOutline(args.builder, args.page_id);
9657
+ case 'wordpress_get_page_outline': {
9658
+ // F9: every sibling read tool takes `id`; agents pass it here too and
9659
+ // used to get a schema error. Accept both.
9660
+ const outlineId = args.page_id ?? args.id;
9661
+ if (outlineId === undefined || outlineId === null) {
9662
+ throw new Error('get_page_outline needs page_id (or its alias id).');
9663
+ }
9664
+ return await client.getPageOutline(args.builder, outlineId);
9665
+ }
9649
9666
  case 'wordpress_get_builder_inline_schemas':
9650
9667
  return await client.getBuilderInlineSchemas(args.builder, args.types);
9651
9668
  case 'wordpress_inject_builder_content':
@@ -10819,12 +10836,12 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
10819
10836
  post_id: { type: 'number', description: 'Page/post ID' },
10820
10837
  operations: {
10821
10838
  type: 'array',
10822
- description: 'Array of operations applied in order. Each op: {action: "update"|"remove"|"move"|"duplicate", identifier_type: "id"|"admin_label"|"type"|"path", identifier_value: string, updates?: object, target_container_path?: string, position?: number, match_content?: string}.',
10839
+ description: 'Array of operations applied in order. Each op: {action: "update"|"remove"|"move", identifier_type: "id"|"admin_label"|"type"|"path", identifier_value: string, updates?: object, target_container_path?: string, position?: number, match_content?: string}. To duplicate an element, use wordpress_duplicate_element (batch duplicate is not implemented server-side; the schema used to advertise it and the server rejected the whole batch).',
10823
10840
  items: {
10824
10841
  type: 'object',
10825
10842
  required: ['action', 'identifier_type', 'identifier_value'],
10826
10843
  properties: {
10827
- action: { type: 'string', enum: ['update', 'remove', 'move', 'duplicate'] },
10844
+ action: { type: 'string', enum: ['update', 'remove', 'move'] },
10828
10845
  identifier_type: { type: 'string', enum: ['id', 'admin_label', 'type', 'widget_type', 'path', 'content'] },
10829
10846
  identifier_value: { type: 'string' },
10830
10847
  updates: { type: 'object', description: 'For action=update: flat settings patch OR nested attrs bucket. See respira_update_element for shape.' },
@@ -11387,7 +11404,11 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
11387
11404
  ];
11388
11405
  return shortcuts.map((s) => ({
11389
11406
  name: `wordpress_${s.name}`,
11390
- description: s.description,
11407
+ // F6 (Bronko's field report): the append-only behavior was only surfaced
11408
+ // AFTER a positioning param was silently ignored, so agents built whole
11409
+ // pages in content→form→rest order to control placement. State the
11410
+ // contract and the supported recipe up front.
11411
+ description: `${s.description} Appends at the END of the page (no positioning params). To place it elsewhere, call wordpress_move_element with the returned element_id.`,
11391
11412
  inputSchema: {
11392
11413
  type: 'object',
11393
11414
  properties: {