@wootsup/yt-builder-mcp 1.10.0 → 1.12.0
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 +12 -11
- package/bin/yt-builder-mcp.js +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +1 -1
- package/dist/catalog/tool-catalog-markdown.d.ts.map +1 -1
- package/dist/catalog/tool-catalog-markdown.js +13 -1
- package/dist/catalog/tool-catalog-markdown.js.map +1 -1
- package/dist/cli/doctor-command.d.ts.map +1 -1
- package/dist/cli/doctor-command.js +22 -2
- package/dist/cli/doctor-command.js.map +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/clients/index.d.ts +1 -1
- package/dist/clients/index.js +1 -1
- package/dist/diagnostics/ca-reexec.js +2 -2
- package/dist/diagnostics/diagnose-network-error.d.ts +1 -1
- package/dist/diagnostics/doctor.d.ts +34 -2
- package/dist/diagnostics/doctor.d.ts.map +1 -1
- package/dist/diagnostics/doctor.js +63 -2
- package/dist/diagnostics/doctor.js.map +1 -1
- package/dist/diagnostics/startup-self-probe.js +1 -1
- package/dist/gateway/advanced-read-tool.d.ts.map +1 -1
- package/dist/gateway/advanced-read-tool.js +14 -2
- package/dist/gateway/advanced-read-tool.js.map +1 -1
- package/dist/gateway/advanced-tool/discovery.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/discovery.js +12 -1
- package/dist/gateway/advanced-tool/discovery.js.map +1 -1
- package/dist/gateway/advanced-tool/domains.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/domains.js +5 -0
- package/dist/gateway/advanced-tool/domains.js.map +1 -1
- package/dist/gateway/advanced-tool/execute.d.ts +7 -1
- package/dist/gateway/advanced-tool/execute.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/execute.js +58 -4
- package/dist/gateway/advanced-tool/execute.js.map +1 -1
- package/dist/gateway/essentials.d.ts +4 -4
- package/dist/gateway/essentials.d.ts.map +1 -1
- package/dist/gateway/essentials.js +12 -7
- package/dist/gateway/essentials.js.map +1 -1
- package/dist/install-skill.js +1 -1
- package/dist/net/extra-headers.d.ts +1 -1
- package/dist/net/extra-headers.js +1 -1
- package/dist/net/internal-host.js +2 -2
- package/dist/net/proxy-dispatcher.js +1 -1
- package/dist/net/proxy-dispatcher.js.map +1 -1
- package/dist/net/site-basic-auth.d.ts +2 -2
- package/dist/net/site-basic-auth.js +2 -2
- package/dist/proxy/bridge.d.ts +2 -2
- package/dist/proxy/bridge.js +3 -3
- package/dist/proxy/bridge.js.map +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/server.js +3 -3
- package/dist/setup-cli.d.ts +2 -2
- package/dist/setup-cli.js +2 -2
- package/dist/setup-cli.js.map +1 -1
- package/dist/setup-npx-spec.d.ts +1 -1
- package/dist/setup-npx-spec.js +1 -1
- package/dist/setup-wizard-handshake.js +1 -1
- package/dist/setup-wizard-types.d.ts +1 -1
- package/dist/setup-wizard.js +3 -3
- package/dist/setup-wizard.js.map +1 -1
- package/dist/sites/client-pool.d.ts +1 -1
- package/dist/sites/client-pool.js +1 -1
- package/dist/sites/tools/sites-list.d.ts.map +1 -1
- package/dist/sites/tools/sites-list.js +26 -4
- package/dist/sites/tools/sites-list.js.map +1 -1
- package/dist/sites/tools/sites-test.js +1 -1
- package/dist/sites/tools/sites-test.js.map +1 -1
- package/dist/sites/tools/use-site.js +2 -2
- package/dist/sites/tools/use-site.js.map +1 -1
- package/dist/tools/budgeted-table.d.ts +21 -0
- package/dist/tools/budgeted-table.d.ts.map +1 -0
- package/dist/tools/budgeted-table.js +137 -0
- package/dist/tools/budgeted-table.js.map +1 -0
- package/dist/tools/elements/builders.d.ts.map +1 -1
- package/dist/tools/elements/builders.js +102 -40
- package/dist/tools/elements/builders.js.map +1 -1
- package/dist/tools/elements/handlers-write.d.ts +21 -0
- package/dist/tools/elements/handlers-write.d.ts.map +1 -1
- package/dist/tools/elements/handlers-write.js +231 -11
- package/dist/tools/elements/handlers-write.js.map +1 -1
- package/dist/tools/elements/handlers.d.ts +20 -12
- package/dist/tools/elements/handlers.d.ts.map +1 -1
- package/dist/tools/elements/handlers.js +77 -26
- package/dist/tools/elements/handlers.js.map +1 -1
- package/dist/tools/elements/schema-validation.d.ts +147 -7
- package/dist/tools/elements/schema-validation.d.ts.map +1 -1
- package/dist/tools/elements/schema-validation.js +508 -28
- package/dist/tools/elements/schema-validation.js.map +1 -1
- package/dist/tools/format/elements-format.d.ts.map +1 -1
- package/dist/tools/format/elements-format.js +56 -12
- package/dist/tools/format/elements-format.js.map +1 -1
- package/dist/tools/format/health-format.d.ts +16 -0
- package/dist/tools/format/health-format.d.ts.map +1 -1
- package/dist/tools/format/health-format.js +9 -0
- package/dist/tools/format/health-format.js.map +1 -1
- package/dist/tools/format/inspection-format.d.ts +7 -0
- package/dist/tools/format/inspection-format.d.ts.map +1 -1
- package/dist/tools/format/inspection-format.js +18 -0
- package/dist/tools/format/inspection-format.js.map +1 -1
- package/dist/tools/format/pages-format.d.ts +1 -1
- package/dist/tools/format/pages-format.d.ts.map +1 -1
- package/dist/tools/format/pages-format.js +7 -0
- package/dist/tools/format/pages-format.js.map +1 -1
- package/dist/tools/format/sources-format.d.ts +12 -5
- package/dist/tools/format/sources-format.d.ts.map +1 -1
- package/dist/tools/format/sources-format.js +31 -6
- package/dist/tools/format/sources-format.js.map +1 -1
- package/dist/tools/health.d.ts.map +1 -1
- package/dist/tools/health.js +85 -11
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/inspection.d.ts +34 -0
- package/dist/tools/inspection.d.ts.map +1 -1
- package/dist/tools/inspection.js +666 -62
- package/dist/tools/inspection.js.map +1 -1
- package/dist/tools/layout-flatten.d.ts +7 -1
- package/dist/tools/layout-flatten.d.ts.map +1 -1
- package/dist/tools/layout-flatten.js +24 -13
- package/dist/tools/layout-flatten.js.map +1 -1
- package/dist/tools/library.d.ts +29 -2
- package/dist/tools/library.d.ts.map +1 -1
- package/dist/tools/library.js +247 -34
- package/dist/tools/library.js.map +1 -1
- package/dist/tools/local-content/builders.js +14 -14
- package/dist/tools/local-content/builders.js.map +1 -1
- package/dist/tools/local-content/handlers.d.ts +3 -1
- package/dist/tools/local-content/handlers.d.ts.map +1 -1
- package/dist/tools/local-content/handlers.js +42 -9
- package/dist/tools/local-content/handlers.js.map +1 -1
- package/dist/tools/local-content/schemas.d.ts +9 -4
- package/dist/tools/local-content/schemas.d.ts.map +1 -1
- package/dist/tools/local-content/schemas.js +14 -6
- package/dist/tools/local-content/schemas.js.map +1 -1
- package/dist/tools/multi-items/builders.d.ts.map +1 -1
- package/dist/tools/multi-items/builders.js +11 -10
- package/dist/tools/multi-items/builders.js.map +1 -1
- package/dist/tools/navigation/builders.d.ts +18 -0
- package/dist/tools/navigation/builders.d.ts.map +1 -0
- package/dist/tools/navigation/builders.js +47 -0
- package/dist/tools/navigation/builders.js.map +1 -0
- package/dist/tools/navigation/handlers.d.ts +30 -0
- package/dist/tools/navigation/handlers.d.ts.map +1 -0
- package/dist/tools/navigation/handlers.js +41 -0
- package/dist/tools/navigation/handlers.js.map +1 -0
- package/dist/tools/navigation/index.d.ts +15 -0
- package/dist/tools/navigation/index.d.ts.map +1 -0
- package/dist/tools/navigation/index.js +14 -0
- package/dist/tools/navigation/index.js.map +1 -0
- package/dist/tools/navigation/schemas.d.ts +46 -0
- package/dist/tools/navigation/schemas.d.ts.map +1 -0
- package/dist/tools/navigation/schemas.js +41 -0
- package/dist/tools/navigation/schemas.js.map +1 -0
- package/dist/tools/pages/builders.d.ts.map +1 -1
- package/dist/tools/pages/builders.js +213 -81
- package/dist/tools/pages/builders.js.map +1 -1
- package/dist/tools/pages/handlers-audit.d.ts +112 -3
- package/dist/tools/pages/handlers-audit.d.ts.map +1 -1
- package/dist/tools/pages/handlers-audit.js +623 -7
- package/dist/tools/pages/handlers-audit.js.map +1 -1
- package/dist/tools/pages/handlers-read.d.ts +51 -8
- package/dist/tools/pages/handlers-read.d.ts.map +1 -1
- package/dist/tools/pages/handlers-read.js +348 -69
- package/dist/tools/pages/handlers-read.js.map +1 -1
- package/dist/tools/pages/handlers-write.d.ts +7 -3
- package/dist/tools/pages/handlers-write.d.ts.map +1 -1
- package/dist/tools/pages/handlers-write.js +69 -25
- package/dist/tools/pages/handlers-write.js.map +1 -1
- package/dist/tools/pages/header-transparency.d.ts +64 -0
- package/dist/tools/pages/header-transparency.d.ts.map +1 -0
- package/dist/tools/pages/header-transparency.js +119 -0
- package/dist/tools/pages/header-transparency.js.map +1 -0
- package/dist/tools/pages/schemas.d.ts +284 -13
- package/dist/tools/pages/schemas.d.ts.map +1 -1
- package/dist/tools/pages/schemas.js +434 -26
- package/dist/tools/pages/schemas.js.map +1 -1
- package/dist/tools/pages/target.d.ts +162 -0
- package/dist/tools/pages/target.d.ts.map +1 -0
- package/dist/tools/pages/target.js +239 -0
- package/dist/tools/pages/target.js.map +1 -0
- package/dist/tools/response-budget.d.ts +77 -0
- package/dist/tools/response-budget.d.ts.map +1 -0
- package/dist/tools/response-budget.js +134 -0
- package/dist/tools/response-budget.js.map +1 -0
- package/dist/tools/shared-schemas.d.ts +45 -0
- package/dist/tools/shared-schemas.d.ts.map +1 -1
- package/dist/tools/shared-schemas.js +50 -0
- package/dist/tools/shared-schemas.js.map +1 -1
- package/dist/tools/sources/builders.d.ts.map +1 -1
- package/dist/tools/sources/builders.js +55 -39
- package/dist/tools/sources/builders.js.map +1 -1
- package/dist/tools/sources/handlers-bind.d.ts +10 -11
- package/dist/tools/sources/handlers-bind.d.ts.map +1 -1
- package/dist/tools/sources/handlers-bind.js +110 -9
- package/dist/tools/sources/handlers-bind.js.map +1 -1
- package/dist/tools/sources/handlers.d.ts +4 -2
- package/dist/tools/sources/handlers.d.ts.map +1 -1
- package/dist/tools/sources/handlers.js +11 -7
- package/dist/tools/sources/handlers.js.map +1 -1
- package/dist/tools/sparse-fields.d.ts +61 -8
- package/dist/tools/sparse-fields.d.ts.map +1 -1
- package/dist/tools/sparse-fields.js +124 -12
- package/dist/tools/sparse-fields.js.map +1 -1
- package/dist/tools/sublayout/builders.d.ts.map +1 -1
- package/dist/tools/sublayout/builders.js +1 -2
- package/dist/tools/sublayout/builders.js.map +1 -1
- package/dist/tools/tool-builder/results.d.ts +19 -6
- package/dist/tools/tool-builder/results.d.ts.map +1 -1
- package/dist/tools/tool-builder/results.js +133 -6
- package/dist/tools/tool-builder/results.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +2 -2
- package/skills/yt-builder-mcp/SKILL.md +1713 -72
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation — tool barrel (proxy-mode arm).
|
|
3
|
+
*
|
|
4
|
+
* yootheme_builder_navigation
|
|
5
|
+
* → GET /navigation — the site's menus as a parent -> children tree,
|
|
6
|
+
* each item carrying `page_role` + (when derivable for free)
|
|
7
|
+
* `target_page`. Optional `menu` narrows to one menu by name.
|
|
8
|
+
*
|
|
9
|
+
* READ-ONLY; routed via the read-only advanced gateway, NOT first-class.
|
|
10
|
+
*
|
|
11
|
+
* @license MIT
|
|
12
|
+
*/
|
|
13
|
+
export { buildNavigationTools } from './builders.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/navigation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation — zod input/output schema for `yootheme_builder_navigation`.
|
|
3
|
+
*
|
|
4
|
+
* T-C4 (mega-push plan 2026-07-24-02, customer P1.4). The proxy-mode arm of
|
|
5
|
+
* the Navigation Tree feature — the site's menus (WP nav menus / Joomla
|
|
6
|
+
* menus) as a parent -> children TREE, mirroring the WordPress REST
|
|
7
|
+
* controller ({@see \WootsUp\BuilderMcp\LocalContent\NavigationController})
|
|
8
|
+
* 1:1:
|
|
9
|
+
*
|
|
10
|
+
* yootheme_builder_navigation → GET /navigation
|
|
11
|
+
*
|
|
12
|
+
* Each menu item node is a RECURSIVE tree ({id, title, url, parent_id, type,
|
|
13
|
+
* target_page, page_role, children}) — modelled as a free
|
|
14
|
+
* `z.record(z.string(), z.unknown())` (mirrors
|
|
15
|
+
* `LOCAL_CONTENT_READ_OUTPUT_SCHEMA.items`'s heterogeneous rows) rather than
|
|
16
|
+
* a `z.lazy()` self-referential schema: there is no precedent in this
|
|
17
|
+
* codebase's zod4 `z.toJSONSchema()` catalog pipeline for a recursive shape,
|
|
18
|
+
* and a menu's nesting depth is unbounded by design. The concrete per-node
|
|
19
|
+
* shape is documented here + in the shared PHP
|
|
20
|
+
* {@see \WootsUp\BuilderMcp\LocalContent\MenuTreeBuilder} /
|
|
21
|
+
* {@see \WootsUp\BuilderMcp\LocalContent\LocalContentProjection::menuItem()}.
|
|
22
|
+
*
|
|
23
|
+
* @license MIT
|
|
24
|
+
*/
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
/**
|
|
27
|
+
* One MENU's already-nested tree. `items` is a list of recursive tree nodes:
|
|
28
|
+
* `{id: number, title: string, url: string|null, parent_id: number|null,
|
|
29
|
+
* type: string|null, target_page: string|null, page_role: string,
|
|
30
|
+
* children: <same shape>[]}`.
|
|
31
|
+
*/
|
|
32
|
+
export declare const NAVIGATION_MENU_SCHEMA: z.ZodObject<{
|
|
33
|
+
menu_id: z.ZodNullable<z.ZodNumber>;
|
|
34
|
+
menu_name: z.ZodString;
|
|
35
|
+
item_count: z.ZodNumber;
|
|
36
|
+
items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
export declare const NAVIGATION_OUTPUT_SCHEMA: z.ZodObject<{
|
|
39
|
+
menus: z.ZodArray<z.ZodObject<{
|
|
40
|
+
menu_id: z.ZodNullable<z.ZodNumber>;
|
|
41
|
+
menu_name: z.ZodString;
|
|
42
|
+
item_count: z.ZodNumber;
|
|
43
|
+
items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
44
|
+
}, z.core.$strip>>;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/tools/navigation/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;iBAKjC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;iBAEnC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation — zod input/output schema for `yootheme_builder_navigation`.
|
|
3
|
+
*
|
|
4
|
+
* T-C4 (mega-push plan 2026-07-24-02, customer P1.4). The proxy-mode arm of
|
|
5
|
+
* the Navigation Tree feature — the site's menus (WP nav menus / Joomla
|
|
6
|
+
* menus) as a parent -> children TREE, mirroring the WordPress REST
|
|
7
|
+
* controller ({@see \WootsUp\BuilderMcp\LocalContent\NavigationController})
|
|
8
|
+
* 1:1:
|
|
9
|
+
*
|
|
10
|
+
* yootheme_builder_navigation → GET /navigation
|
|
11
|
+
*
|
|
12
|
+
* Each menu item node is a RECURSIVE tree ({id, title, url, parent_id, type,
|
|
13
|
+
* target_page, page_role, children}) — modelled as a free
|
|
14
|
+
* `z.record(z.string(), z.unknown())` (mirrors
|
|
15
|
+
* `LOCAL_CONTENT_READ_OUTPUT_SCHEMA.items`'s heterogeneous rows) rather than
|
|
16
|
+
* a `z.lazy()` self-referential schema: there is no precedent in this
|
|
17
|
+
* codebase's zod4 `z.toJSONSchema()` catalog pipeline for a recursive shape,
|
|
18
|
+
* and a menu's nesting depth is unbounded by design. The concrete per-node
|
|
19
|
+
* shape is documented here + in the shared PHP
|
|
20
|
+
* {@see \WootsUp\BuilderMcp\LocalContent\MenuTreeBuilder} /
|
|
21
|
+
* {@see \WootsUp\BuilderMcp\LocalContent\LocalContentProjection::menuItem()}.
|
|
22
|
+
*
|
|
23
|
+
* @license MIT
|
|
24
|
+
*/
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
/**
|
|
27
|
+
* One MENU's already-nested tree. `items` is a list of recursive tree nodes:
|
|
28
|
+
* `{id: number, title: string, url: string|null, parent_id: number|null,
|
|
29
|
+
* type: string|null, target_page: string|null, page_role: string,
|
|
30
|
+
* children: <same shape>[]}`.
|
|
31
|
+
*/
|
|
32
|
+
export const NAVIGATION_MENU_SCHEMA = z.object({
|
|
33
|
+
menu_id: z.number().nullable(),
|
|
34
|
+
menu_name: z.string(),
|
|
35
|
+
item_count: z.number(),
|
|
36
|
+
items: z.array(z.record(z.string(), z.unknown())),
|
|
37
|
+
});
|
|
38
|
+
export const NAVIGATION_OUTPUT_SCHEMA = z.object({
|
|
39
|
+
menus: z.array(NAVIGATION_MENU_SCHEMA),
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/tools/navigation/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;CACpD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC;CACzC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../../src/tools/pages/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../../src/tools/pages/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAa7D,OAAO,EAOH,KAAK,iBAAiB,EACzB,MAAM,oBAAoB,CAAC;AAwD5B;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,aAAa,CAMhB;AAyCD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,iBAAiB,EAAE,CA8pB9E"}
|
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { z } from 'zod';
|
|
16
16
|
import { withSiteRetry, withWriteSiteRetry } from '../pool-resolve-helper.js';
|
|
17
|
-
import { ETAG as ETAG_STRICT, POST_ID, RESOLVE_URL, SITE_ID_SCHEMA, TEMPLATE_ID, TEMPLATE_ID_OPTIONAL, } from '../shared-schemas.js';
|
|
17
|
+
import { ETAG as ETAG_STRICT, INCLUDE_META_SCHEMA, POST_ID, RESOLVE_URL, SITE_ID_SCHEMA, TEMPLATE_ID, TEMPLATE_ID_OPTIONAL, } from '../shared-schemas.js';
|
|
18
18
|
import { FIELDS, FLAT, MAX_CHARS } from '../sparse-fields.js';
|
|
19
19
|
import { creating, defineTool, destructive, mutating, readOnly, withSiteMeta, } from '../tool-builder.js';
|
|
20
20
|
import { handlePagesAudit } from './handlers-audit.js';
|
|
21
|
-
import {
|
|
21
|
+
import { handleHeaderTransparencySet, HEADER_TRANSPARENCY_SET_INPUT, } from './header-transparency.js';
|
|
22
|
+
import { handleGetEtag, handleHeadingOutline, handlePageGetLayout, handlePageGetSchema, handlePagesList, handlePagesResolve, handleRenderPreview, handleTemplateSummary, } from './handlers-read.js';
|
|
22
23
|
import { handlePageDynamize, handlePagePublish, handlePagesCreate, handlePagesDelete, handlePageSave, handleTemplateSetType, TEMPLATE_SET_TYPE_OUTPUT_SCHEMA, } from './handlers-write.js';
|
|
23
|
-
import { ETAG_OUTPUT_SCHEMA, PAGE_DYNAMIZE_INPUT, PAGES_AUDIT_INPUT, PAGES_AUDIT_OUTPUT_SCHEMA, PAGES_CREATE_INPUT, PAGES_DELETE_INPUT, PAGES_DELETE_OUTPUT_SCHEMA, PAGES_LIST_OUTPUT_SCHEMA, PAGES_RESOLVE_INPUT, PAGES_RESOLVE_OUTPUT_SCHEMA, RENDER_PREVIEW_OUTPUT_SCHEMA, SCHEMA_OUTPUT_SCHEMA, TEMPLATE_SUMMARY_OUTPUT_SCHEMA, } from './schemas.js';
|
|
24
|
+
import { ETAG_OUTPUT_SCHEMA, HEADING_OUTLINE_OUTPUT_SCHEMA, PAGE_DYNAMIZE_INPUT, PAGES_AUDIT_INPUT, PAGES_AUDIT_OUTPUT_SCHEMA, PAGES_CREATE_INPUT, PAGES_DELETE_INPUT, PAGES_DELETE_OUTPUT_SCHEMA, PAGES_LIST_OUTPUT_SCHEMA, PAGES_RESOLVE_INPUT, PAGES_RESOLVE_OUTPUT_SCHEMA, RENDER_PREVIEW_OUTPUT_SCHEMA, SCHEMA_OUTPUT_SCHEMA, TEMPLATE_SUMMARY_OUTPUT_SCHEMA, } from './schemas.js';
|
|
24
25
|
// F-14: page-level save/publish accept OPTIONAL ETag (no precondition lock
|
|
25
26
|
// at template level — element/binding mutations REQUIRE one via the strict
|
|
26
27
|
// ETAG in shared-schemas.ts). Schema and description now agree: optional
|
|
@@ -80,12 +81,12 @@ export function buildPagesTools(pool) {
|
|
|
80
81
|
name: 'yootheme_builder_pages_list',
|
|
81
82
|
description: 'List pages, templates, and layouts in the YOOtheme Pro builder ' +
|
|
82
83
|
'(id, label, type, elements_count, frontend_url, builder_url, ' +
|
|
83
|
-
'serves_context_kind, serves_context_ids per row). ' +
|
|
84
|
+
'serves_context_kind, serves_context_ids, page_role per row). ' +
|
|
84
85
|
'CALL THIS FIRST to discover template IDs before page_get_layout / element_list / ' +
|
|
85
86
|
'page_get_schema. Paginates: up to `limit` rows (default 50) plus `total` and a ' +
|
|
86
87
|
'`next_cursor` (pass it back as `cursor`) when more remain. Filter with ' +
|
|
87
88
|
'`label_contains`. Slim rows with `fields:["id","label"]`; bound output ' +
|
|
88
|
-
'with `max_chars`.
|
|
89
|
+
'with `max_chars`.',
|
|
89
90
|
inputSchema: {
|
|
90
91
|
site_id: SITE_ID_SCHEMA,
|
|
91
92
|
fields: FIELDS,
|
|
@@ -103,8 +104,10 @@ export function buildPagesTools(pool) {
|
|
|
103
104
|
label_contains: z
|
|
104
105
|
.string()
|
|
105
106
|
.optional()
|
|
106
|
-
.describe('Case-insensitive substring filter on the page label / id / type
|
|
107
|
+
.describe('Case-insensitive substring filter on the page label / id / type / frontend_url ' +
|
|
108
|
+
'(also matches a slug or URL fragment, e.g. "blog" or "product-launch").'),
|
|
107
109
|
max_chars: MAX_CHARS,
|
|
110
|
+
include_meta: INCLUDE_META_SCHEMA,
|
|
108
111
|
},
|
|
109
112
|
outputSchema: PAGES_LIST_OUTPUT_SCHEMA,
|
|
110
113
|
annotations: readOnly('List Pages'),
|
|
@@ -112,14 +115,24 @@ export function buildPagesTools(pool) {
|
|
|
112
115
|
}),
|
|
113
116
|
defineTool({
|
|
114
117
|
name: 'yootheme_builder_page_get_layout',
|
|
118
|
+
// B-1 (SEO-routing fix, 2026-07-21): a generic "SEO audit" prompt
|
|
119
|
+
// from a COLD agent (no SKILL.md) otherwise loops this tool
|
|
120
|
+
// page-by-page into its Max-Iterations limit instead of the one-call
|
|
121
|
+
// pages_audit sweep (empirically confirmed on a customer site —
|
|
122
|
+
// followup_pages_audit_routing_generic_seo_request). The negative
|
|
123
|
+
// steer at the tail routes a whole-site audit to pages_audit (an L2
|
|
124
|
+
// read-only tool reached via yootheme_builder_advanced_read). The
|
|
125
|
+
// per-arg details dropped from this prose (bindings-skeleton / force
|
|
126
|
+
// / cursor semantics) already live in each param's own .describe().
|
|
115
127
|
description: 'Get the layout tree for one template — address it by `template_id` ' +
|
|
116
|
-
'(from pages_list), `post_id
|
|
117
|
-
'dynamize/bind
|
|
118
|
-
'
|
|
119
|
-
'
|
|
120
|
-
'
|
|
121
|
-
'
|
|
122
|
-
'
|
|
128
|
+
'(from pages_list), `post_id`, or `url`. `mode:"bindings_only"` for ' +
|
|
129
|
+
'dynamize/bind; `mode:"full"` (default) is nested `{layout, etag}`, ' +
|
|
130
|
+
'`flat:true` a depth-first array. `max_chars` bounds the text; a clipped ' +
|
|
131
|
+
'read returns `next_cursor` to page the rest. For a site-wide ' +
|
|
132
|
+
'SEO/structure/content/links audit (h1, image alt, thin pages, dead ' +
|
|
133
|
+
'links) do NOT loop this tool page-by-page — call ' +
|
|
134
|
+
'yootheme_builder_pages_audit (one sweep via ' +
|
|
135
|
+
'yootheme_builder_advanced_read).',
|
|
123
136
|
inputSchema: {
|
|
124
137
|
site_id: SITE_ID_SCHEMA,
|
|
125
138
|
// G-A (Track-C URL→layout): three interchangeable addressing modes
|
|
@@ -154,7 +167,7 @@ export function buildPagesTools(pool) {
|
|
|
154
167
|
flat: FLAT,
|
|
155
168
|
fields: FIELDS,
|
|
156
169
|
max_chars: MAX_CHARS,
|
|
157
|
-
// B7 (
|
|
170
|
+
// B7 (customer continuation cursor): resume a clipped full/
|
|
158
171
|
// bindings_only text leg from its char offset. Opaque
|
|
159
172
|
// base64url `o:<n>` — the SAME offset-cursor contract
|
|
160
173
|
// pages_list/sources_list use. Omit to read from the start.
|
|
@@ -175,8 +188,7 @@ export function buildPagesTools(pool) {
|
|
|
175
188
|
description: 'Get the flat schema for a template — nodes with their JSON-Pointer ' +
|
|
176
189
|
'paths and element types. Lighter than page_get_layout, enough to locate ' +
|
|
177
190
|
'elements before editing. Address by `template_id` (pages_list), `post_id`, ' +
|
|
178
|
-
'or `url`. `fields[]` slims each node; `max_chars` bounds output.
|
|
179
|
-
'Operates on the default site unless site_id is provided.',
|
|
191
|
+
'or `url`. `fields[]` slims each node; `max_chars` bounds output.',
|
|
180
192
|
inputSchema: {
|
|
181
193
|
site_id: SITE_ID_SCHEMA,
|
|
182
194
|
// G-A (Track-C URL→layout): three interchangeable addressing modes.
|
|
@@ -185,6 +197,7 @@ export function buildPagesTools(pool) {
|
|
|
185
197
|
url: RESOLVE_URL,
|
|
186
198
|
fields: FIELDS,
|
|
187
199
|
max_chars: MAX_CHARS,
|
|
200
|
+
include_meta: INCLUDE_META_SCHEMA,
|
|
188
201
|
},
|
|
189
202
|
outputSchema: SCHEMA_OUTPUT_SCHEMA,
|
|
190
203
|
annotations: readOnly('Get Page Schema'),
|
|
@@ -202,9 +215,8 @@ export function buildPagesTools(pool) {
|
|
|
202
215
|
'Joomla (incl. deep sub-category paths), not only raw ?option= URLs. A singular page ' +
|
|
203
216
|
'→ its per-page layout; a category/tag/CPT/author archive → the governing THEME ' +
|
|
204
217
|
'TEMPLATE, and for a category/term the SPECIFICALLY-ASSIGNED template (honoring ' +
|
|
205
|
-
'include-child-categories), not a generic one. Returns {template_id,
|
|
206
|
-
'frontend_url, context, resolved_via}.
|
|
207
|
-
'Operates on the default site unless site_id is provided.',
|
|
218
|
+
'include-child-categories), not a generic one. Or a `target`. Returns {template_id, ' +
|
|
219
|
+
'post_id, type, frontend_url, context, resolved_via}.',
|
|
208
220
|
inputSchema: { site_id: SITE_ID_SCHEMA, ...PAGES_RESOLVE_INPUT },
|
|
209
221
|
outputSchema: PAGES_RESOLVE_OUTPUT_SCHEMA,
|
|
210
222
|
annotations: readOnly('Resolve URL to Template'),
|
|
@@ -212,13 +224,12 @@ export function buildPagesTools(pool) {
|
|
|
212
224
|
}),
|
|
213
225
|
defineTool({
|
|
214
226
|
name: 'yootheme_builder_get_etag',
|
|
215
|
-
description: 'Get the current ETag (state revision) for the YOOtheme builder. ' +
|
|
216
|
-
'
|
|
217
|
-
'
|
|
218
|
-
'
|
|
219
|
-
'
|
|
220
|
-
'
|
|
221
|
-
'Operates on the default site unless site_id is provided.',
|
|
227
|
+
description: 'Get the current ETag (state revision) for the YOOtheme builder. Returns a ' +
|
|
228
|
+
'sha256+revision string for optimistic locking. This ETag is SITE-WIDE: it covers ' +
|
|
229
|
+
'the ENTIRE builder state, so ANY write to ANY template (by any client) bumps it — ' +
|
|
230
|
+
'a 412 means the site state advanced, not necessarily that YOUR template changed. ' +
|
|
231
|
+
'It is the SAME token the read tools (page_get_layout, element_list) return in ' +
|
|
232
|
+
'their `etag`. Pass it back as `etag` on any write tool; on 412, re-read and retry.',
|
|
222
233
|
inputSchema: { site_id: SITE_ID_SCHEMA },
|
|
223
234
|
outputSchema: ETAG_OUTPUT_SCHEMA,
|
|
224
235
|
annotations: readOnly('Get ETag'),
|
|
@@ -227,17 +238,58 @@ export function buildPagesTools(pool) {
|
|
|
227
238
|
defineTool({
|
|
228
239
|
name: 'yootheme_builder_template_summary',
|
|
229
240
|
description: 'Token-efficient template overview: element counts by type, binding ' +
|
|
230
|
-
'count, max nesting depth, and named landmark sections
|
|
241
|
+
'count, max nesting depth, and named landmark sections, computed ' +
|
|
231
242
|
'server-side in one call. Use this to grasp a large template before ' +
|
|
232
|
-
'pulling element_list or page_get_layout. ' +
|
|
243
|
+
'pulling element_list or page_get_layout. Pass `include_nodes:true` for a ' +
|
|
244
|
+
'`content_nodes` per-node breakdown (status/effective_visible/headings/alts), ' +
|
|
245
|
+
'pageable via `limit`/`cursor`. Pass ' +
|
|
246
|
+
'`template_ids:[...]` for a batch: response carries `summaries` + ' +
|
|
247
|
+
'`not_found`. ' +
|
|
233
248
|
// F206 (P3): concrete first-call example. The Desktop client
|
|
234
249
|
// rejected the first guessed call because no example showed the
|
|
235
250
|
// exact arg shape (the whole yt-builder package used none, while
|
|
236
251
|
// apimapper's schema.ts does). Mirrors apimapper's 'Example:'
|
|
237
252
|
// pattern.
|
|
238
|
-
'Example: yootheme_builder_template_summary({ template_id: "default" }).
|
|
239
|
-
|
|
240
|
-
|
|
253
|
+
'Example: yootheme_builder_template_summary({ template_id: "default" }).',
|
|
254
|
+
inputSchema: {
|
|
255
|
+
site_id: SITE_ID_SCHEMA,
|
|
256
|
+
template_id: TEMPLATE_ID.optional().describe('Template ID (e.g. "default"). Provide this OR `template_ids` (batch) - ' +
|
|
257
|
+
'exactly one, not both. Use yootheme_builder_pages_list to discover.'),
|
|
258
|
+
// T-C5 (mega-push plan 2026-07-24-02, customer P1.5): batch mode -
|
|
259
|
+
// one REST round-trip for N templates instead of N calls.
|
|
260
|
+
template_ids: z
|
|
261
|
+
.array(z.string().min(1))
|
|
262
|
+
.min(1)
|
|
263
|
+
.optional()
|
|
264
|
+
.describe('Batch of template IDs (2+) - one call instead of N. Provide this OR ' +
|
|
265
|
+
'`template_id` (single) - exactly one, not both. Response carries ' +
|
|
266
|
+
'`summaries` (keyed by id) + `not_found`.'),
|
|
267
|
+
// T-E2 (mega-push plan 2026-07-24-02, Thomas-Entscheid C):
|
|
268
|
+
// content_nodes is opt-in - omit for the compact aggregate-only
|
|
269
|
+
// shape, pass true to also get the per-node breakdown.
|
|
270
|
+
include_nodes: z
|
|
271
|
+
.boolean()
|
|
272
|
+
.optional()
|
|
273
|
+
.describe('When true, also return `content_nodes` (per-node status/' +
|
|
274
|
+
'effective_visible/hidden_on_mobile/headings/alts). Default false ' +
|
|
275
|
+
'(the compact aggregate-only shape).'),
|
|
276
|
+
// T-C5: page content_nodes when include_nodes:true (same
|
|
277
|
+
// limit/cursor contract as pages_list/element_list).
|
|
278
|
+
limit: z
|
|
279
|
+
.number()
|
|
280
|
+
.int()
|
|
281
|
+
.min(1)
|
|
282
|
+
.max(200)
|
|
283
|
+
.optional()
|
|
284
|
+
.describe('Page size for `content_nodes` when `include_nodes:true` (1-200). ' +
|
|
285
|
+
'Omit for the full unpaged list. The response carries `next_cursor` ' +
|
|
286
|
+
'when more remain.'),
|
|
287
|
+
cursor: z
|
|
288
|
+
.string()
|
|
289
|
+
.optional()
|
|
290
|
+
.describe('Opaque cursor from a previous response\'s next_cursor - resumes ' +
|
|
291
|
+
'content_nodes pagination (use with include_nodes:true + limit).'),
|
|
292
|
+
},
|
|
241
293
|
outputSchema: TEMPLATE_SUMMARY_OUTPUT_SCHEMA,
|
|
242
294
|
annotations: readOnly('Template Summary'),
|
|
243
295
|
handler: async ({ site_id, ...rest }) => withSiteRetry(pool, site_id, async (client, site) => withSiteMeta(await handleTemplateSummary(client, rest), site)),
|
|
@@ -250,19 +302,19 @@ export function buildPagesTools(pool) {
|
|
|
250
302
|
// automatically (annotation-driven, no allowlist edit).
|
|
251
303
|
defineTool({
|
|
252
304
|
name: 'yootheme_builder_pages_audit',
|
|
253
|
-
description: 'One-call site-wide SEO/structure/content/links audit — severity-sorted ' +
|
|
254
|
-
'
|
|
255
|
-
'pages,
|
|
256
|
-
'
|
|
257
|
-
'
|
|
258
|
-
|
|
259
|
-
'
|
|
305
|
+
description: 'One-call site-wide SEO/structure/content/links/design audit — severity-sorted findings ' +
|
|
306
|
+
'with fix_hints (a props fragment to merge: supply template_id+path from the ' +
|
|
307
|
+
'locator). Covers h1/headings, thin pages, image alt, duplicate layouts, title ' +
|
|
308
|
+
'collisions, non-pretty URLs, dead anchors. Only active (non-disabled) nodes ' +
|
|
309
|
+
'produce findings. A site sweep caps hits/page, drops content_snippet; `target` ' +
|
|
310
|
+
'scopes to ONE page for the full set (cap 100). Filter with `types`/`checks`. ' +
|
|
311
|
+
'Disclaimer: SEO-plugin meta (title/description/OG) NOT covered.',
|
|
260
312
|
inputSchema: { site_id: SITE_ID_SCHEMA, ...PAGES_AUDIT_INPUT },
|
|
261
313
|
outputSchema: PAGES_AUDIT_OUTPUT_SCHEMA,
|
|
262
314
|
annotations: readOnly('Pages Audit'),
|
|
263
315
|
handler: async ({ site_id, ...rest }) => withSiteRetry(pool, site_id, async (client, site) => withSiteMeta(await handlePagesAudit(client, rest), site)),
|
|
264
316
|
}),
|
|
265
|
-
// ─── F5 + N5 (
|
|
317
|
+
// ─── F5 + N5 (customer HANDOFF-4/5) — render_preview ───────────
|
|
266
318
|
// The authenticated post-write render HEALTHCHECK. READ-ONLY: renders
|
|
267
319
|
// the template server-side over the existing Bearer channel and reports
|
|
268
320
|
// {rendered, item_count, empty, error?} + a cache_purge_hint — answering
|
|
@@ -273,21 +325,23 @@ export function buildPagesTools(pool) {
|
|
|
273
325
|
// template_id OR url (exactly one).
|
|
274
326
|
defineTool({
|
|
275
327
|
name: 'yootheme_builder_render_preview',
|
|
276
|
-
description: 'Render-check a saved template
|
|
277
|
-
'
|
|
278
|
-
'
|
|
279
|
-
'
|
|
280
|
-
'
|
|
281
|
-
'
|
|
282
|
-
'
|
|
283
|
-
'without persisting. Operates on the default site unless site_id is provided.',
|
|
328
|
+
description: 'Render-check a saved template — does it actually render, with how many items, or ' +
|
|
329
|
+
'is it blank? Address by `template_id` (from pages_list), `post_id`, or `url` ' +
|
|
330
|
+
'(resolved for you) — exactly one. `item_count` = items yielded by the ' +
|
|
331
|
+
'template\'s dynamic/Multi-Items bindings (rendered repeat-source rows); 0 with ' +
|
|
332
|
+
'empty:true means a binding returned nothing. Returns {rendered, item_count, empty, ' +
|
|
333
|
+
'error?, cache_purge_hint}; with `expect`, also {matched, snippet}. Use AFTER a ' +
|
|
334
|
+
'save/bind to catch a silently-empty page. Read-only.',
|
|
284
335
|
inputSchema: {
|
|
285
336
|
site_id: SITE_ID_SCHEMA,
|
|
286
|
-
//
|
|
287
|
-
//
|
|
337
|
+
// WAVE-1 follow-up (a): render_preview threads the SAME three
|
|
338
|
+
// addressing modes page_get_layout uses (template_id | post_id |
|
|
339
|
+
// url, exactly one) — the handler already resolved post_id via
|
|
340
|
+
// resolveEffectiveTemplateId; this exposes it at the MCP boundary.
|
|
288
341
|
template_id: TEMPLATE_ID_OPTIONAL,
|
|
342
|
+
post_id: POST_ID,
|
|
289
343
|
url: RESOLVE_URL,
|
|
290
|
-
//
|
|
344
|
+
// customer HANDOFF-6 #4: optional substring the rendered HTML must
|
|
291
345
|
// contain. When set, the response adds {matched, snippet} so "did
|
|
292
346
|
// my edit reach the render?" is answerable in one call.
|
|
293
347
|
expect: z
|
|
@@ -295,7 +349,9 @@ export function buildPagesTools(pool) {
|
|
|
295
349
|
.min(1)
|
|
296
350
|
.optional()
|
|
297
351
|
.describe('Optional substring to find in the rendered HTML (e.g. a headline you ' +
|
|
298
|
-
'just bound).
|
|
352
|
+
'just bound). Matched CASE-SENSITIVELY against the RAW, un-decoded ' +
|
|
353
|
+
'response markup — pass raw HTML, not HTML-escaped text (search for ' +
|
|
354
|
+
'"<h1", not "<h1"). When set, the response adds `matched` (bool) + ' +
|
|
299
355
|
'`snippet` (≈200-char window, or null) — confirm an edit reached ' +
|
|
300
356
|
'the render in one call.'),
|
|
301
357
|
},
|
|
@@ -303,16 +359,48 @@ export function buildPagesTools(pool) {
|
|
|
303
359
|
annotations: readOnly('Render Preview'),
|
|
304
360
|
handler: async ({ site_id, ...rest }) => withSiteRetry(pool, site_id, async (client, site) => withSiteMeta(await handleRenderPreview(client, rest), site)),
|
|
305
361
|
}),
|
|
362
|
+
// ─── T-A5 (heading_outline tool, mega-push plan 2026-07-24-02) ────
|
|
363
|
+
// L2 (advanced_read): a real, doc-order H1-H6 outline of ONE
|
|
364
|
+
// template attributed to its source element, plus the alt-status of
|
|
365
|
+
// every image. Deliberately NOT in ESSENTIAL_TOOLS — `readOnly()`
|
|
366
|
+
// routes it into the advanced_read gateway automatically, same as
|
|
367
|
+
// pages_audit/layout_query.
|
|
368
|
+
defineTool({
|
|
369
|
+
name: 'yootheme_builder_heading_outline',
|
|
370
|
+
description: 'A real, doc-order H1-H6 outline of ONE template: each heading with its TEXT ' +
|
|
371
|
+
'and the source element that carries it (`element_type`/`path`), plus the ' +
|
|
372
|
+
'alt-status of every image (including images inside html/text/code raw markup). ' +
|
|
373
|
+
'Read-only STRUCTURE inspection, not findings; use yootheme_builder_pages_audit ' +
|
|
374
|
+
'for severity-sorted SEO findings across the whole site. Returns ' +
|
|
375
|
+
'{outline, images, h1_count, has_level_skip, images_missing_alt}. Address by ' +
|
|
376
|
+
'`template_id` (from pages_list or pages_resolve).',
|
|
377
|
+
inputSchema: {
|
|
378
|
+
site_id: SITE_ID_SCHEMA,
|
|
379
|
+
template_id: TEMPLATE_ID,
|
|
380
|
+
mode: z
|
|
381
|
+
.enum(['builder', 'rendered'])
|
|
382
|
+
.optional()
|
|
383
|
+
.describe('Outline source. "builder" (default) reads the saved layout tree: fast, ' +
|
|
384
|
+
'but blind to module/widget output and anything a plugin injects only ' +
|
|
385
|
+
'at render time. "rendered" renders the page first (via the SAME ' +
|
|
386
|
+
'engine render_preview / pages_audit use) and reads the ACTUAL DOM - ' +
|
|
387
|
+
'element_type is empty ("") in this mode, since there is no builder ' +
|
|
388
|
+
'node to point at; locate a heading by its `path` (a synthetic ' +
|
|
389
|
+
'"rendered:heading:N" marker) or the page\'s frontend_url instead.'),
|
|
390
|
+
},
|
|
391
|
+
outputSchema: HEADING_OUTLINE_OUTPUT_SCHEMA,
|
|
392
|
+
annotations: readOnly('Heading Outline'),
|
|
393
|
+
handler: async ({ site_id, ...rest }) => withSiteRetry(pool, site_id, async (client, site) => withSiteMeta(await handleHeadingOutline(client, rest), site)),
|
|
394
|
+
}),
|
|
306
395
|
defineTool({
|
|
307
396
|
name: 'yootheme_builder_page_save',
|
|
308
397
|
description: 'Re-run save-transforms + flush caches. Optionally REPLACE the template tree by ' +
|
|
309
|
-
'passing the INNER {type:"layout",children:[...]} tree as `layout` —
|
|
310
|
-
'
|
|
311
|
-
'Validated + ETag-locked; on reject
|
|
312
|
-
'
|
|
313
|
-
'`
|
|
314
|
-
'
|
|
315
|
-
'Operates on the default site unless site_id is provided.',
|
|
398
|
+
'passing the INNER {type:"layout",children:[...]} tree as `layout` — page_get_layout\'s ' +
|
|
399
|
+
'`.layout` child, NOT the whole response it returns (rejected 422, would blank the ' +
|
|
400
|
+
'page). Validated + ETag-locked; nothing persists on reject. Does NOT change CMS ' +
|
|
401
|
+
'post status — a draft stays invisible to visitors; set status via pages_create. ' +
|
|
402
|
+
'`dry_run:true` preflights; success carries `previous_layout` for rollback. ETag ' +
|
|
403
|
+
'optional (412 on conflict; else last-write-wins).',
|
|
316
404
|
inputSchema: {
|
|
317
405
|
site_id: SITE_ID_SCHEMA,
|
|
318
406
|
template_id: TEMPLATE_ID,
|
|
@@ -323,11 +411,13 @@ export function buildPagesTools(pool) {
|
|
|
323
411
|
.record(z.string(), z.unknown())
|
|
324
412
|
.optional()
|
|
325
413
|
.describe('Optional whole YT layout-node object — the INNER tree ' +
|
|
326
|
-
'{type:"layout",children:[...]},
|
|
327
|
-
'
|
|
328
|
-
'Replaces the template tree atomically. Validated
|
|
329
|
-
'
|
|
330
|
-
|
|
414
|
+
'{type:"layout",children:[...]}, i.e. page_get_layout\'s `.layout` ' +
|
|
415
|
+
'child, NOT the whole response it returns (passing that is rejected ' +
|
|
416
|
+
'as a double-nest). Replaces the template tree atomically. Validated ' +
|
|
417
|
+
'+ ETag-locked, BUT prop KEYS are NOT schema-validated on a whole-tree ' +
|
|
418
|
+
'save — YT-Pro silently drops unknown keys; use element_update_settings ' +
|
|
419
|
+
'for validated per-element edits. Omit to just re-run save-transforms.'),
|
|
420
|
+
// U3/F3 (customer HANDOFF-4): optional render preflight.
|
|
331
421
|
dry_run: z
|
|
332
422
|
.boolean()
|
|
333
423
|
.optional()
|
|
@@ -357,9 +447,11 @@ export function buildPagesTools(pool) {
|
|
|
357
447
|
defineTool({
|
|
358
448
|
name: 'yootheme_builder_page_publish',
|
|
359
449
|
description: 'Publish a template — persist state, flush YT + WP caches, snapshot the ' +
|
|
360
|
-
'published-state ETag.
|
|
361
|
-
'
|
|
362
|
-
'
|
|
450
|
+
'published-state ETag. YOOtheme templates already publish on save, so this is a ' +
|
|
451
|
+
'cache-flush + state-snapshot op. Neither publish nor save changes the CMS post ' +
|
|
452
|
+
'status — a draft page stays invisible to visitors; set status at creation via ' +
|
|
453
|
+
'pages_create/library_insert. ETag optional — when provided, 412 on conflict; when ' +
|
|
454
|
+
'omitted, last-write-wins.',
|
|
363
455
|
inputSchema: {
|
|
364
456
|
site_id: SITE_ID_SCHEMA,
|
|
365
457
|
template_id: TEMPLATE_ID,
|
|
@@ -386,24 +478,23 @@ export function buildPagesTools(pool) {
|
|
|
386
478
|
locale: localeForSite(site),
|
|
387
479
|
}))),
|
|
388
480
|
}),
|
|
389
|
-
// ─── N3 (
|
|
481
|
+
// ─── N3 (customer HANDOFF-5) — template_set_type ───────────────
|
|
390
482
|
// L2 (advanced): set which archive/single a YOOtheme theme template
|
|
391
483
|
// is assigned to (the `templates.<id>.type` condition pages_list
|
|
392
484
|
// reads). The #1 missing step in a taxonomy/CPT-rename workflow —
|
|
393
485
|
// after categoryFaq→categoryHelp the `taxonomy-category_faq` /
|
|
394
|
-
// `single-
|
|
486
|
+
// `single-example_faq` templates are orphaned and must be re-typed.
|
|
395
487
|
defineTool({
|
|
396
488
|
name: 'yootheme_builder_template_set_type',
|
|
397
489
|
description:
|
|
398
|
-
// N3 (
|
|
490
|
+
// N3 (customer HANDOFF-5) — archive/single TYPE reassignment.
|
|
399
491
|
'Reassign which archive/single a YOOtheme THEME template applies to — ' +
|
|
400
492
|
'set its `type` condition (the value pages_list shows) in ONE ETag-locked ' +
|
|
401
493
|
'write. Use after a taxonomy/CPT rename orphans a template (e.g. re-type ' +
|
|
402
|
-
'"taxonomy-category_faq" → "taxonomy-category_help"
|
|
403
|
-
'
|
|
404
|
-
'
|
|
405
|
-
'templates only:
|
|
406
|
-
'Operates on the default site unless site_id is provided.',
|
|
494
|
+
'"taxonomy-category_faq" → "taxonomy-category_help"). Returns ' +
|
|
495
|
+
'{type, previous_type, new_etag}. Site-wide + immediate — preview with ' +
|
|
496
|
+
'dry_run:true, reversible via previous_type. ' +
|
|
497
|
+
'THEME templates only: page:/article: is refused (422). ETag req.',
|
|
407
498
|
inputSchema: {
|
|
408
499
|
site_id: SITE_ID_SCHEMA,
|
|
409
500
|
template_id: TEMPLATE_ID,
|
|
@@ -412,12 +503,23 @@ export function buildPagesTools(pool) {
|
|
|
412
503
|
.min(1)
|
|
413
504
|
.describe('The new archive/single TYPE assignment (the `type` condition ' +
|
|
414
505
|
'pages_list surfaces), e.g. "taxonomy-category_help", ' +
|
|
415
|
-
'"single-
|
|
506
|
+
'"single-example_help", "archive-post", or the bare "template". ' +
|
|
416
507
|
'Read the current value via pages_list (the `type` column) or ' +
|
|
417
508
|
'GET the template first. `page`/`article` are NOT valid here.'),
|
|
418
509
|
// Required strict ETag (the re-type is a real mutation; the PHP
|
|
419
510
|
// controller enforces If-Match → 428 if omitted, 412 on stale).
|
|
420
511
|
etag: ETAG_STRICT,
|
|
512
|
+
// PAGES_LIBRARY_MEDIA-14: preflight the re-type without persisting.
|
|
513
|
+
dry_run: z
|
|
514
|
+
.boolean()
|
|
515
|
+
.optional()
|
|
516
|
+
.describe('Preflight ONLY. When true, validate the re-type (authz + ETag ' +
|
|
517
|
+
'lock + theme-template-only + type validity + template-exists) ' +
|
|
518
|
+
'and return {previous_type, would_change, dry_run:true} WITHOUT ' +
|
|
519
|
+
'persisting — the template TYPE assignment governs which items ' +
|
|
520
|
+
'render this layout SITE-WIDE and applies immediately once ' +
|
|
521
|
+
'written, so preview first. Nothing is written (etag == new_etag); ' +
|
|
522
|
+
'reversible anytime by re-calling with the returned previous_type.'),
|
|
421
523
|
},
|
|
422
524
|
outputSchema: TEMPLATE_SET_TYPE_OUTPUT_SCHEMA,
|
|
423
525
|
annotations: mutating('Set Template Type'),
|
|
@@ -439,8 +541,7 @@ export function buildPagesTools(pool) {
|
|
|
439
541
|
'menu_item (Joomla SEF route), dry_run (preflight, no persist). Returns page_id ' +
|
|
440
542
|
'(WP) / article_id (Joomla), slug, template_id (page:{id} or article:{id}), etag, ' +
|
|
441
543
|
'warnings. Joomla: a published article has NO SEF route until a menu item points ' +
|
|
442
|
-
'at it — pass menu_item, else frontend_url may 404.
|
|
443
|
-
'Operates on the default site unless site_id is provided.',
|
|
544
|
+
'at it — pass menu_item, else frontend_url may 404.',
|
|
444
545
|
inputSchema: { site_id: SITE_ID_SCHEMA, ...PAGES_CREATE_INPUT },
|
|
445
546
|
// No outputSchema: the response shape is a discriminated union
|
|
446
547
|
// (201 wet vs 200 dry-run). page_get_layout uses the same pattern.
|
|
@@ -465,10 +566,9 @@ export function buildPagesTools(pool) {
|
|
|
465
566
|
'hand-editing JSON. Give a REFERENCE (section_name from ' +
|
|
466
567
|
'template_summary, or element_path) + list_source_name + a leaf_map ' +
|
|
467
568
|
'(original leaf field-name → flat flow field; #parent + tuned props kept). ' +
|
|
468
|
-
'A section with several source blocks
|
|
569
|
+
'A section with several source blocks dynamizes in ONE ' +
|
|
469
570
|
'call via source_map ({match, source_name, leaf_map?}[]). Sub-query panels: ' +
|
|
470
|
-
'key by "<subquery>.<leaf>". Returns page + `summary`.
|
|
471
|
-
'Operates on the default site unless site_id is provided.',
|
|
571
|
+
'key by "<subquery>.<leaf>". Returns page + `summary`. Preview with dry_run:true.',
|
|
472
572
|
inputSchema: { site_id: SITE_ID_SCHEMA, ...PAGE_DYNAMIZE_INPUT },
|
|
473
573
|
// No outputSchema: the response is the create wire-shape (WP
|
|
474
574
|
// page_id / Joomla article_id discriminated union) plus the
|
|
@@ -481,13 +581,45 @@ export function buildPagesTools(pool) {
|
|
|
481
581
|
locale: localeForSite(site),
|
|
482
582
|
}))),
|
|
483
583
|
}),
|
|
584
|
+
// ─── Task 5 (transparent-header plan) — header_transparency_set ───
|
|
585
|
+
// L2 (advanced): inspect + repair the three `header_transparent*`
|
|
586
|
+
// props on the section that actually governs the site header. NOT an
|
|
587
|
+
// L1 essential — it is the remediation for ONE specific
|
|
588
|
+
// misconfiguration, reached from a `header-contrast-*` finding's
|
|
589
|
+
// fix_hint or from an explicit customer request, not a hot path. The
|
|
590
|
+
// tool budget (~40 in `tools/list`) is spent on the workflow spine.
|
|
591
|
+
defineTool({
|
|
592
|
+
name: 'yootheme_builder_header_transparency_set',
|
|
593
|
+
description:
|
|
594
|
+
// ≤600 chars (catalog constraint). Every clause is a behaviour
|
|
595
|
+
// an agent gets WRONG without it — see the behavior-truth pins.
|
|
596
|
+
'Inspect + repair the transparent header (nav over the hero). Always targets ' +
|
|
597
|
+
'the FIRST section — YOOtheme reads these props there only; later ones are ' +
|
|
598
|
+
'silently dead. dry_run defaults TRUE: returns current state, the ' +
|
|
599
|
+
'theme-declared --uk-inverse, risk_class, confidence, recommendation, ' +
|
|
600
|
+
'would_change. mode:"auto" writes the theme-declared colour; over a hero ' +
|
|
601
|
+
'image/video it writes NO colour and says to LOOK. mode:"explicit" refuses a ' +
|
|
602
|
+
'colour contradicting the theme (409) unless acknowledge_contrast_risk. ' +
|
|
603
|
+
'transparent:false is always allowed.',
|
|
604
|
+
inputSchema: HEADER_TRANSPARENCY_SET_INPUT,
|
|
605
|
+
// No outputSchema: the payload is a rich diagnosis object whose
|
|
606
|
+
// `changes` map is keyed by whichever props moved — a strict
|
|
607
|
+
// structuredContent schema would either be permissive to the point
|
|
608
|
+
// of uselessness or reject a legitimate response.
|
|
609
|
+
annotations: mutating('Set Header Transparency'),
|
|
610
|
+
handler: async ({ site_id, ...rest }, extra) => withWriteSiteRetry(pool, site_id, 'yootheme_builder_header_transparency_set', async (client, site) => withRenderContext(withSiteMeta(await handleHeaderTransparencySet(client, rest, extra), site), buildRenderContext({
|
|
611
|
+
siteUrl: site.url,
|
|
612
|
+
parentTemplateId: rest.template_id,
|
|
613
|
+
locale: localeForSite(site),
|
|
614
|
+
}))),
|
|
615
|
+
}),
|
|
484
616
|
defineTool({
|
|
485
617
|
name: 'yootheme_builder_pages_delete',
|
|
486
618
|
description: 'Delete a page (WordPress) or article (Joomla 5/6) with its YOOtheme per-page ' +
|
|
487
619
|
'layout. Requires confirm:true (gate against accidental deletion). Default: trash ' +
|
|
488
620
|
'(recoverable). force:true: permanent delete. Refuses non-page/article types with ' +
|
|
489
621
|
'403 (Layer 9 defense). Returns deleted:true, page_id (WP) / article_id (Joomla), ' +
|
|
490
|
-
'force_deleted, bumped etag.
|
|
622
|
+
'force_deleted, bumped etag.',
|
|
491
623
|
inputSchema: { site_id: SITE_ID_SCHEMA, ...PAGES_DELETE_INPUT },
|
|
492
624
|
outputSchema: PAGES_DELETE_OUTPUT_SCHEMA,
|
|
493
625
|
// A page/article delete (force:true = PERMANENT, non-idempotent) is
|