@respira/wordpress-mcp-server 8.3.24 → 8.3.25
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 +12 -0
- package/README.md +97 -20
- package/TOOL_CATALOG.md +445 -307
- package/dist/__tests__/0e6bd33c-redeem-preserves-per-site-settings.test.js +3 -2
- package/dist/__tests__/0e6bd33c-redeem-preserves-per-site-settings.test.js.map +1 -1
- package/dist/__tests__/81c478df-create-page-duplicate-id-aliases.test.d.ts +11 -0
- package/dist/__tests__/81c478df-create-page-duplicate-id-aliases.test.d.ts.map +1 -0
- package/dist/__tests__/81c478df-create-page-duplicate-id-aliases.test.js +80 -0
- package/dist/__tests__/81c478df-create-page-duplicate-id-aliases.test.js.map +1 -0
- package/dist/__tests__/plugin-slug-path-encoding.test.d.ts +2 -0
- package/dist/__tests__/plugin-slug-path-encoding.test.d.ts.map +1 -0
- package/dist/__tests__/plugin-slug-path-encoding.test.js +41 -0
- package/dist/__tests__/plugin-slug-path-encoding.test.js.map +1 -0
- package/dist/__tests__/release-9-surface.test.d.ts +2 -0
- package/dist/__tests__/release-9-surface.test.d.ts.map +1 -0
- package/dist/__tests__/release-9-surface.test.js +197 -0
- package/dist/__tests__/release-9-surface.test.js.map +1 -0
- package/dist/install-skills.d.ts +4 -5
- package/dist/install-skills.d.ts.map +1 -1
- package/dist/install-skills.js +4 -5
- package/dist/install-skills.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +252 -73
- package/dist/server.js.map +1 -1
- package/dist/skill-prompts.d.ts +43 -0
- package/dist/skill-prompts.d.ts.map +1 -0
- package/dist/skill-prompts.js +135 -0
- package/dist/skill-prompts.js.map +1 -0
- package/dist/wordpress-client.d.ts +40 -11
- package/dist/wordpress-client.d.ts.map +1 -1
- package/dist/wordpress-client.js +74 -22
- package/dist/wordpress-client.js.map +1 -1
- package/package.json +2 -2
- package/skills/activity-report-composer/SKILL.md +17 -5
- package/skills/activity-report-composer/metadata.json +2 -2
- package/skills/art-direction/SKILL.md +9 -3
- package/skills/art-direction/metadata.json +7 -3
- package/skills/brand-voice-synthesizer/SKILL.md +36 -16
- package/skills/brand-voice-synthesizer/metadata.json +8 -4
- package/skills/build-oxygen6-page/SKILL.md +17 -2
- package/skills/conversion-audit/SKILL.md +12 -0
- package/skills/custom-post-type-architect/SKILL.md +12 -0
- package/skills/figma-to-bricks/SKILL.md +4 -2
- package/skills/figma-to-divi/SKILL.md +4 -2
- package/skills/figma-to-elementor/SKILL.md +8 -1
- package/skills/figma-to-gutenberg/SKILL.md +4 -2
- package/skills/html-to-breakdance/SKILL.md +7 -3
- package/skills/html-to-breakdance/metadata.json +7 -3
- package/skills/html-to-bricks/SKILL.md +7 -3
- package/skills/html-to-bricks/metadata.json +7 -3
- package/skills/internal-link-builder/SKILL.md +12 -0
- package/skills/migrate-beaver-builder-to-bricks/SKILL.md +19 -3
- package/skills/migrate-beaver-builder-to-gutenberg/SKILL.md +19 -3
- package/skills/migrate-brizy-to-gutenberg/SKILL.md +19 -3
- package/skills/migrate-divi-to-breakdance/SKILL.md +19 -3
- package/skills/migrate-divi-to-bricks/SKILL.md +19 -3
- package/skills/migrate-divi-to-gutenberg/SKILL.md +19 -3
- package/skills/migrate-elementor-to-breakdance/SKILL.md +20 -4
- package/skills/migrate-elementor-to-bricks/SKILL.md +20 -4
- package/skills/migrate-elementor-to-gutenberg/SKILL.md +20 -4
- package/skills/migrate-elementor-to-oxygen/SKILL.md +20 -4
- package/skills/migrate-oxygen-to-breakdance/SKILL.md +19 -3
- package/skills/migrate-oxygen-to-bricks/SKILL.md +19 -3
- package/skills/migrate-thrive-architect-to-gutenberg/SKILL.md +19 -3
- package/skills/migrate-visual-composer-to-gutenberg/SKILL.md +19 -3
- package/skills/migrate-wpbakery-to-bricks/SKILL.md +19 -3
- package/skills/migrate-wpbakery-to-gutenberg/SKILL.md +19 -3
- package/skills/mobile-experience-report/SKILL.md +12 -0
- package/skills/murmur-review-loop/SKILL.md +142 -0
- package/skills/page-template-library/SKILL.md +12 -0
- package/skills/respira-builder-edits/SKILL.md +1 -0
- package/skills/respira-setup-assistant/SKILL.md +12 -0
- package/skills/respira-site-audit/SKILL.md +18 -6
- package/skills/respira-woocommerce/SKILL.md +1 -0
- package/skills/seo-aeo-amplifier/SKILL.md +14 -2
- package/skills/seo-aeo-amplifier/metadata.json +2 -2
- package/skills/stale-content-detector/SKILL.md +12 -0
- package/skills/technical-debt-audit/SKILL.md +14 -2
- package/skills/woo-marketing-campaigns/SKILL.md +12 -9
- package/skills/woo-pricing-promotions/SKILL.md +9 -9
- package/skills/woocommerce-health-check/SKILL.md +22 -8
- package/skills/wordpress-ai-image-optimizer/SKILL.md +14 -2
- package/skills/wordpress-ai-image-optimizer/metadata.json +2 -2
- package/skills/wordpress-security-review/SKILL.md +154 -0
- package/skills/wordpress-site-dna/README.md +1 -1
- package/skills/wordpress-site-dna/SKILL.md +52 -19
- package/tool-capabilities.json +3171 -370
package/dist/server.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides tools for AI coding assistants to interact with WordPress sites
|
|
5
5
|
*/
|
|
6
|
-
import { Server } from '@modelcontextprotocol/server';
|
|
6
|
+
import { Server, ProtocolError, ProtocolErrorCode } from '@modelcontextprotocol/server';
|
|
7
7
|
import { setMcpClientInfo } from './agent-signature.js';
|
|
8
8
|
import { serveStdio } from '@modelcontextprotocol/server/stdio';
|
|
9
9
|
import { execSync } from 'child_process';
|
|
@@ -17,6 +17,7 @@ import { RespiraVersionChecker } from './version-checker.js';
|
|
|
17
17
|
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
|
+
import { listSkillPrompts, getSkillPrompt } from './skill-prompts.js';
|
|
20
21
|
import { getUsageEmitter, deriveToolKind } from './usage-emitter.js';
|
|
21
22
|
import { FSE_OPERATION_ITEM_SCHEMA } from './fse-operation-schema.js';
|
|
22
23
|
import { collapseLauncherProcesses, validateApiKeyShape, describeConfigOrigin, configOriginKey } from './config.js';
|
|
@@ -133,6 +134,19 @@ function saveRespiraMcpState(patch) {
|
|
|
133
134
|
console.error('[respira-mcp] could not write', STATE_FILE_PATH, '-', err?.message);
|
|
134
135
|
}
|
|
135
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Tools removed in a major release, keyed by the name a caller would still
|
|
139
|
+
* send. dispatchToolCall answers them with the replacement instead of a bare
|
|
140
|
+
* "Unknown tool". Not advertised and not dispatched, so the parity gate never
|
|
141
|
+
* sees them.
|
|
142
|
+
*/
|
|
143
|
+
const RETIRED_TOOLS = {
|
|
144
|
+
woocommerce_sales_report: {
|
|
145
|
+
replacement: 'woocommerce_revenue_summary',
|
|
146
|
+
removedIn: '9.0',
|
|
147
|
+
note: 'It takes date_start and date_end (ISO, in the store timezone) instead of period, date_min and date_max, and states exactly which order statuses and amounts it counts.',
|
|
148
|
+
},
|
|
149
|
+
};
|
|
136
150
|
const MCP_SERVER_VERSION = (() => {
|
|
137
151
|
try {
|
|
138
152
|
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -566,6 +580,8 @@ export class RespiraWordPressServer {
|
|
|
566
580
|
}, {
|
|
567
581
|
capabilities: {
|
|
568
582
|
tools: {},
|
|
583
|
+
// The bundled skills catalog, one prompt per skill (skill-prompts.ts).
|
|
584
|
+
prompts: {},
|
|
569
585
|
},
|
|
570
586
|
instructions: `${SOUL_MD_CONTENT}
|
|
571
587
|
|
|
@@ -592,7 +608,7 @@ Follow these on every site. They are what separates a great result from a frustr
|
|
|
592
608
|
|
|
593
609
|
## Tool naming
|
|
594
610
|
|
|
595
|
-
Always use respira_* tool names (e.g. respira_update_page, respira_find_element). The wordpress_* names
|
|
611
|
+
Always use respira_* tool names (e.g. respira_update_page, respira_find_element). The older wordpress_* names still answer, so a saved call keeps working, but new calls should use respira_*.
|
|
596
612
|
|
|
597
613
|
## Step 1: Understand the site
|
|
598
614
|
|
|
@@ -1826,6 +1842,20 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
1826
1842
|
tools: await this.getTools(),
|
|
1827
1843
|
};
|
|
1828
1844
|
});
|
|
1845
|
+
// Skills as prompts. Served from the skills folder bundled into the
|
|
1846
|
+
// package, so listing them needs no site and no network: a client can
|
|
1847
|
+
// offer every Respira skill as a slash command before a site is set up.
|
|
1848
|
+
this.server.setRequestHandler('prompts/list', async () => {
|
|
1849
|
+
return { prompts: listSkillPrompts() };
|
|
1850
|
+
});
|
|
1851
|
+
this.server.setRequestHandler('prompts/get', async (request) => {
|
|
1852
|
+
const { name, arguments: promptArgs } = request.params;
|
|
1853
|
+
const prompt = getSkillPrompt(String(name || ''), promptArgs);
|
|
1854
|
+
if (!prompt) {
|
|
1855
|
+
throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown prompt: ${name}. Call prompts/list for the Respira skills this server offers.`);
|
|
1856
|
+
}
|
|
1857
|
+
return prompt;
|
|
1858
|
+
});
|
|
1829
1859
|
// Handle tool calls
|
|
1830
1860
|
this.server.setRequestHandler('tools/call', async (request) => {
|
|
1831
1861
|
const { name, arguments: args } = request.params;
|
|
@@ -2566,12 +2596,20 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
2566
2596
|
type: 'number',
|
|
2567
2597
|
description: 'ID of the original page to duplicate',
|
|
2568
2598
|
},
|
|
2599
|
+
page_id: {
|
|
2600
|
+
type: 'number',
|
|
2601
|
+
description: 'Alias for original_id, matching the builder page tools',
|
|
2602
|
+
},
|
|
2603
|
+
post_id: {
|
|
2604
|
+
type: 'number',
|
|
2605
|
+
description: 'Alias for original_id, matching tools that operate on any post type',
|
|
2606
|
+
},
|
|
2569
2607
|
suffix: {
|
|
2570
2608
|
type: 'string',
|
|
2571
2609
|
description: 'Optional suffix for the duplicated page title',
|
|
2572
2610
|
},
|
|
2573
2611
|
},
|
|
2574
|
-
required: [
|
|
2612
|
+
required: [],
|
|
2575
2613
|
},
|
|
2576
2614
|
annotations: {
|
|
2577
2615
|
title: "Duplicate Page",
|
|
@@ -2649,7 +2687,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
2649
2687
|
},
|
|
2650
2688
|
{
|
|
2651
2689
|
name: 'wordpress_delete_page',
|
|
2652
|
-
description: 'Delete a page. IMPORTANT: By default, this only works on Respira-created duplicates. To delete an original: pass `force=true` AND `confirm_live_edit=true`. The "Allow Direct Editing" setting in Respira must also be enabled (disabled by default for safety).\n\nApproval flow
|
|
2690
|
+
description: 'Delete a page. IMPORTANT: By default, this only works on Respira-created duplicates. To delete an original: pass `force=true` AND `confirm_live_edit=true`. The "Allow Direct Editing" setting in Respira must also be enabled (disabled by default for safety).\n\nApproval flow: the first call returns `code: respira_approval_required` with `data.approval_request.approval_token`. Pass that token back via the `approval_token` param on the next call to complete the delete.',
|
|
2653
2691
|
inputSchema: {
|
|
2654
2692
|
type: 'object',
|
|
2655
2693
|
properties: {
|
|
@@ -2663,7 +2701,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
2663
2701
|
},
|
|
2664
2702
|
confirm_live_edit: {
|
|
2665
2703
|
type: 'boolean',
|
|
2666
|
-
description: '
|
|
2704
|
+
description: 'Operator confirmation that a force-delete on an original is intended. Required alongside force=true, and honoured only when "Allow Direct Editing" is enabled in Respira settings.',
|
|
2667
2705
|
},
|
|
2668
2706
|
approval_token: {
|
|
2669
2707
|
type: 'string',
|
|
@@ -3081,7 +3119,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
3081
3119
|
},
|
|
3082
3120
|
{
|
|
3083
3121
|
name: 'wordpress_delete_post',
|
|
3084
|
-
description: 'Delete a post. IMPORTANT: By default, this only works on Respira-created duplicates. To delete an original: pass `force=true` AND `confirm_live_edit=true`. The "Allow Direct Editing" setting in Respira must also be enabled (disabled by default for safety).\n\nApproval flow: destructive — the FIRST call returns `code: respira_approval_required` with `data.approval_request.approval_token`, and deletes nothing. Pass that exact token back via the `approval_token` param on the next call to complete the delete. Deleting a Respira-created duplicate still takes both calls; the approval gate runs before the duplicate check.\n\
|
|
3122
|
+
description: 'Delete a post. IMPORTANT: By default, this only works on Respira-created duplicates. To delete an original: pass `force=true` AND `confirm_live_edit=true`. The "Allow Direct Editing" setting in Respira must also be enabled (disabled by default for safety).\n\nApproval flow: destructive — the FIRST call returns `code: respira_approval_required` with `data.approval_request.approval_token`, and deletes nothing. Pass that exact token back via the `approval_token` param on the next call to complete the delete. Deleting a Respira-created duplicate still takes both calls; the approval gate runs before the duplicate check.\n\nThe response is always the site\'s answer: the approval token, the refusal reason, or the success flag.',
|
|
3085
3123
|
inputSchema: {
|
|
3086
3124
|
type: 'object',
|
|
3087
3125
|
properties: {
|
|
@@ -3324,7 +3362,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
3324
3362
|
},
|
|
3325
3363
|
mode: {
|
|
3326
3364
|
type: 'string',
|
|
3327
|
-
description: 'replace (default): OVERWRITES all existing page content. append: adds new content after existing elements, preserving the current layout.
|
|
3365
|
+
description: 'replace (default): OVERWRITES all existing page content. append: adds new content after existing elements, preserving the current layout. Replacing a page that already has content requires confirm_replace=true.',
|
|
3328
3366
|
enum: ['replace', 'append'],
|
|
3329
3367
|
},
|
|
3330
3368
|
confirm_replace: {
|
|
@@ -3660,6 +3698,57 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
3660
3698
|
openWorldHint: false,
|
|
3661
3699
|
},
|
|
3662
3700
|
},
|
|
3701
|
+
{
|
|
3702
|
+
// The client report. Before 9.0 it existed only as the ability
|
|
3703
|
+
// respira/generate-activity-report, which invoke_ability cannot reach
|
|
3704
|
+
// (the inhale gate refuses it), so every skill that asked for it
|
|
3705
|
+
// failed at step 1.
|
|
3706
|
+
name: 'wordpress_generate_activity_report',
|
|
3707
|
+
description: 'Generate the client report for a period from this site\'s Respira activity log: what changed, through which tools and builders, concrete before and after examples, notable moments, and time saved against per-tool manual baselines. Returns structured data for you to write up in the chosen framing, such as an agency client report or a personal recap. Reads the log and changes nothing. Defaults to the last 30 days. Needs an administrator key.',
|
|
3708
|
+
inputSchema: {
|
|
3709
|
+
type: 'object',
|
|
3710
|
+
properties: {
|
|
3711
|
+
window_days: { type: 'integer', minimum: 1, maximum: 365, description: 'Days back from now. Default 30. Ignored when start_date and end_date are given.' },
|
|
3712
|
+
start_date: { type: 'string', description: 'ISO 8601 start date. Use with end_date.' },
|
|
3713
|
+
end_date: { type: 'string', description: 'ISO 8601 end date. Use with start_date.' },
|
|
3714
|
+
content_types: {
|
|
3715
|
+
type: 'array',
|
|
3716
|
+
items: { type: 'string', enum: ['pages', 'posts', 'products', 'variables', 'snapshots', 'migrations', 'audits', 'skills'] },
|
|
3717
|
+
description: 'Limit the report to these content types. Default all.',
|
|
3718
|
+
},
|
|
3719
|
+
scope: {
|
|
3720
|
+
type: 'object',
|
|
3721
|
+
properties: {
|
|
3722
|
+
page_ids: { type: 'array', items: { type: 'integer' } },
|
|
3723
|
+
post_ids: { type: 'array', items: { type: 'integer' } },
|
|
3724
|
+
product_ids: { type: 'array', items: { type: 'integer' } },
|
|
3725
|
+
builder: { type: 'string' },
|
|
3726
|
+
},
|
|
3727
|
+
description: 'Focus on specific page, post or product IDs, or on one page builder by slug.',
|
|
3728
|
+
},
|
|
3729
|
+
framing: {
|
|
3730
|
+
type: 'string',
|
|
3731
|
+
enum: ['personal_recap', 'agency_client_report', 'agency_case_study', 'team_report', 'testimonial_draft', 'build_in_public'],
|
|
3732
|
+
description: 'Who the write-up is for. Default personal_recap; use agency_client_report for a client.',
|
|
3733
|
+
},
|
|
3734
|
+
output_mode: { type: 'string', enum: ['structured', 'client_report', 'ops_report'], description: 'structured returns the data; client_report and ops_report add ready-made sections.' },
|
|
3735
|
+
report_tone: { type: 'string', enum: ['client_update', 'retainer_proof', 'internal_ops'], description: 'Tone for the ready-made sections.' },
|
|
3736
|
+
client_name: { type: 'string', description: 'Who an agency report is addressed to.' },
|
|
3737
|
+
include_examples: { type: 'boolean', description: 'Up to 10 edits with 200-character before and after excerpts. Default true.' },
|
|
3738
|
+
include_time_estimates: { type: 'boolean', description: 'Estimate time saved from per-tool baselines. Default true.' },
|
|
3739
|
+
anonymize: { type: 'boolean', description: 'Redact page titles, URLs and excerpts, for a report that will be published. Default false.' },
|
|
3740
|
+
currency: { type: 'string', description: 'ISO 4217 code for the cost estimate. Default EUR.' },
|
|
3741
|
+
hourly_rate: { type: 'number', description: 'When set, time savings include a cost estimate at this hourly rate.' },
|
|
3742
|
+
},
|
|
3743
|
+
},
|
|
3744
|
+
annotations: {
|
|
3745
|
+
title: "Generate Activity Report",
|
|
3746
|
+
readOnlyHint: true,
|
|
3747
|
+
destructiveHint: false,
|
|
3748
|
+
idempotentHint: true,
|
|
3749
|
+
openWorldHint: false,
|
|
3750
|
+
},
|
|
3751
|
+
},
|
|
3663
3752
|
{
|
|
3664
3753
|
name: 'wordpress_get_site_template',
|
|
3665
3754
|
description: 'Read one FSE template or template part as normalized blocks. Returns its source, render route, supported targeted operations, and expected_fingerprint for safe updates.',
|
|
@@ -4650,7 +4739,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
4650
4739
|
},
|
|
4651
4740
|
probe_timeout_ms: {
|
|
4652
4741
|
type: 'number',
|
|
4653
|
-
description: 'Optional per-probe timeout in milliseconds. Default 30000
|
|
4742
|
+
description: 'Optional per-probe timeout in milliseconds. Default 30000. Clamped to [5000, 60000]. Bump this when probing sites behind slow edge layers (some Cloudflare custom rules add 8+ seconds before forwarding to origin).',
|
|
4654
4743
|
minimum: 5000,
|
|
4655
4744
|
maximum: 60000,
|
|
4656
4745
|
},
|
|
@@ -4786,31 +4875,35 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
4786
4875
|
},
|
|
4787
4876
|
},
|
|
4788
4877
|
{
|
|
4878
|
+
// Until 9.0 this returned a heuristic estimate from static page
|
|
4879
|
+
// analysis. AER's "what a visitor notices first" shortcut and three
|
|
4880
|
+
// skills call it by name expecting field data, so it now runs the real
|
|
4881
|
+
// PageSpeed Insights audit instead of being removed.
|
|
4789
4882
|
name: 'wordpress_get_core_web_vitals',
|
|
4790
|
-
description: '
|
|
4883
|
+
description: 'Core Web Vitals for a page, measured by Google PageSpeed Insights: LCP, CLS and INP from real Chrome users over the last 28 days when Google publishes field data for the URL, plus Lighthouse lab metrics. Runs the same audit as respira_run_pagespeed_audit with one strategy, so the page must be publicly reachable; drafts and local sites return an error that says so. Cached for 1 hour per URL and strategy.',
|
|
4791
4884
|
inputSchema: {
|
|
4792
4885
|
type: 'object',
|
|
4793
4886
|
properties: {
|
|
4794
|
-
page_id: {
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
},
|
|
4887
|
+
page_id: { type: 'number', description: 'Page ID to measure. Resolved to its public permalink.' },
|
|
4888
|
+
url: { type: 'string', description: 'Explicit public URL to measure instead of a page ID.' },
|
|
4889
|
+
strategy: { type: 'string', enum: ['mobile', 'desktop'], default: 'mobile', description: 'Device profile. Default mobile.' },
|
|
4798
4890
|
},
|
|
4799
|
-
|
|
4891
|
+
anyOf: [
|
|
4892
|
+
{ required: ['page_id'] },
|
|
4893
|
+
{ required: ['url'] },
|
|
4894
|
+
],
|
|
4800
4895
|
},
|
|
4801
4896
|
annotations: {
|
|
4802
4897
|
title: "Core Web Vitals",
|
|
4803
4898
|
readOnlyHint: true,
|
|
4804
4899
|
destructiveHint: false,
|
|
4805
4900
|
idempotentHint: true,
|
|
4806
|
-
openWorldHint:
|
|
4901
|
+
openWorldHint: true,
|
|
4807
4902
|
},
|
|
4808
4903
|
},
|
|
4809
4904
|
{
|
|
4810
|
-
//
|
|
4811
|
-
//
|
|
4812
|
-
// Lighthouse lab data + CrUX field data (when available) + the
|
|
4813
|
-
// opportunity list ranked by metric savings.
|
|
4905
|
+
// Real PageSpeed Insights v5 audit: Lighthouse lab data, CrUX field
|
|
4906
|
+
// data when available, and opportunities ranked by metric savings.
|
|
4814
4907
|
name: 'wordpress_run_pagespeed_audit',
|
|
4815
4908
|
description: 'Run a real PageSpeed Insights v5 audit against a public URL. Returns Lighthouse lab data (scores for performance/accessibility/best-practices/seo, lab metrics FCP/LCP/TBT/CLS/SI/TTI, opportunities ranked by savings_ms, diagnostics) plus CrUX field data (real-user p75 metrics over the trailing ~28 days, when Google has enough traffic to publish them for the URL). Cached for 1 hour per (url, strategy). Pass `fresh=true` to bypass the cache. `strategy="both"` runs mobile + desktop in series. Set the `respira_pagespeed_api_key` WordPress option to lift the 1 req/sec free-tier rate limit to 200 req/min.',
|
|
4816
4909
|
inputSchema: {
|
|
@@ -4836,9 +4929,8 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
4836
4929
|
},
|
|
4837
4930
|
},
|
|
4838
4931
|
{
|
|
4839
|
-
//
|
|
4840
|
-
//
|
|
4841
|
-
// `pagespeed` slot. Use for periodic site-wide health passes; use
|
|
4932
|
+
// Standard-analyzer-envelope wrapper around PSI. Feeds the Health tab
|
|
4933
|
+
// composite via Respira_Site_Health's `pagespeed` slot. Use for periodic site-wide health passes; use
|
|
4842
4934
|
// `respira_run_pagespeed_audit` for the raw lab+field data.
|
|
4843
4935
|
name: 'wordpress_analyze_pagespeed',
|
|
4844
4936
|
description: 'Analyzer-envelope wrapper around the PSI audit. Returns the standard `{success, score, grade, issues, recommendations, metrics, data_source, measured_at}` shape that the Reports → Health tab consumes. Score = Lighthouse performance score (0-100). Grade A≥90, B≥75, C≥60, D≥40, F<40. Issues derived from Lighthouse opportunities, ranked by savings_ms. CrUX p75 field-data surfaces as an info-priority recommendation when available.',
|
|
@@ -5016,7 +5108,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5016
5108
|
// Safety & Security center
|
|
5017
5109
|
{
|
|
5018
5110
|
name: 'wordpress_run_security_audit',
|
|
5019
|
-
description: 'Run a bounded
|
|
5111
|
+
description: 'Run a bounded WordPress security audit. Returns authoritative WordPress/WooCommerce versions, official core checksum mismatches, administrators and account hygiene, standard and must-use plugins, themes, WordPress cron hooks, advisory indicators, scan coverage and explicit host-level limitations. The audit reads and never changes the site, deep_scan included. One flag writes: probe_uploads_execution, off by default, puts one inert PHP file in uploads, requests it to learn whether PHP runs there, then deletes it. The result includes known_vulnerabilities: installed core, plugins and themes matched against the Respira vulnerability database for a licensed site, with status ok or unavailable. An unavailable status never means the site is clean. known_vulnerabilities=false skips that match. On plugins older than 9.0, deep_scan also runs the uploads probe.',
|
|
5020
5112
|
inputSchema: {
|
|
5021
5113
|
type: 'object',
|
|
5022
5114
|
properties: {
|
|
@@ -5028,7 +5120,17 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5028
5120
|
deep_scan: {
|
|
5029
5121
|
type: 'boolean',
|
|
5030
5122
|
default: false,
|
|
5031
|
-
description: 'Inspect uploads and must-use plugin paths with strict file, time, symlink and result limits.',
|
|
5123
|
+
description: 'Inspect uploads and must-use plugin paths for executable files, with strict file, time, symlink and result limits. Reads only on plugin 9.0 and newer.',
|
|
5124
|
+
},
|
|
5125
|
+
probe_uploads_execution: {
|
|
5126
|
+
type: 'boolean',
|
|
5127
|
+
default: false,
|
|
5128
|
+
description: 'Writes one inert PHP file into uploads, requests it to test whether PHP executes there, then deletes it. Off by default. File-change monitors such as Wordfence may report the file. Needs plugin 9.0 or newer; older plugins ignore it.',
|
|
5129
|
+
},
|
|
5130
|
+
known_vulnerabilities: {
|
|
5131
|
+
type: 'boolean',
|
|
5132
|
+
default: true,
|
|
5133
|
+
description: 'Match installed core, plugins and themes against the Respira vulnerability database. On by default; false skips that round trip. Needs plugin 9.0 or newer.',
|
|
5032
5134
|
},
|
|
5033
5135
|
},
|
|
5034
5136
|
},
|
|
@@ -5042,17 +5144,17 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5042
5144
|
},
|
|
5043
5145
|
{
|
|
5044
5146
|
name: 'wordpress_update_core_security',
|
|
5045
|
-
description: 'Update WordPress core to
|
|
5147
|
+
description: 'Update WordPress core to the security release WordPress.org offers on the site\'s current release branch. Requires a recent recoverable backup, then explicit two-step approval. The first call returns respira_approval_required and an approval_token; repeat the same arguments with that token. The result verifies the running version, REST/frontend boot and official checksums. WordPress core has no automatic rollback, and the receipt says so. Plugins older than 9.0 accept only the releases in their own catalog.',
|
|
5046
5148
|
inputSchema: {
|
|
5047
5149
|
type: 'object',
|
|
5048
5150
|
properties: {
|
|
5049
5151
|
advisory_id: {
|
|
5050
5152
|
type: 'string',
|
|
5051
|
-
description: '
|
|
5153
|
+
description: 'Security advisory ID from respira_run_security_audit, recorded on the receipt. Do not guess it: run the audit first and use the advisory it reports.',
|
|
5052
5154
|
},
|
|
5053
5155
|
target_version: {
|
|
5054
5156
|
type: 'string',
|
|
5055
|
-
description: '
|
|
5157
|
+
description: 'The exact version WordPress.org offers as the update on this site\'s own release branch, as reported by respira_run_security_audit. The plugin refuses any other version and never moves a site across branches.',
|
|
5056
5158
|
},
|
|
5057
5159
|
backup_confirmed: {
|
|
5058
5160
|
type: 'boolean',
|
|
@@ -5073,6 +5175,60 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5073
5175
|
openWorldHint: true,
|
|
5074
5176
|
},
|
|
5075
5177
|
},
|
|
5178
|
+
{
|
|
5179
|
+
name: 'wordpress_update_theme',
|
|
5180
|
+
description: 'Update a theme to the latest version offered to this site, then check that the site still answers (REST API, front page, fatal-error marker). Requires plugin management to be enabled in Respira settings. Approval-gated: the first call returns `respira_approval_required` with an `approval_token`; call again with the same `stylesheet` plus that token. If the result carries `stop_batch: true`, stop updating and check the site. There is no automatic rollback.',
|
|
5181
|
+
inputSchema: {
|
|
5182
|
+
type: 'object',
|
|
5183
|
+
properties: {
|
|
5184
|
+
stylesheet: {
|
|
5185
|
+
type: 'string',
|
|
5186
|
+
description: 'Theme directory name (its stylesheet), as respira_run_security_audit lists it under checks.themes.',
|
|
5187
|
+
},
|
|
5188
|
+
approval_token: {
|
|
5189
|
+
type: 'string',
|
|
5190
|
+
description: 'Second-step approval token returned by the first call. Echo it back unchanged with the same stylesheet.',
|
|
5191
|
+
},
|
|
5192
|
+
},
|
|
5193
|
+
required: ['stylesheet'],
|
|
5194
|
+
},
|
|
5195
|
+
annotations: {
|
|
5196
|
+
title: "Update Theme",
|
|
5197
|
+
readOnlyHint: false,
|
|
5198
|
+
destructiveHint: true,
|
|
5199
|
+
idempotentHint: true,
|
|
5200
|
+
openWorldHint: true,
|
|
5201
|
+
},
|
|
5202
|
+
},
|
|
5203
|
+
{
|
|
5204
|
+
name: 'wordpress_revoke_application_password',
|
|
5205
|
+
description: 'Revoke one WordPress application password, by user id and uuid as respira_run_security_audit reports them under checks.account_hygiene. Anything that signs in with it stops working and it cannot be restored. Approval-gated: the first call returns `respira_approval_required` with an `approval_token`; call again with the same arguments plus that token. The password this request itself signed in with is refused.',
|
|
5206
|
+
inputSchema: {
|
|
5207
|
+
type: 'object',
|
|
5208
|
+
properties: {
|
|
5209
|
+
user_id: {
|
|
5210
|
+
type: 'integer',
|
|
5211
|
+
description: 'The user the application password belongs to.',
|
|
5212
|
+
},
|
|
5213
|
+
uuid: {
|
|
5214
|
+
type: 'string',
|
|
5215
|
+
description: 'The application password uuid from the security audit. Never the password itself.',
|
|
5216
|
+
},
|
|
5217
|
+
approval_token: {
|
|
5218
|
+
type: 'string',
|
|
5219
|
+
description: 'Second-step approval token returned by the first call. Echo it back unchanged with the same user_id and uuid.',
|
|
5220
|
+
},
|
|
5221
|
+
},
|
|
5222
|
+
required: ['user_id', 'uuid'],
|
|
5223
|
+
},
|
|
5224
|
+
annotations: {
|
|
5225
|
+
title: "Revoke Application Password",
|
|
5226
|
+
readOnlyHint: false,
|
|
5227
|
+
destructiveHint: true,
|
|
5228
|
+
idempotentHint: true,
|
|
5229
|
+
openWorldHint: false,
|
|
5230
|
+
},
|
|
5231
|
+
},
|
|
5076
5232
|
// Accessibility tools
|
|
5077
5233
|
{
|
|
5078
5234
|
name: 'wordpress_list_accessibility_scans',
|
|
@@ -5155,10 +5311,12 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5155
5311
|
openWorldHint: false,
|
|
5156
5312
|
},
|
|
5157
5313
|
},
|
|
5158
|
-
// Plugin Management tools
|
|
5314
|
+
// Plugin Management tools. The EXPERIMENTAL label came off in 9.0: every
|
|
5315
|
+
// mutation is approval-gated, and activation has probed the site and
|
|
5316
|
+
// rolled itself back on failure since plugin 8.5.5.
|
|
5159
5317
|
{
|
|
5160
5318
|
name: 'wordpress_list_plugins',
|
|
5161
|
-
description: '
|
|
5319
|
+
description: 'List all installed plugins with their status, version, and update availability. Requires plugin management to be enabled in Respira settings.',
|
|
5162
5320
|
inputSchema: {
|
|
5163
5321
|
type: 'object',
|
|
5164
5322
|
properties: {},
|
|
@@ -5173,7 +5331,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5173
5331
|
},
|
|
5174
5332
|
{
|
|
5175
5333
|
name: 'wordpress_install_plugin',
|
|
5176
|
-
description: '
|
|
5334
|
+
description: 'Install a plugin from WordPress.org or a ZIP URL. Requires plugin management to be enabled in Respira settings. Approval-gated: first call returns `respira_approval_required` with an `approval_token`; call again with that token to complete the install. Install only what the site owner asked for.',
|
|
5177
5335
|
inputSchema: {
|
|
5178
5336
|
type: 'object',
|
|
5179
5337
|
properties: {
|
|
@@ -5203,7 +5361,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5203
5361
|
},
|
|
5204
5362
|
{
|
|
5205
5363
|
name: 'wordpress_activate_plugin',
|
|
5206
|
-
description: '
|
|
5364
|
+
description: 'Safely activate a plugin. Respira checks declared PHP, WordPress, dependency and companion-plugin compatibility, activates in a fresh loopback request, probes REST and frontend boot, and automatically deactivates the plugin if the site fails. Approval-gated. Use force_without_probe only after explicit operator approval on a host that blocks loopback requests.',
|
|
5207
5365
|
inputSchema: {
|
|
5208
5366
|
type: 'object',
|
|
5209
5367
|
properties: {
|
|
@@ -5232,7 +5390,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5232
5390
|
},
|
|
5233
5391
|
{
|
|
5234
5392
|
name: 'wordpress_deactivate_plugin',
|
|
5235
|
-
description: '
|
|
5393
|
+
description: 'Deactivate a plugin. Requires plugin management to be enabled in Respira settings. Approval-gated: first call returns `respira_approval_required` with an `approval_token`; call again with the same `slug` plus that token to complete deactivation.',
|
|
5236
5394
|
inputSchema: {
|
|
5237
5395
|
type: 'object',
|
|
5238
5396
|
properties: {
|
|
@@ -5257,7 +5415,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5257
5415
|
},
|
|
5258
5416
|
{
|
|
5259
5417
|
name: 'wordpress_update_plugin',
|
|
5260
|
-
description: '
|
|
5418
|
+
description: 'Update a plugin to the latest version. Requires plugin management to be enabled in Respira settings. Approval-gated: first call returns `respira_approval_required` with an `approval_token`; call again with the same `slug` plus that token to complete the update. Make sure a recent backup exists before updating, and load the front page afterwards to confirm the site still renders.',
|
|
5261
5419
|
inputSchema: {
|
|
5262
5420
|
type: 'object',
|
|
5263
5421
|
properties: {
|
|
@@ -5282,7 +5440,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5282
5440
|
},
|
|
5283
5441
|
{
|
|
5284
5442
|
name: 'wordpress_delete_plugin',
|
|
5285
|
-
description: '
|
|
5443
|
+
description: 'Permanently delete a plugin. Requires plugin management to be enabled in Respira settings. The plugin must be deactivated first. Approval-gated: first call returns `respira_approval_required` with an `approval_token`; call again with the same `slug` plus that token to confirm deletion.',
|
|
5286
5444
|
inputSchema: {
|
|
5287
5445
|
type: 'object',
|
|
5288
5446
|
properties: {
|
|
@@ -5357,7 +5515,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5357
5515
|
},
|
|
5358
5516
|
{
|
|
5359
5517
|
name: 'wordpress_create_user',
|
|
5360
|
-
description: 'Create a new user.\n\nApproval flow
|
|
5518
|
+
description: 'Create a new user.\n\nApproval flow: the first call returns `code: respira_approval_required` with `data.approval_request.approval_token`. Pass that token back via the `approval_token` param on the next call to complete the create.',
|
|
5361
5519
|
inputSchema: {
|
|
5362
5520
|
type: 'object',
|
|
5363
5521
|
properties: {
|
|
@@ -5394,7 +5552,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5394
5552
|
},
|
|
5395
5553
|
{
|
|
5396
5554
|
name: 'wordpress_update_user',
|
|
5397
|
-
description: 'Update user information.\n\nApproval flow
|
|
5555
|
+
description: 'Update user information.\n\nApproval flow: the first call returns `respira_approval_required` with `approval_token`; pass it back to complete the update.',
|
|
5398
5556
|
inputSchema: {
|
|
5399
5557
|
type: 'object',
|
|
5400
5558
|
properties: {
|
|
@@ -5435,7 +5593,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
5435
5593
|
},
|
|
5436
5594
|
{
|
|
5437
5595
|
name: 'wordpress_delete_user',
|
|
5438
|
-
description: 'Delete a user.\n\nApproval flow
|
|
5596
|
+
description: 'Delete a user.\n\nApproval flow: the first call returns `respira_approval_required` with `approval_token`; pass it back to complete the delete.',
|
|
5439
5597
|
inputSchema: {
|
|
5440
5598
|
type: 'object',
|
|
5441
5599
|
properties: {
|
|
@@ -6531,7 +6689,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
6531
6689
|
},
|
|
6532
6690
|
{
|
|
6533
6691
|
name: 'wordpress_delete_custom_post',
|
|
6534
|
-
description: 'Delete a custom post.\n\nSafety flow
|
|
6692
|
+
description: 'Delete a custom post.\n\nSafety flow: by default this only works on Respira-created duplicates. To delete an original: pass `force=true` AND `confirm_live_edit=true` (the latter requires "Allow Direct Editing" enabled in Respira settings). The approval gate may also fire: if the response is `respira_approval_required`, pass the returned `approval_token` back to complete the delete.',
|
|
6535
6693
|
inputSchema: {
|
|
6536
6694
|
type: 'object',
|
|
6537
6695
|
properties: {
|
|
@@ -6610,7 +6768,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
6610
6768
|
},
|
|
6611
6769
|
{
|
|
6612
6770
|
name: 'wordpress_update_option',
|
|
6613
|
-
description: 'Update an option value.',
|
|
6771
|
+
description: 'Update an option value. Send the value in the same type get_option returns. A string stays a string, even when it contains JSON, because many plugins store JSON as text and decode it themselves. Send an object or array only for options that already hold one, such as theme_mods. Writing an object or array over an option that holds text is refused unless allow_type_change is true.',
|
|
6614
6772
|
inputSchema: {
|
|
6615
6773
|
type: 'object',
|
|
6616
6774
|
properties: {
|
|
@@ -6619,7 +6777,15 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
6619
6777
|
description: 'Option name',
|
|
6620
6778
|
},
|
|
6621
6779
|
value: {
|
|
6622
|
-
description: 'Option value
|
|
6780
|
+
description: 'Option value, in the type get_option returns for this option. Text stays text (JSON-encode it if needed). Objects or arrays only for options that already hold them, such as theme_mods.',
|
|
6781
|
+
},
|
|
6782
|
+
allow_type_change: {
|
|
6783
|
+
type: 'boolean',
|
|
6784
|
+
description: 'Set true only to really replace an option that holds text with an object or array. Without it that write is refused, because a plugin that decodes its own text option can crash on every page load.',
|
|
6785
|
+
},
|
|
6786
|
+
allow_object_overwrite: {
|
|
6787
|
+
type: 'boolean',
|
|
6788
|
+
description: 'Set true only to replace an option that stores a PHP object, and only when the new value keeps the same shape. Without it that write is refused.',
|
|
6623
6789
|
},
|
|
6624
6790
|
},
|
|
6625
6791
|
required: ['option', 'value'],
|
|
@@ -6771,7 +6937,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
6771
6937
|
},
|
|
6772
6938
|
{
|
|
6773
6939
|
name: 'wordpress_delete_media',
|
|
6774
|
-
description: 'Delete a media file. Approval-gated
|
|
6940
|
+
description: 'Delete a media file. Approval-gated: the first call returns `code: respira_approval_required` with an `approval_token`; pass that token in the second call to confirm. Same flow as `delete_page` / `delete_user` / `delete_plugin`.',
|
|
6775
6941
|
inputSchema: {
|
|
6776
6942
|
type: 'object',
|
|
6777
6943
|
properties: {
|
|
@@ -6891,7 +7057,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
6891
7057
|
},
|
|
6892
7058
|
{
|
|
6893
7059
|
name: 'wordpress_delete_menu',
|
|
6894
|
-
description: 'Delete a navigation menu.\n\nApproval flow
|
|
7060
|
+
description: 'Delete a navigation menu.\n\nApproval flow: the first call returns `respira_approval_required` with `approval_token`; pass it back to complete the delete.',
|
|
6895
7061
|
inputSchema: {
|
|
6896
7062
|
type: 'object',
|
|
6897
7063
|
properties: {
|
|
@@ -7156,9 +7322,10 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
7156
7322
|
}
|
|
7157
7323
|
// Generate respira_* aliases for all wordpress_* tools.
|
|
7158
7324
|
const allTools = this.generateDualTools(tools);
|
|
7159
|
-
// Context-aware tool filtering:
|
|
7160
|
-
//
|
|
7161
|
-
//
|
|
7325
|
+
// Context-aware tool filtering: builder-specific tools appear only on the
|
|
7326
|
+
// builder they serve, and WooCommerce tools only where WooCommerce runs.
|
|
7327
|
+
// When the site context cannot be read, everything is shown (fail-open).
|
|
7328
|
+
// The README's "Tools on one site" table has the measured counts.
|
|
7162
7329
|
return this.filterToolsByContext(allTools);
|
|
7163
7330
|
}
|
|
7164
7331
|
/**
|
|
@@ -7719,25 +7886,6 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
7719
7886
|
openWorldHint: false,
|
|
7720
7887
|
},
|
|
7721
7888
|
},
|
|
7722
|
-
{
|
|
7723
|
-
name: 'woocommerce_sales_report',
|
|
7724
|
-
description: 'Deprecated compatibility alias for woocommerce_revenue_summary. Retained for two minor releases.',
|
|
7725
|
-
inputSchema: {
|
|
7726
|
-
type: 'object',
|
|
7727
|
-
properties: {
|
|
7728
|
-
period: { type: 'string', description: 'week, month, year, custom' },
|
|
7729
|
-
date_min: { type: 'string', description: 'Start date for custom period' },
|
|
7730
|
-
date_max: { type: 'string', description: 'End date for custom period' },
|
|
7731
|
-
},
|
|
7732
|
-
},
|
|
7733
|
-
annotations: {
|
|
7734
|
-
title: "Sales Report",
|
|
7735
|
-
readOnlyHint: true,
|
|
7736
|
-
destructiveHint: false,
|
|
7737
|
-
idempotentHint: true,
|
|
7738
|
-
openWorldHint: false,
|
|
7739
|
-
},
|
|
7740
|
-
},
|
|
7741
7889
|
{
|
|
7742
7890
|
name: 'woocommerce_revenue_summary',
|
|
7743
7891
|
description: 'Bounded HPOS-compatible revenue summary with currency, store timezone, exact date boundaries, included statuses, pagination coverage, and explicit gross/discount/refund/tax/shipping/net definitions.',
|
|
@@ -9784,11 +9932,16 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
9784
9932
|
return await client.listPages(args);
|
|
9785
9933
|
case 'wordpress_read_page':
|
|
9786
9934
|
return await client.getPage(args.id, args.include);
|
|
9787
|
-
case 'wordpress_create_page_duplicate':
|
|
9935
|
+
case 'wordpress_create_page_duplicate': {
|
|
9936
|
+
const originalId = args.original_id ?? args.page_id ?? args.post_id;
|
|
9937
|
+
if (originalId === undefined || originalId === null) {
|
|
9938
|
+
throw new Error('create_page_duplicate needs original_id, page_id, or post_id.');
|
|
9939
|
+
}
|
|
9788
9940
|
return {
|
|
9789
|
-
...(await client.duplicatePage(
|
|
9941
|
+
...(await client.duplicatePage(originalId, args.suffix, args.include)),
|
|
9790
9942
|
respira_approvals_url: client.getApprovalsUrl(),
|
|
9791
9943
|
};
|
|
9944
|
+
}
|
|
9792
9945
|
case 'wordpress_update_page': {
|
|
9793
9946
|
const approvalsUrl = client.getApprovalsUrl();
|
|
9794
9947
|
const page = await client.updatePage(args.id, args);
|
|
@@ -10092,7 +10245,11 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10092
10245
|
case 'wordpress_analyze_performance':
|
|
10093
10246
|
return await client.analyzePerformance(args.page_id);
|
|
10094
10247
|
case 'wordpress_get_core_web_vitals':
|
|
10095
|
-
return await client.getCoreWebVitals(
|
|
10248
|
+
return await client.getCoreWebVitals({
|
|
10249
|
+
page_id: args.page_id,
|
|
10250
|
+
url: args.url,
|
|
10251
|
+
strategy: args.strategy,
|
|
10252
|
+
});
|
|
10096
10253
|
case 'wordpress_run_pagespeed_audit':
|
|
10097
10254
|
return await client.runPageSpeedAudit({
|
|
10098
10255
|
page_id: args.page_id,
|
|
@@ -10124,7 +10281,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10124
10281
|
case 'wordpress_check_structured_data':
|
|
10125
10282
|
return await client.checkStructuredData(args.page_id);
|
|
10126
10283
|
case 'wordpress_run_security_audit':
|
|
10127
|
-
return await client.runSecurityAudit(args.advisory_ids || [], args.deep_scan === true);
|
|
10284
|
+
return await client.runSecurityAudit(args.advisory_ids || [], args.deep_scan === true, args.probe_uploads_execution === true, args.known_vulnerabilities !== false);
|
|
10128
10285
|
case 'wordpress_update_core_security':
|
|
10129
10286
|
return await client.updateCoreSecurity({
|
|
10130
10287
|
advisoryId: args.advisory_id,
|
|
@@ -10132,6 +10289,10 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10132
10289
|
backupConfirmed: args.backup_confirmed === true,
|
|
10133
10290
|
approvalToken: args.approval_token,
|
|
10134
10291
|
});
|
|
10292
|
+
case 'wordpress_update_theme':
|
|
10293
|
+
return await client.updateTheme(args.stylesheet, args.approval_token);
|
|
10294
|
+
case 'wordpress_revoke_application_password':
|
|
10295
|
+
return await client.revokeApplicationPassword(Number(args.user_id), String(args.uuid), args.approval_token);
|
|
10135
10296
|
// Accessibility
|
|
10136
10297
|
case 'wordpress_list_accessibility_scans':
|
|
10137
10298
|
return await client.listAccessibilityScans({
|
|
@@ -10145,7 +10306,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10145
10306
|
return await client.scanPageAccessibility(args.page_id, args.standard, args.url);
|
|
10146
10307
|
case 'wordpress_apply_accessibility_fixes':
|
|
10147
10308
|
return await client.applyAccessibilityFixes(args.scan_id, args.rule_ids);
|
|
10148
|
-
// Plugin Management
|
|
10309
|
+
// Plugin Management
|
|
10149
10310
|
case 'wordpress_list_plugins':
|
|
10150
10311
|
return await client.listPlugins();
|
|
10151
10312
|
case 'wordpress_install_plugin':
|
|
@@ -10274,7 +10435,10 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10274
10435
|
case 'wordpress_get_option':
|
|
10275
10436
|
return await client.getOption(args.option);
|
|
10276
10437
|
case 'wordpress_update_option':
|
|
10277
|
-
return await client.updateOption(args.option, args.value
|
|
10438
|
+
return await client.updateOption(args.option, args.value, {
|
|
10439
|
+
allow_type_change: args.allow_type_change,
|
|
10440
|
+
allow_object_overwrite: args.allow_object_overwrite,
|
|
10441
|
+
});
|
|
10278
10442
|
case 'wordpress_delete_option':
|
|
10279
10443
|
return await client.deleteOption(args.option, args.approval_token);
|
|
10280
10444
|
case 'wordpress_purge_cache':
|
|
@@ -10341,6 +10505,10 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10341
10505
|
return await client.callRestV1('GET', '/activity', args);
|
|
10342
10506
|
case 'wordpress_get_activity':
|
|
10343
10507
|
return await client.callRestV1('GET', `/activity/${args.id}`);
|
|
10508
|
+
case 'wordpress_generate_activity_report': {
|
|
10509
|
+
const { site_id: _siteId, ...reportInput } = args || {};
|
|
10510
|
+
return await client.generateActivityReport(reportInput);
|
|
10511
|
+
}
|
|
10344
10512
|
case 'wordpress_get_site_template':
|
|
10345
10513
|
return await client.callRestV2('GET', '/fse/template', args);
|
|
10346
10514
|
case 'wordpress_create_site_template':
|
|
@@ -10478,8 +10646,6 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10478
10646
|
const { id, ...payload } = args;
|
|
10479
10647
|
return await client.woocommerceUpdateStock(id, payload);
|
|
10480
10648
|
}
|
|
10481
|
-
case 'woocommerce_sales_report':
|
|
10482
|
-
return await client.woocommerceSalesReport(args);
|
|
10483
10649
|
case 'woocommerce_revenue_summary':
|
|
10484
10650
|
return await client.callRestV1('GET', '/woocommerce/reports/revenue-summary', args);
|
|
10485
10651
|
case 'woocommerce_sales_timeseries':
|
|
@@ -10891,6 +11057,19 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10891
11057
|
}
|
|
10892
11058
|
// Return isError result instead of throwing — unknown tool is an execution
|
|
10893
11059
|
// error, not a protocol error. This lets LLMs self-correct gracefully.
|
|
11060
|
+
// A tool removed in a major release answers with its replacement, so a
|
|
11061
|
+
// saved workflow or an older skill learns the new name in one turn
|
|
11062
|
+
// instead of guessing from "Unknown tool".
|
|
11063
|
+
const retired = RETIRED_TOOLS[name];
|
|
11064
|
+
if (retired) {
|
|
11065
|
+
return {
|
|
11066
|
+
__respira_is_error: true,
|
|
11067
|
+
error: `Retired tool: ${name}`,
|
|
11068
|
+
code: 'respira_tool_retired',
|
|
11069
|
+
replacement: retired.replacement,
|
|
11070
|
+
hint: `${name} was removed in ${retired.removedIn}. Call ${retired.replacement} instead. ${retired.note}`,
|
|
11071
|
+
};
|
|
11072
|
+
}
|
|
10894
11073
|
return {
|
|
10895
11074
|
__respira_is_error: true,
|
|
10896
11075
|
error: `Unknown tool: ${name}`,
|
|
@@ -10969,7 +11148,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
|
|
|
10969
11148
|
editTarget: {
|
|
10970
11149
|
type: 'string',
|
|
10971
11150
|
enum: ['live', 'duplicate'],
|
|
10972
|
-
description: 'Deprecated camelCase alias of edit_target. Prefer edit_target. Kept
|
|
11151
|
+
description: 'Deprecated camelCase alias of edit_target. Prefer edit_target. Kept so older callers keep working.',
|
|
10973
11152
|
},
|
|
10974
11153
|
confirm_live_edit: {
|
|
10975
11154
|
type: 'boolean',
|