@wootsup/yt-builder-mcp 1.11.0 → 2.0.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 +131 -33
- package/bin/node-floor.d.ts +28 -0
- package/bin/node-floor.js +123 -0
- package/bin/yt-builder-mcp.js +52 -11
- package/dist/auth.d.ts +3 -121
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +40 -170
- package/dist/auth.js.map +1 -1
- package/dist/catalog/build-catalog.d.ts +4 -49
- package/dist/catalog/build-catalog.d.ts.map +1 -1
- package/dist/catalog/build-catalog.js +15 -126
- package/dist/catalog/build-catalog.js.map +1 -1
- package/dist/catalog/json-schema.d.ts +3 -0
- package/dist/catalog/json-schema.d.ts.map +1 -0
- package/dist/catalog/json-schema.js +68 -0
- package/dist/catalog/json-schema.js.map +1 -0
- package/dist/catalog/output-shapes.d.ts +6 -0
- package/dist/catalog/output-shapes.d.ts.map +1 -0
- package/dist/catalog/output-shapes.js +89 -0
- package/dist/catalog/output-shapes.js.map +1 -0
- package/dist/catalog/tool-catalog-markdown.d.ts +1 -37
- package/dist/catalog/tool-catalog-markdown.d.ts.map +1 -1
- package/dist/catalog/tool-catalog-markdown.js +9 -41
- package/dist/catalog/tool-catalog-markdown.js.map +1 -1
- package/dist/cli/doctor-command.d.ts +2 -7
- package/dist/cli/doctor-command.d.ts.map +1 -1
- package/dist/cli/doctor-command.js +33 -54
- package/dist/cli/doctor-command.js.map +1 -1
- package/dist/cli/invocation-decision.d.ts +4 -52
- package/dist/cli/invocation-decision.d.ts.map +1 -1
- package/dist/cli/invocation-decision.js +45 -54
- package/dist/cli/invocation-decision.js.map +1 -1
- package/dist/client.d.ts +3 -107
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +34 -115
- package/dist/client.js.map +1 -1
- package/dist/clients/claude-code.d.ts +0 -15
- package/dist/clients/claude-code.d.ts.map +1 -1
- package/dist/clients/claude-code.js +0 -22
- package/dist/clients/claude-code.js.map +1 -1
- package/dist/clients/claude-desktop.d.ts +0 -16
- package/dist/clients/claude-desktop.d.ts.map +1 -1
- package/dist/clients/claude-desktop.js +0 -18
- package/dist/clients/claude-desktop.js.map +1 -1
- package/dist/clients/cline.d.ts +0 -23
- package/dist/clients/cline.d.ts.map +1 -1
- package/dist/clients/cline.js +0 -33
- package/dist/clients/cline.js.map +1 -1
- package/dist/clients/codex-cli.d.ts +0 -39
- package/dist/clients/codex-cli.d.ts.map +1 -1
- package/dist/clients/codex-cli.js +0 -137
- package/dist/clients/codex-cli.js.map +1 -1
- package/dist/clients/continue.d.ts +0 -10
- package/dist/clients/continue.d.ts.map +1 -1
- package/dist/clients/continue.js +0 -26
- package/dist/clients/continue.js.map +1 -1
- package/dist/clients/cursor.d.ts +0 -9
- package/dist/clients/cursor.d.ts.map +1 -1
- package/dist/clients/cursor.js +0 -11
- package/dist/clients/cursor.js.map +1 -1
- package/dist/clients/gemini-cli.d.ts +0 -15
- package/dist/clients/gemini-cli.d.ts.map +1 -1
- package/dist/clients/gemini-cli.js +0 -17
- package/dist/clients/gemini-cli.js.map +1 -1
- package/dist/clients/home.d.ts +0 -12
- package/dist/clients/home.d.ts.map +1 -1
- package/dist/clients/home.js +0 -12
- package/dist/clients/home.js.map +1 -1
- package/dist/clients/index.d.ts +0 -150
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +0 -112
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/roo-code.d.ts +0 -20
- package/dist/clients/roo-code.d.ts.map +1 -1
- package/dist/clients/roo-code.js +0 -22
- package/dist/clients/roo-code.js.map +1 -1
- package/dist/clients/zed.d.ts +0 -9
- package/dist/clients/zed.d.ts.map +1 -1
- package/dist/clients/zed.js +0 -18
- package/dist/clients/zed.js.map +1 -1
- package/dist/compat-floor.d.ts +35 -0
- package/dist/compat-floor.d.ts.map +1 -0
- package/dist/compat-floor.js +84 -0
- package/dist/compat-floor.js.map +1 -0
- package/dist/compat-probe.d.ts +6 -0
- package/dist/compat-probe.d.ts.map +1 -0
- package/dist/compat-probe.js +20 -0
- package/dist/compat-probe.js.map +1 -0
- package/dist/diagnostics/ca-reexec.d.ts +0 -30
- package/dist/diagnostics/ca-reexec.d.ts.map +1 -1
- package/dist/diagnostics/ca-reexec.js +0 -62
- package/dist/diagnostics/ca-reexec.js.map +1 -1
- package/dist/diagnostics/ca-trust.d.ts +0 -22
- package/dist/diagnostics/ca-trust.d.ts.map +1 -1
- package/dist/diagnostics/ca-trust.js +3 -42
- package/dist/diagnostics/ca-trust.js.map +1 -1
- package/dist/diagnostics/diagnose-network-error.d.ts +1 -38
- package/dist/diagnostics/diagnose-network-error.d.ts.map +1 -1
- package/dist/diagnostics/diagnose-network-error.js +26 -37
- package/dist/diagnostics/diagnose-network-error.js.map +1 -1
- package/dist/diagnostics/doctor.d.ts +13 -65
- package/dist/diagnostics/doctor.d.ts.map +1 -1
- package/dist/diagnostics/doctor.js +46 -70
- package/dist/diagnostics/doctor.js.map +1 -1
- package/dist/diagnostics/startup-self-probe.d.ts +3 -25
- package/dist/diagnostics/startup-self-probe.d.ts.map +1 -1
- package/dist/diagnostics/startup-self-probe.js +11 -48
- package/dist/diagnostics/startup-self-probe.js.map +1 -1
- package/dist/errors/hints.d.ts +0 -44
- package/dist/errors/hints.d.ts.map +1 -1
- package/dist/errors/hints.js +0 -32
- package/dist/errors/hints.js.map +1 -1
- package/dist/errors/mask.d.ts +0 -31
- package/dist/errors/mask.d.ts.map +1 -1
- package/dist/errors/mask.js +0 -32
- package/dist/errors/mask.js.map +1 -1
- package/dist/errors/redact-credentials.d.ts +2 -0
- package/dist/errors/redact-credentials.d.ts.map +1 -0
- package/dist/errors/redact-credentials.js +13 -0
- package/dist/errors/redact-credentials.js.map +1 -0
- package/dist/errors/sanitize.d.ts +0 -29
- package/dist/errors/sanitize.d.ts.map +1 -1
- package/dist/errors/sanitize.js +0 -40
- package/dist/errors/sanitize.js.map +1 -1
- package/dist/errors.d.ts +6 -17
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +16 -21
- package/dist/errors.js.map +1 -1
- package/dist/gateway/advanced-read-tool.d.ts +0 -32
- package/dist/gateway/advanced-read-tool.d.ts.map +1 -1
- package/dist/gateway/advanced-read-tool.js +43 -111
- package/dist/gateway/advanced-read-tool.js.map +1 -1
- package/dist/gateway/advanced-tool/discovery.d.ts +1 -12
- package/dist/gateway/advanced-tool/discovery.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/discovery.js +18 -16
- package/dist/gateway/advanced-tool/discovery.js.map +1 -1
- package/dist/gateway/advanced-tool/domains.d.ts +7 -66
- package/dist/gateway/advanced-tool/domains.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/domains.js +36 -80
- package/dist/gateway/advanced-tool/domains.js.map +1 -1
- package/dist/gateway/advanced-tool/execute.d.ts +0 -25
- package/dist/gateway/advanced-tool/execute.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/execute.js +13 -49
- package/dist/gateway/advanced-tool/execute.js.map +1 -1
- package/dist/gateway/advanced-tool/index.d.ts +1 -32
- package/dist/gateway/advanced-tool/index.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/index.js +1 -35
- package/dist/gateway/advanced-tool/index.js.map +1 -1
- package/dist/gateway/advanced-tool/register.d.ts +0 -14
- package/dist/gateway/advanced-tool/register.d.ts.map +1 -1
- package/dist/gateway/advanced-tool/register.js +22 -58
- package/dist/gateway/advanced-tool/register.js.map +1 -1
- package/dist/gateway/advanced-tool.d.ts +0 -11
- package/dist/gateway/advanced-tool.d.ts.map +1 -1
- package/dist/gateway/advanced-tool.js +0 -11
- package/dist/gateway/advanced-tool.js.map +1 -1
- package/dist/gateway/capturing-server.d.ts +3 -88
- package/dist/gateway/capturing-server.d.ts.map +1 -1
- package/dist/gateway/capturing-server.js +0 -77
- package/dist/gateway/capturing-server.js.map +1 -1
- package/dist/gateway/essentials.d.ts +1 -63
- package/dist/gateway/essentials.d.ts.map +1 -1
- package/dist/gateway/essentials.js +10 -174
- package/dist/gateway/essentials.js.map +1 -1
- package/dist/gateway/test-support.d.ts +0 -28
- package/dist/gateway/test-support.d.ts.map +1 -1
- package/dist/gateway/test-support.js +0 -29
- package/dist/gateway/test-support.js.map +1 -1
- package/dist/health-response.d.ts +2 -0
- package/dist/health-response.d.ts.map +1 -0
- package/dist/health-response.js +7 -0
- package/dist/health-response.js.map +1 -0
- package/dist/icon-data.js +0 -3
- package/dist/icon-data.js.map +1 -1
- package/dist/index.d.ts +7 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -130
- package/dist/index.js.map +1 -1
- package/dist/install-skill.d.ts +0 -44
- package/dist/install-skill.d.ts.map +1 -1
- package/dist/install-skill.js +5 -46
- package/dist/install-skill.js.map +1 -1
- package/dist/net/extra-headers.d.ts +0 -58
- package/dist/net/extra-headers.d.ts.map +1 -1
- package/dist/net/extra-headers.js +0 -67
- package/dist/net/extra-headers.js.map +1 -1
- package/dist/net/internal-host.d.ts +0 -31
- package/dist/net/internal-host.d.ts.map +1 -1
- package/dist/net/internal-host.js +7 -65
- package/dist/net/internal-host.js.map +1 -1
- package/dist/net/proxy-dispatcher.d.ts +0 -37
- package/dist/net/proxy-dispatcher.d.ts.map +1 -1
- package/dist/net/proxy-dispatcher.js +0 -40
- package/dist/net/proxy-dispatcher.js.map +1 -1
- package/dist/net/public-fetch.d.ts +53 -0
- package/dist/net/public-fetch.d.ts.map +1 -0
- package/dist/net/public-fetch.js +143 -0
- package/dist/net/public-fetch.js.map +1 -0
- package/dist/net/public-page-report.d.ts +26 -0
- package/dist/net/public-page-report.d.ts.map +1 -0
- package/dist/net/public-page-report.js +145 -0
- package/dist/net/public-page-report.js.map +1 -0
- package/dist/net/redirect-safe-fetch.d.ts +14 -0
- package/dist/net/redirect-safe-fetch.d.ts.map +1 -0
- package/dist/net/redirect-safe-fetch.js +61 -0
- package/dist/net/redirect-safe-fetch.js.map +1 -0
- package/dist/net/session-recovery-fetch.d.ts +7 -0
- package/dist/net/session-recovery-fetch.d.ts.map +1 -0
- package/dist/net/session-recovery-fetch.js +139 -0
- package/dist/net/session-recovery-fetch.js.map +1 -0
- package/dist/net/site-basic-auth.d.ts +1 -59
- package/dist/net/site-basic-auth.d.ts.map +1 -1
- package/dist/net/site-basic-auth.js +5 -94
- package/dist/net/site-basic-auth.js.map +1 -1
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +15 -0
- package/dist/package-version.js.map +1 -0
- package/dist/platform/detect.d.ts +0 -54
- package/dist/platform/detect.d.ts.map +1 -1
- package/dist/platform/detect.js +0 -53
- package/dist/platform/detect.js.map +1 -1
- package/dist/platform/index.d.ts +0 -100
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/index.js +0 -106
- package/dist/platform/index.js.map +1 -1
- package/dist/platform/joomla.d.ts +0 -35
- package/dist/platform/joomla.d.ts.map +1 -1
- package/dist/platform/joomla.js +0 -35
- package/dist/platform/joomla.js.map +1 -1
- package/dist/proxy/bridge.d.ts +36 -76
- package/dist/proxy/bridge.d.ts.map +1 -1
- package/dist/proxy/bridge.js +443 -136
- package/dist/proxy/bridge.js.map +1 -1
- package/dist/proxy/confirm-elicitation.d.ts +22 -0
- package/dist/proxy/confirm-elicitation.d.ts.map +1 -0
- package/dist/proxy/confirm-elicitation.js +170 -0
- package/dist/proxy/confirm-elicitation.js.map +1 -0
- package/dist/proxy/confirm-question-contract.d.ts +6 -0
- package/dist/proxy/confirm-question-contract.d.ts.map +1 -0
- package/dist/proxy/confirm-question-contract.js +9 -0
- package/dist/proxy/confirm-question-contract.js.map +1 -0
- package/dist/proxy/confirm-question.d.ts +2 -0
- package/dist/proxy/confirm-question.d.ts.map +1 -0
- package/dist/proxy/confirm-question.js +125 -0
- package/dist/proxy/confirm-question.js.map +1 -0
- package/dist/proxy/instructions.d.ts +4 -0
- package/dist/proxy/instructions.d.ts.map +1 -0
- package/dist/proxy/instructions.js +12 -0
- package/dist/proxy/instructions.js.map +1 -0
- package/dist/proxy/mode.d.ts +14 -9
- package/dist/proxy/mode.d.ts.map +1 -1
- package/dist/proxy/mode.js +58 -34
- package/dist/proxy/mode.js.map +1 -1
- package/dist/proxy/multi-site.d.ts +42 -0
- package/dist/proxy/multi-site.d.ts.map +1 -0
- package/dist/proxy/multi-site.js +134 -0
- package/dist/proxy/multi-site.js.map +1 -0
- package/dist/proxy/request-headers.d.ts +9 -0
- package/dist/proxy/request-headers.d.ts.map +1 -0
- package/dist/proxy/request-headers.js +17 -0
- package/dist/proxy/request-headers.js.map +1 -0
- package/dist/proxy/shadow-tools.d.ts +9 -0
- package/dist/proxy/shadow-tools.d.ts.map +1 -0
- package/dist/proxy/shadow-tools.js +42 -0
- package/dist/proxy/shadow-tools.js.map +1 -0
- package/dist/proxy/tools-list-cap.d.ts +7 -0
- package/dist/proxy/tools-list-cap.d.ts.map +1 -0
- package/dist/proxy/tools-list-cap.js +14 -0
- package/dist/proxy/tools-list-cap.js.map +1 -0
- package/dist/proxy/transport-uncertainty.d.ts +2 -0
- package/dist/proxy/transport-uncertainty.d.ts.map +1 -0
- package/dist/proxy/transport-uncertainty.js +8 -0
- package/dist/proxy/transport-uncertainty.js.map +1 -0
- package/dist/proxy/upstream-error.d.ts +7 -0
- package/dist/proxy/upstream-error.d.ts.map +1 -0
- package/dist/proxy/upstream-error.js +35 -0
- package/dist/proxy/upstream-error.js.map +1 -0
- package/dist/proxy/wire-dialect.d.ts +5 -0
- package/dist/proxy/wire-dialect.d.ts.map +1 -0
- package/dist/proxy/wire-dialect.js +33 -0
- package/dist/proxy/wire-dialect.js.map +1 -0
- package/dist/server.d.ts +14 -82
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +107 -203
- package/dist/server.js.map +1 -1
- package/dist/setup/banner-color.d.ts +13 -0
- package/dist/setup/banner-color.d.ts.map +1 -0
- package/dist/setup/banner-color.js +93 -0
- package/dist/setup/banner-color.js.map +1 -0
- package/dist/setup/banner.d.ts +22 -0
- package/dist/setup/banner.d.ts.map +1 -0
- package/dist/setup/banner.js +119 -0
- package/dist/setup/banner.js.map +1 -0
- package/dist/setup/ca-recovery.d.ts +20 -0
- package/dist/setup/ca-recovery.d.ts.map +1 -0
- package/dist/setup/ca-recovery.js +92 -0
- package/dist/setup/ca-recovery.js.map +1 -0
- package/dist/setup/closing.d.ts +15 -0
- package/dist/setup/closing.d.ts.map +1 -0
- package/dist/setup/closing.js +43 -0
- package/dist/setup/closing.js.map +1 -0
- package/dist/setup/corporate-ca.d.ts +16 -0
- package/dist/setup/corporate-ca.d.ts.map +1 -0
- package/dist/setup/corporate-ca.js +32 -0
- package/dist/setup/corporate-ca.js.map +1 -0
- package/dist/setup/host-platform.d.ts +8 -0
- package/dist/setup/host-platform.d.ts.map +1 -0
- package/dist/setup/host-platform.js +21 -0
- package/dist/setup/host-platform.js.map +1 -0
- package/dist/setup/install-configs.d.ts +18 -0
- package/dist/setup/install-configs.d.ts.map +1 -0
- package/dist/setup/install-configs.js +70 -0
- package/dist/setup/install-configs.js.map +1 -0
- package/dist/setup/multi-site-loop.d.ts +14 -0
- package/dist/setup/multi-site-loop.d.ts.map +1 -0
- package/dist/setup/multi-site-loop.js +20 -0
- package/dist/setup/multi-site-loop.js.map +1 -0
- package/dist/setup/phases.d.ts +18 -0
- package/dist/setup/phases.d.ts.map +1 -0
- package/dist/setup/phases.js +55 -0
- package/dist/setup/phases.js.map +1 -0
- package/dist/setup/registry-remedy.d.ts +12 -0
- package/dist/setup/registry-remedy.d.ts.map +1 -0
- package/dist/setup/registry-remedy.js +37 -0
- package/dist/setup/registry-remedy.js.map +1 -0
- package/dist/setup/resume.d.ts +28 -0
- package/dist/setup/resume.d.ts.map +1 -0
- package/dist/setup/resume.js +99 -0
- package/dist/setup/resume.js.map +1 -0
- package/dist/setup-ca-env.d.ts +0 -30
- package/dist/setup-ca-env.d.ts.map +1 -1
- package/dist/setup-ca-env.js +0 -28
- package/dist/setup-ca-env.js.map +1 -1
- package/dist/setup-ca-reprobe.d.ts +0 -25
- package/dist/setup-ca-reprobe.d.ts.map +1 -1
- package/dist/setup-ca-reprobe.js +0 -34
- package/dist/setup-ca-reprobe.js.map +1 -1
- package/dist/setup-cli-confirm.d.ts +0 -34
- package/dist/setup-cli-confirm.d.ts.map +1 -1
- package/dist/setup-cli-confirm.js +0 -36
- package/dist/setup-cli-confirm.js.map +1 -1
- package/dist/setup-cli.d.ts +6 -167
- package/dist/setup-cli.d.ts.map +1 -1
- package/dist/setup-cli.js +161 -173
- package/dist/setup-cli.js.map +1 -1
- package/dist/setup-npx-spec.d.ts +0 -36
- package/dist/setup-npx-spec.d.ts.map +1 -1
- package/dist/setup-npx-spec.js +0 -38
- package/dist/setup-npx-spec.js.map +1 -1
- package/dist/setup-prompts.d.ts +5 -70
- package/dist/setup-prompts.d.ts.map +1 -1
- package/dist/setup-prompts.js +67 -107
- package/dist/setup-prompts.js.map +1 -1
- package/dist/setup-token.d.ts +0 -34
- package/dist/setup-token.d.ts.map +1 -1
- package/dist/setup-token.js +0 -40
- package/dist/setup-token.js.map +1 -1
- package/dist/setup-wizard-defaults.d.ts +0 -36
- package/dist/setup-wizard-defaults.d.ts.map +1 -1
- package/dist/setup-wizard-defaults.js +0 -75
- package/dist/setup-wizard-defaults.js.map +1 -1
- package/dist/setup-wizard-handshake.d.ts +1 -19
- package/dist/setup-wizard-handshake.d.ts.map +1 -1
- package/dist/setup-wizard-handshake.js +8 -45
- package/dist/setup-wizard-handshake.js.map +1 -1
- package/dist/setup-wizard-types.d.ts +16 -209
- package/dist/setup-wizard-types.d.ts.map +1 -1
- package/dist/setup-wizard-types.js +0 -9
- package/dist/setup-wizard-types.js.map +1 -1
- package/dist/setup-wizard.d.ts +0 -28
- package/dist/setup-wizard.d.ts.map +1 -1
- package/dist/setup-wizard.js +167 -412
- package/dist/setup-wizard.js.map +1 -1
- package/dist/setup.d.ts +0 -15
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +0 -15
- package/dist/setup.js.map +1 -1
- package/dist/sites/bootstrap.d.ts +0 -38
- package/dist/sites/bootstrap.d.ts.map +1 -1
- package/dist/sites/bootstrap.js +0 -44
- package/dist/sites/bootstrap.js.map +1 -1
- package/dist/sites/cli/add-site.d.ts +0 -76
- package/dist/sites/cli/add-site.d.ts.map +1 -1
- package/dist/sites/cli/add-site.js +0 -71
- package/dist/sites/cli/add-site.js.map +1 -1
- package/dist/sites/cli/list-sites.d.ts +0 -31
- package/dist/sites/cli/list-sites.d.ts.map +1 -1
- package/dist/sites/cli/list-sites.js +0 -45
- package/dist/sites/cli/list-sites.js.map +1 -1
- package/dist/sites/cli/remove-site.d.ts +0 -37
- package/dist/sites/cli/remove-site.d.ts.map +1 -1
- package/dist/sites/cli/remove-site.js +0 -37
- package/dist/sites/cli/remove-site.js.map +1 -1
- package/dist/sites/cli/set-default.d.ts +0 -25
- package/dist/sites/cli/set-default.d.ts.map +1 -1
- package/dist/sites/cli/set-default.js +0 -22
- package/dist/sites/cli/set-default.js.map +1 -1
- package/dist/sites/cli/test-site.d.ts +0 -44
- package/dist/sites/cli/test-site.d.ts.map +1 -1
- package/dist/sites/cli/test-site.js +0 -39
- package/dist/sites/cli/test-site.js.map +1 -1
- package/dist/sites/client-pool.d.ts +11 -164
- package/dist/sites/client-pool.d.ts.map +1 -1
- package/dist/sites/client-pool.js +73 -194
- package/dist/sites/client-pool.js.map +1 -1
- package/dist/sites/config-problem.d.ts +2 -0
- package/dist/sites/config-problem.d.ts.map +1 -0
- package/dist/sites/config-problem.js +13 -0
- package/dist/sites/config-problem.js.map +1 -0
- package/dist/sites/env-bridge.d.ts +0 -69
- package/dist/sites/env-bridge.d.ts.map +1 -1
- package/dist/sites/env-bridge.js +2 -71
- package/dist/sites/env-bridge.js.map +1 -1
- package/dist/sites/op-inject.d.ts +23 -0
- package/dist/sites/op-inject.d.ts.map +1 -0
- package/dist/sites/op-inject.js +131 -0
- package/dist/sites/op-inject.js.map +1 -0
- package/dist/sites/paths.d.ts +0 -19
- package/dist/sites/paths.d.ts.map +1 -1
- package/dist/sites/paths.js +0 -19
- package/dist/sites/paths.js.map +1 -1
- package/dist/sites/probe.d.ts +1 -47
- package/dist/sites/probe.d.ts.map +1 -1
- package/dist/sites/probe.js +4 -46
- package/dist/sites/probe.js.map +1 -1
- package/dist/sites/registry.d.ts +4 -135
- package/dist/sites/registry.d.ts.map +1 -1
- package/dist/sites/registry.js +4 -98
- package/dist/sites/registry.js.map +1 -1
- package/dist/sites/schema.d.ts +3 -51
- package/dist/sites/schema.d.ts.map +1 -1
- package/dist/sites/schema.js +6 -52
- package/dist/sites/schema.js.map +1 -1
- package/dist/sites/secret-resolver.d.ts +6 -76
- package/dist/sites/secret-resolver.d.ts.map +1 -1
- package/dist/sites/secret-resolver.js +39 -104
- package/dist/sites/secret-resolver.js.map +1 -1
- package/dist/sites/store.d.ts +12 -69
- package/dist/sites/store.d.ts.map +1 -1
- package/dist/sites/store.js +37 -86
- package/dist/sites/store.js.map +1 -1
- package/dist/sites/substituted-registry.d.ts +11 -0
- package/dist/sites/substituted-registry.d.ts.map +1 -0
- package/dist/sites/substituted-registry.js +13 -0
- package/dist/sites/substituted-registry.js.map +1 -0
- package/dist/sites/tools/fetch-public-url.d.ts +4 -0
- package/dist/sites/tools/fetch-public-url.d.ts.map +1 -0
- package/dist/sites/tools/fetch-public-url.js +231 -0
- package/dist/sites/tools/fetch-public-url.js.map +1 -0
- package/dist/sites/tools/index.d.ts +2 -26
- package/dist/sites/tools/index.d.ts.map +1 -1
- package/dist/sites/tools/index.js +5 -28
- package/dist/sites/tools/index.js.map +1 -1
- package/dist/sites/tools/sites-list.d.ts +3 -47
- package/dist/sites/tools/sites-list.d.ts.map +1 -1
- package/dist/sites/tools/sites-list.js +68 -80
- package/dist/sites/tools/sites-list.js.map +1 -1
- package/dist/sites/tools/sites-overview.d.ts +4 -0
- package/dist/sites/tools/sites-overview.d.ts.map +1 -0
- package/dist/sites/tools/sites-overview.js +209 -0
- package/dist/sites/tools/sites-overview.js.map +1 -0
- package/dist/sites/tools/sites-test.d.ts +2 -45
- package/dist/sites/tools/sites-test.d.ts.map +1 -1
- package/dist/sites/tools/sites-test.js +1 -56
- package/dist/sites/tools/sites-test.js.map +1 -1
- package/dist/sites/tools/use-site.d.ts +2 -45
- package/dist/sites/tools/use-site.d.ts.map +1 -1
- package/dist/sites/tools/use-site.js +31 -80
- package/dist/sites/tools/use-site.js.map +1 -1
- package/dist/sites/unknown-name-result.d.ts +10 -0
- package/dist/sites/unknown-name-result.d.ts.map +1 -0
- package/dist/sites/unknown-name-result.js +13 -0
- package/dist/sites/unknown-name-result.js.map +1 -0
- package/dist/skill-instructions.d.ts +7 -0
- package/dist/skill-instructions.d.ts.map +1 -0
- package/dist/skill-instructions.js +84 -0
- package/dist/skill-instructions.js.map +1 -0
- package/dist/skill-loader.d.ts +0 -102
- package/dist/skill-loader.d.ts.map +1 -1
- package/dist/skill-loader.js +4 -142
- package/dist/skill-loader.js.map +1 -1
- package/dist/skill-manifest.d.ts +0 -20
- package/dist/skill-manifest.d.ts.map +1 -1
- package/dist/skill-manifest.js +1 -21
- package/dist/skill-manifest.js.map +1 -1
- package/dist/skill-topics.d.ts +19 -0
- package/dist/skill-topics.d.ts.map +1 -0
- package/dist/skill-topics.js +181 -0
- package/dist/skill-topics.js.map +1 -0
- package/dist/tools/active-site.d.ts +16 -0
- package/dist/tools/active-site.d.ts.map +1 -0
- package/dist/tools/active-site.js +55 -0
- package/dist/tools/active-site.js.map +1 -0
- package/dist/tools/bind-guidance.d.ts +2 -72
- package/dist/tools/bind-guidance.d.ts.map +1 -1
- package/dist/tools/bind-guidance.js +2 -72
- package/dist/tools/bind-guidance.js.map +1 -1
- package/dist/tools/budgeted-table.d.ts +16 -0
- package/dist/tools/budgeted-table.d.ts.map +1 -0
- package/dist/tools/budgeted-table.js +203 -0
- package/dist/tools/budgeted-table.js.map +1 -0
- package/dist/tools/elements/bind-output-schema.d.ts +69 -0
- package/dist/tools/elements/bind-output-schema.d.ts.map +1 -0
- package/dist/tools/elements/bind-output-schema.js +64 -0
- package/dist/tools/elements/bind-output-schema.js.map +1 -0
- package/dist/tools/elements/builders.d.ts +1 -22
- package/dist/tools/elements/builders.d.ts.map +1 -1
- package/dist/tools/elements/builders.js +171 -133
- package/dist/tools/elements/builders.js.map +1 -1
- package/dist/tools/elements/index.d.ts +0 -26
- package/dist/tools/elements/index.d.ts.map +1 -1
- package/dist/tools/elements/index.js +0 -25
- package/dist/tools/elements/index.js.map +1 -1
- package/dist/tools/elements/read-output-schemas.d.ts +121 -0
- package/dist/tools/elements/read-output-schemas.d.ts.map +1 -0
- package/dist/tools/elements/read-output-schemas.js +225 -0
- package/dist/tools/elements/read-output-schemas.js.map +1 -0
- package/dist/tools/elements/write-output-schemas.d.ts +185 -0
- package/dist/tools/elements/write-output-schemas.d.ts.map +1 -0
- package/dist/tools/elements/write-output-schemas.js +98 -0
- package/dist/tools/elements/write-output-schemas.js.map +1 -0
- package/dist/tools/elements.d.ts +0 -11
- package/dist/tools/elements.d.ts.map +1 -1
- package/dist/tools/elements.js +0 -11
- package/dist/tools/elements.js.map +1 -1
- package/dist/tools/format/health-format.d.ts +42 -43
- package/dist/tools/format/health-format.d.ts.map +1 -1
- package/dist/tools/format/health-format.js +32 -55
- package/dist/tools/format/health-format.js.map +1 -1
- package/dist/tools/format/inspection-format.d.ts +4 -49
- package/dist/tools/format/inspection-format.d.ts.map +1 -1
- package/dist/tools/format/inspection-format.js +46 -114
- package/dist/tools/format/inspection-format.js.map +1 -1
- package/dist/tools/format/pages-format.d.ts +32 -69
- package/dist/tools/format/pages-format.d.ts.map +1 -1
- package/dist/tools/format/pages-format.js +115 -133
- package/dist/tools/format/pages-format.js.map +1 -1
- package/dist/tools/format/sources-format.d.ts +5 -39
- package/dist/tools/format/sources-format.d.ts.map +1 -1
- package/dist/tools/format/sources-format.js +57 -87
- package/dist/tools/format/sources-format.js.map +1 -1
- package/dist/tools/health-output-schemas.d.ts +82 -0
- package/dist/tools/health-output-schemas.d.ts.map +1 -0
- package/dist/tools/health-output-schemas.js +130 -0
- package/dist/tools/health-output-schemas.js.map +1 -0
- package/dist/tools/health.d.ts +2 -20
- package/dist/tools/health.d.ts.map +1 -1
- package/dist/tools/health.js +59 -184
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/index.d.ts +1 -26
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +13 -33
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/inspection.d.ts +21 -17
- package/dist/tools/inspection.d.ts.map +1 -1
- package/dist/tools/inspection.js +431 -268
- package/dist/tools/inspection.js.map +1 -1
- package/dist/tools/library.d.ts +118 -126
- package/dist/tools/library.d.ts.map +1 -1
- package/dist/tools/library.js +723 -456
- package/dist/tools/library.js.map +1 -1
- package/dist/tools/local-content/builders.d.ts +1 -17
- package/dist/tools/local-content/builders.d.ts.map +1 -1
- package/dist/tools/local-content/builders.js +105 -48
- package/dist/tools/local-content/builders.js.map +1 -1
- package/dist/tools/local-content/index.d.ts +0 -15
- package/dist/tools/local-content/index.d.ts.map +1 -1
- package/dist/tools/local-content/index.js +0 -14
- package/dist/tools/local-content/index.js.map +1 -1
- package/dist/tools/local-content/schemas.d.ts +31 -47
- package/dist/tools/local-content/schemas.d.ts.map +1 -1
- package/dist/tools/local-content/schemas.js +33 -62
- package/dist/tools/local-content/schemas.js.map +1 -1
- package/dist/tools/modules/builders.d.ts +4 -0
- package/dist/tools/modules/builders.d.ts.map +1 -0
- package/dist/tools/modules/builders.js +58 -0
- package/dist/tools/modules/builders.js.map +1 -0
- package/dist/tools/modules/index.d.ts +2 -0
- package/dist/tools/modules/index.d.ts.map +1 -0
- package/dist/tools/modules/index.js +2 -0
- package/dist/tools/modules/index.js.map +1 -0
- package/dist/tools/modules/module-id-schema.d.ts +4 -0
- package/dist/tools/modules/module-id-schema.d.ts.map +1 -0
- package/dist/tools/modules/module-id-schema.js +14 -0
- package/dist/tools/modules/module-id-schema.js.map +1 -0
- package/dist/tools/modules/module-type-fields.d.ts +10 -0
- package/dist/tools/modules/module-type-fields.d.ts.map +1 -0
- package/dist/tools/modules/module-type-fields.js +34 -0
- package/dist/tools/modules/module-type-fields.js.map +1 -0
- package/dist/tools/modules/modules-create.d.ts +59 -0
- package/dist/tools/modules/modules-create.d.ts.map +1 -0
- package/dist/tools/modules/modules-create.js +154 -0
- package/dist/tools/modules/modules-create.js.map +1 -0
- package/dist/tools/modules/modules-delete.d.ts +51 -0
- package/dist/tools/modules/modules-delete.d.ts.map +1 -0
- package/dist/tools/modules/modules-delete.js +180 -0
- package/dist/tools/modules/modules-delete.js.map +1 -0
- package/dist/tools/modules/modules-update.d.ts +43 -0
- package/dist/tools/modules/modules-update.d.ts.map +1 -0
- package/dist/tools/modules/modules-update.js +177 -0
- package/dist/tools/modules/modules-update.js.map +1 -0
- package/dist/tools/modules/placement-hints.d.ts +5 -0
- package/dist/tools/modules/placement-hints.d.ts.map +1 -0
- package/dist/tools/modules/placement-hints.js +90 -0
- package/dist/tools/modules/placement-hints.js.map +1 -0
- package/dist/tools/modules/placement-ways.d.ts +13 -0
- package/dist/tools/modules/placement-ways.d.ts.map +1 -0
- package/dist/tools/modules/placement-ways.js +61 -0
- package/dist/tools/modules/placement-ways.js.map +1 -0
- package/dist/tools/multi-items/builders.d.ts +1 -21
- package/dist/tools/multi-items/builders.d.ts.map +1 -1
- package/dist/tools/multi-items/builders.js +22 -67
- package/dist/tools/multi-items/builders.js.map +1 -1
- package/dist/tools/multi-items/index.d.ts +0 -15
- package/dist/tools/multi-items/index.d.ts.map +1 -1
- package/dist/tools/multi-items/index.js +0 -15
- package/dist/tools/multi-items/index.js.map +1 -1
- package/dist/tools/multi-items/item-container-map.d.ts +0 -35
- package/dist/tools/multi-items/item-container-map.d.ts.map +1 -1
- package/dist/tools/multi-items/item-container-map.js +0 -35
- package/dist/tools/multi-items/item-container-map.js.map +1 -1
- package/dist/tools/multi-items/output-schemas.d.ts +101 -0
- package/dist/tools/multi-items/output-schemas.d.ts.map +1 -0
- package/dist/tools/multi-items/output-schemas.js +74 -0
- package/dist/tools/multi-items/output-schemas.js.map +1 -0
- package/dist/tools/navigation/builders.d.ts +3 -0
- package/dist/tools/navigation/builders.d.ts.map +1 -0
- package/dist/tools/navigation/builders.js +25 -0
- package/dist/tools/navigation/builders.js.map +1 -0
- package/dist/tools/navigation/index.d.ts +2 -0
- package/dist/tools/navigation/index.d.ts.map +1 -0
- package/dist/tools/navigation/index.js +2 -0
- package/dist/tools/navigation/index.js.map +1 -0
- package/dist/tools/navigation/schemas.d.ts +16 -0
- package/dist/tools/navigation/schemas.d.ts.map +1 -0
- package/dist/tools/navigation/schemas.js +11 -0
- package/dist/tools/navigation/schemas.js.map +1 -0
- package/dist/tools/output-schema-metadata.d.ts +5 -0
- package/dist/tools/output-schema-metadata.d.ts.map +1 -0
- package/dist/tools/output-schema-metadata.js +83 -0
- package/dist/tools/output-schema-metadata.js.map +1 -0
- package/dist/tools/pages/builders.d.ts +1 -41
- package/dist/tools/pages/builders.d.ts.map +1 -1
- package/dist/tools/pages/builders.js +373 -359
- package/dist/tools/pages/builders.js.map +1 -1
- package/dist/tools/pages/header-transparency.d.ts +34 -0
- package/dist/tools/pages/header-transparency.d.ts.map +1 -0
- package/dist/tools/pages/header-transparency.js +85 -0
- package/dist/tools/pages/header-transparency.js.map +1 -0
- package/dist/tools/pages/index.d.ts +1 -19
- package/dist/tools/pages/index.d.ts.map +1 -1
- package/dist/tools/pages/index.js +1 -19
- package/dist/tools/pages/index.js.map +1 -1
- package/dist/tools/pages/schemas.d.ts +392 -224
- package/dist/tools/pages/schemas.d.ts.map +1 -1
- package/dist/tools/pages/schemas.js +605 -458
- package/dist/tools/pages/schemas.js.map +1 -1
- package/dist/tools/pages/write-output-schemas.d.ts +139 -0
- package/dist/tools/pages/write-output-schemas.d.ts.map +1 -0
- package/dist/tools/pages/write-output-schemas.js +138 -0
- package/dist/tools/pages/write-output-schemas.js.map +1 -0
- package/dist/tools/pages.d.ts +0 -11
- package/dist/tools/pages.d.ts.map +1 -1
- package/dist/tools/pages.js +0 -11
- package/dist/tools/pages.js.map +1 -1
- package/dist/tools/pool-resolve-helper.d.ts +0 -52
- package/dist/tools/pool-resolve-helper.d.ts.map +1 -1
- package/dist/tools/pool-resolve-helper.js +29 -104
- package/dist/tools/pool-resolve-helper.js.map +1 -1
- package/dist/tools/progress-phases.d.ts +0 -42
- package/dist/tools/progress-phases.d.ts.map +1 -1
- package/dist/tools/progress-phases.js +0 -44
- package/dist/tools/progress-phases.js.map +1 -1
- package/dist/tools/response-budget.d.ts +8 -0
- package/dist/tools/response-budget.d.ts.map +1 -0
- package/dist/tools/response-budget.js +7 -0
- package/dist/tools/response-budget.js.map +1 -0
- package/dist/tools/shared-schemas.d.ts +12 -43
- package/dist/tools/shared-schemas.d.ts.map +1 -1
- package/dist/tools/shared-schemas.js +42 -97
- package/dist/tools/shared-schemas.js.map +1 -1
- package/dist/tools/skill/builders.d.ts +3 -0
- package/dist/tools/skill/builders.d.ts.map +1 -0
- package/dist/tools/skill/builders.js +81 -0
- package/dist/tools/skill/builders.js.map +1 -0
- package/dist/tools/sources/builders.d.ts +1 -11
- package/dist/tools/sources/builders.d.ts.map +1 -1
- package/dist/tools/sources/builders.js +195 -173
- package/dist/tools/sources/builders.js.map +1 -1
- package/dist/tools/sources/index.d.ts +0 -17
- package/dist/tools/sources/index.d.ts.map +1 -1
- package/dist/tools/sources/index.js +0 -16
- package/dist/tools/sources/index.js.map +1 -1
- package/dist/tools/sources/read-output-schemas.d.ts +101 -0
- package/dist/tools/sources/read-output-schemas.d.ts.map +1 -0
- package/dist/tools/sources/read-output-schemas.js +105 -0
- package/dist/tools/sources/read-output-schemas.js.map +1 -0
- package/dist/tools/sources/source-name-argument.d.ts +17 -0
- package/dist/tools/sources/source-name-argument.d.ts.map +1 -0
- package/dist/tools/sources/source-name-argument.js +64 -0
- package/dist/tools/sources/source-name-argument.js.map +1 -0
- package/dist/tools/sources/write-output-schemas.d.ts +100 -0
- package/dist/tools/sources/write-output-schemas.d.ts.map +1 -0
- package/dist/tools/sources/write-output-schemas.js +61 -0
- package/dist/tools/sources/write-output-schemas.js.map +1 -0
- package/dist/tools/sources.d.ts +0 -12
- package/dist/tools/sources.d.ts.map +1 -1
- package/dist/tools/sources.js +0 -12
- package/dist/tools/sources.js.map +1 -1
- package/dist/tools/sparse-fields.d.ts +19 -194
- package/dist/tools/sparse-fields.d.ts.map +1 -1
- package/dist/tools/sparse-fields.js +212 -196
- package/dist/tools/sparse-fields.js.map +1 -1
- package/dist/tools/strict-input.d.ts +5 -0
- package/dist/tools/strict-input.d.ts.map +1 -0
- package/dist/tools/strict-input.js +55 -0
- package/dist/tools/strict-input.js.map +1 -0
- package/dist/tools/sublayout/builders.d.ts +1 -21
- package/dist/tools/sublayout/builders.d.ts.map +1 -1
- package/dist/tools/sublayout/builders.js +10 -40
- package/dist/tools/sublayout/builders.js.map +1 -1
- package/dist/tools/sublayout/index.d.ts +1 -11
- package/dist/tools/sublayout/index.d.ts.map +1 -1
- package/dist/tools/sublayout/index.js +1 -11
- package/dist/tools/sublayout/index.js.map +1 -1
- package/dist/tools/sublayout/output-schemas.d.ts +57 -0
- package/dist/tools/sublayout/output-schemas.d.ts.map +1 -0
- package/dist/tools/sublayout/output-schemas.js +51 -0
- package/dist/tools/sublayout/output-schemas.js.map +1 -0
- package/dist/tools/tool-builder/annotations.d.ts +1 -49
- package/dist/tools/tool-builder/annotations.d.ts.map +1 -1
- package/dist/tools/tool-builder/annotations.js +9 -49
- package/dist/tools/tool-builder/annotations.js.map +1 -1
- package/dist/tools/tool-builder/confirm-preview.d.ts +24 -0
- package/dist/tools/tool-builder/confirm-preview.d.ts.map +1 -0
- package/dist/tools/tool-builder/confirm-preview.js +37 -0
- package/dist/tools/tool-builder/confirm-preview.js.map +1 -0
- package/dist/tools/tool-builder/define.d.ts +6 -26
- package/dist/tools/tool-builder/define.d.ts.map +1 -1
- package/dist/tools/tool-builder/define.js +0 -25
- package/dist/tools/tool-builder/define.js.map +1 -1
- package/dist/tools/tool-builder/index.d.ts +3 -26
- package/dist/tools/tool-builder/index.d.ts.map +1 -1
- package/dist/tools/tool-builder/index.js +2 -25
- package/dist/tools/tool-builder/index.js.map +1 -1
- package/dist/tools/tool-builder/results.d.ts +4 -111
- package/dist/tools/tool-builder/results.d.ts.map +1 -1
- package/dist/tools/tool-builder/results.js +258 -250
- package/dist/tools/tool-builder/results.js.map +1 -1
- package/dist/tools/tool-builder/types.d.ts +5 -59
- package/dist/tools/tool-builder/types.d.ts.map +1 -1
- package/dist/tools/tool-builder/types.js +0 -7
- package/dist/tools/tool-builder/types.js.map +1 -1
- package/dist/tools/tool-builder.d.ts +0 -14
- package/dist/tools/tool-builder.d.ts.map +1 -1
- package/dist/tools/tool-builder.js +0 -14
- package/dist/tools/tool-builder.js.map +1 -1
- package/dist/uninstall-skill.d.ts +0 -41
- package/dist/uninstall-skill.d.ts.map +1 -1
- package/dist/uninstall-skill.js +0 -49
- package/dist/uninstall-skill.js.map +1 -1
- package/dist/uninstall.d.ts +0 -41
- package/dist/uninstall.d.ts.map +1 -1
- package/dist/uninstall.js +1 -29
- package/dist/uninstall.js.map +1 -1
- package/dist/update/update-check.d.ts +0 -26
- package/dist/update/update-check.d.ts.map +1 -1
- package/dist/update/update-check.js +0 -25
- package/dist/update/update-check.js.map +1 -1
- package/manifest.json +4 -5
- package/package.json +5 -5
- package/skills/yt-builder-mcp/SKILL.md +2958 -382
- package/dist/tools/elements/handlers-write.d.ts +0 -70
- package/dist/tools/elements/handlers-write.d.ts.map +0 -1
- package/dist/tools/elements/handlers-write.js +0 -700
- package/dist/tools/elements/handlers-write.js.map +0 -1
- package/dist/tools/elements/handlers.d.ts +0 -125
- package/dist/tools/elements/handlers.d.ts.map +0 -1
- package/dist/tools/elements/handlers.js +0 -571
- package/dist/tools/elements/handlers.js.map +0 -1
- package/dist/tools/elements/layout-hierarchy-rules.d.ts +0 -62
- package/dist/tools/elements/layout-hierarchy-rules.d.ts.map +0 -1
- package/dist/tools/elements/layout-hierarchy-rules.js +0 -154
- package/dist/tools/elements/layout-hierarchy-rules.js.map +0 -1
- package/dist/tools/elements/schema-validation.d.ts +0 -96
- package/dist/tools/elements/schema-validation.d.ts.map +0 -1
- package/dist/tools/elements/schema-validation.js +0 -249
- package/dist/tools/elements/schema-validation.js.map +0 -1
- package/dist/tools/elicitation.d.ts +0 -87
- package/dist/tools/elicitation.d.ts.map +0 -1
- package/dist/tools/elicitation.js +0 -100
- package/dist/tools/elicitation.js.map +0 -1
- package/dist/tools/format/elements-format.d.ts +0 -75
- package/dist/tools/format/elements-format.d.ts.map +0 -1
- package/dist/tools/format/elements-format.js +0 -324
- package/dist/tools/format/elements-format.js.map +0 -1
- package/dist/tools/format/source-schema-format.d.ts +0 -74
- package/dist/tools/format/source-schema-format.d.ts.map +0 -1
- package/dist/tools/format/source-schema-format.js +0 -208
- package/dist/tools/format/source-schema-format.js.map +0 -1
- package/dist/tools/layout-flatten.d.ts +0 -84
- package/dist/tools/layout-flatten.d.ts.map +0 -1
- package/dist/tools/layout-flatten.js +0 -129
- package/dist/tools/layout-flatten.js.map +0 -1
- package/dist/tools/local-content/handlers.d.ts +0 -54
- package/dist/tools/local-content/handlers.d.ts.map +0 -1
- package/dist/tools/local-content/handlers.js +0 -316
- package/dist/tools/local-content/handlers.js.map +0 -1
- package/dist/tools/multi-items/clean-implode-handler.d.ts +0 -37
- package/dist/tools/multi-items/clean-implode-handler.d.ts.map +0 -1
- package/dist/tools/multi-items/clean-implode-handler.js +0 -65
- package/dist/tools/multi-items/clean-implode-handler.js.map +0 -1
- package/dist/tools/multi-items/format/inspection-format.d.ts +0 -41
- package/dist/tools/multi-items/format/inspection-format.d.ts.map +0 -1
- package/dist/tools/multi-items/format/inspection-format.js +0 -64
- package/dist/tools/multi-items/format/inspection-format.js.map +0 -1
- package/dist/tools/multi-items/inspect-handler.d.ts +0 -97
- package/dist/tools/multi-items/inspect-handler.d.ts.map +0 -1
- package/dist/tools/multi-items/inspect-handler.js +0 -323
- package/dist/tools/multi-items/inspect-handler.js.map +0 -1
- package/dist/tools/multi-items/inspection-cache.d.ts +0 -85
- package/dist/tools/multi-items/inspection-cache.d.ts.map +0 -1
- package/dist/tools/multi-items/inspection-cache.js +0 -126
- package/dist/tools/multi-items/inspection-cache.js.map +0 -1
- package/dist/tools/pages/handlers-audit.d.ts +0 -129
- package/dist/tools/pages/handlers-audit.d.ts.map +0 -1
- package/dist/tools/pages/handlers-audit.js +0 -704
- package/dist/tools/pages/handlers-audit.js.map +0 -1
- package/dist/tools/pages/handlers-read.d.ts +0 -95
- package/dist/tools/pages/handlers-read.d.ts.map +0 -1
- package/dist/tools/pages/handlers-read.js +0 -929
- package/dist/tools/pages/handlers-read.js.map +0 -1
- package/dist/tools/pages/handlers-write.d.ts +0 -212
- package/dist/tools/pages/handlers-write.d.ts.map +0 -1
- package/dist/tools/pages/handlers-write.js +0 -418
- package/dist/tools/pages/handlers-write.js.map +0 -1
- package/dist/tools/pages/target.d.ts +0 -162
- package/dist/tools/pages/target.d.ts.map +0 -1
- package/dist/tools/pages/target.js +0 -239
- package/dist/tools/pages/target.js.map +0 -1
- package/dist/tools/sources/handlers-bind.d.ts +0 -148
- package/dist/tools/sources/handlers-bind.d.ts.map +0 -1
- package/dist/tools/sources/handlers-bind.js +0 -655
- package/dist/tools/sources/handlers-bind.js.map +0 -1
- package/dist/tools/sources/handlers.d.ts +0 -114
- package/dist/tools/sources/handlers.d.ts.map +0 -1
- package/dist/tools/sources/handlers.js +0 -285
- package/dist/tools/sources/handlers.js.map +0 -1
- package/dist/tools/sublayout/inspect-sublayout-handler.d.ts +0 -95
- package/dist/tools/sublayout/inspect-sublayout-handler.d.ts.map +0 -1
- package/dist/tools/sublayout/inspect-sublayout-handler.js +0 -181
- package/dist/tools/sublayout/inspect-sublayout-handler.js.map +0 -1
|
@@ -1,929 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Page-tool READ handlers + shared output-schemas.
|
|
3
|
-
*
|
|
4
|
-
* Split out of `src/tools/pages.ts` (Round-2 R2-A2-CRIT1) to keep
|
|
5
|
-
* each file ≤ 200 LoC per Architecture §11. Write handlers (page_save,
|
|
6
|
-
* page_publish — 3-phase progress contract) live in `./handlers-write.ts`.
|
|
7
|
-
*
|
|
8
|
-
* @license MIT
|
|
9
|
-
*/
|
|
10
|
-
import { detailResult, tableResult } from '@getimo/mcp-toolkit';
|
|
11
|
-
import { encodeTemplateId } from '../../client.js';
|
|
12
|
-
import { RestError } from '../../errors.js';
|
|
13
|
-
import { flattenLayout } from '../layout-flatten.js';
|
|
14
|
-
import { PAGES_COMPACT_COLUMNS, PAGES_TABLE_COLUMNS, SCHEMA_COMPACT_COLUMNS, SCHEMA_TABLE_COLUMNS, buildEtagDetail, buildOutlineText, buildRenderPreviewDetail, buildSchemaRows, mapPageRow, } from '../format/pages-format.js';
|
|
15
|
-
import { DEFAULT_FIELDS_PAGES_LIST, DEFAULT_FIELDS_SCHEMA, applyMaxChars, clipTextWindow, columnsFromFields, decodeOffsetCursor, encodeOffsetCursor, projectFields, projectedFieldsEcho, projectionFeedback, projectionWarning, } from '../sparse-fields.js';
|
|
16
|
-
import { errorResult, jsonResult, structuredResult, } from '../tool-builder.js';
|
|
17
|
-
import { TARGET_KEYS } from './schemas.js';
|
|
18
|
-
import { appendTargetParams, malformedTargetError, normalizeTarget, serverTooOldError, TARGET_FAILURE_HINT, targetKeysOf, tooManyTargetsError, } from './target.js';
|
|
19
|
-
// ─── pages_list ─────────────────────────────────────────────────────
|
|
20
|
-
/** Default page size for pages_list when `limit` is omitted (B2). */
|
|
21
|
-
const DEFAULT_PAGES_LIMIT = 50;
|
|
22
|
-
/**
|
|
23
|
-
* SOURCES_BINDING-29 / DISCOVERY_AUDIT-18 — the STATIC pages_list field
|
|
24
|
-
* vocabulary. `mapPageRow` always emits the SAME key set on every row, so
|
|
25
|
-
* deriving it once from an empty-row projection gives the authoritative
|
|
26
|
-
* discoverable field list WITHOUT hard-coding a list that could drift from the
|
|
27
|
-
* mapper. Used to (a) validate a caller's `fields[]` against the real schema
|
|
28
|
-
* rather than against whatever rows a (possibly empty) result happened to carry,
|
|
29
|
-
* and (b) emit `available_fields` on every call. Sorted for a stable echo.
|
|
30
|
-
*/
|
|
31
|
-
const PAGES_LIST_KNOWN_FIELDS = Object.keys(mapPageRow({})).sort();
|
|
32
|
-
/** Decode an offset cursor (`base64url("o:<n>")` or raw `o:<n>`) → offset, else 0. */
|
|
33
|
-
function decodePagesCursor(cursor) {
|
|
34
|
-
if (cursor === undefined || cursor === '')
|
|
35
|
-
return 0;
|
|
36
|
-
let raw = cursor;
|
|
37
|
-
if (!/^o:\d+$/.test(cursor)) {
|
|
38
|
-
try {
|
|
39
|
-
raw = Buffer.from(cursor.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf8');
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return 0;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
const m = /^o:(\d+)$/.exec(raw);
|
|
46
|
-
return m ? Number(m[1]) : 0;
|
|
47
|
-
}
|
|
48
|
-
function encodePagesCursor(offset) {
|
|
49
|
-
return Buffer.from(`o:${offset}`, 'utf8').toString('base64url');
|
|
50
|
-
}
|
|
51
|
-
/** Case-insensitive substring match across a page row's label / id / type. */
|
|
52
|
-
function matchesPageFilter(row, needle) {
|
|
53
|
-
const hay = `${String(row.label ?? '')} ${String(row.id ?? '')} ${String(row.type ?? '')}`.toLowerCase();
|
|
54
|
-
return hay.includes(needle);
|
|
55
|
-
}
|
|
56
|
-
export async function handlePagesList(client, { fields, limit, cursor, label_contains, max_chars, }) {
|
|
57
|
-
try {
|
|
58
|
-
// G-B (Glöckle 2026-06-26, P0): forward `limit`/`offset`/`filter` to the
|
|
59
|
-
// REST /pages endpoint so a site with hundreds of templates does not
|
|
60
|
-
// serialize the full set every call (server-side pagination). The
|
|
61
|
-
// server is BACKWARD-COMPATIBLE: with no params it returns the full set
|
|
62
|
-
// (the pre-G-B shape), so the client-side slice below stays a correct
|
|
63
|
-
// fallback for an un-upgraded host that ignores the params. When the
|
|
64
|
-
// server DOES honour them it echoes `total` (the filtered grand total)
|
|
65
|
-
// + `returned`; we trust that `total` over the local slice length so
|
|
66
|
-
// the cursor still spans the whole result.
|
|
67
|
-
const offset = decodePagesCursor(cursor);
|
|
68
|
-
const qs = new URLSearchParams();
|
|
69
|
-
if (typeof limit === 'number')
|
|
70
|
-
qs.set('limit', String(limit));
|
|
71
|
-
if (offset > 0)
|
|
72
|
-
qs.set('offset', String(offset));
|
|
73
|
-
if (label_contains !== undefined && label_contains !== '') {
|
|
74
|
-
qs.set('label_contains', label_contains);
|
|
75
|
-
}
|
|
76
|
-
const query = qs.toString();
|
|
77
|
-
const data = await client.get(`/pages${query !== '' ? `?${query}` : ''}`);
|
|
78
|
-
const rawPages = Array.isArray(data.pages) ? data.pages : [];
|
|
79
|
-
let mapped = rawPages
|
|
80
|
-
.filter((x) => x !== null && typeof x === 'object')
|
|
81
|
-
.map(mapPageRow);
|
|
82
|
-
// B2 (Glöckle 2026-06-25) + G-B server-side fallback: a real site can
|
|
83
|
-
// have hundreds of templates. When the server already paged + filtered
|
|
84
|
-
// (it echoes a `total`), the rows it returned ARE the page — do NOT
|
|
85
|
-
// re-slice them. When the server ignored the params (no `total`, full
|
|
86
|
-
// set returned) we still filter + slice CLIENT-SIDE so behaviour is
|
|
87
|
-
// identical against an un-upgraded host. Filter BEFORE paging so
|
|
88
|
-
// `total` + the cursor reflect the filtered result.
|
|
89
|
-
const serverPaged = typeof data.total === 'number';
|
|
90
|
-
if (!serverPaged && label_contains !== undefined && label_contains !== '') {
|
|
91
|
-
const needle = label_contains.toLowerCase();
|
|
92
|
-
mapped = mapped.filter((row) => matchesPageFilter(row, needle));
|
|
93
|
-
}
|
|
94
|
-
const pageSize = limit ?? DEFAULT_PAGES_LIMIT;
|
|
95
|
-
// Server-paged: rows ARE the slice, total comes from the server.
|
|
96
|
-
// Client-fallback: slice the full set locally.
|
|
97
|
-
const slice = serverPaged ? mapped : mapped.slice(offset, offset + pageSize);
|
|
98
|
-
const total = serverPaged ? data.total : mapped.length;
|
|
99
|
-
const nextOffset = offset + slice.length;
|
|
100
|
-
const nextCursor = nextOffset < total ? encodePagesCursor(nextOffset) : undefined;
|
|
101
|
-
// B1: project the SLICE (text leg + structuredContent) when fields given.
|
|
102
|
-
const items = projectFields(slice, fields, DEFAULT_FIELDS_PAGES_LIST);
|
|
103
|
-
const hasExplicitFields = Array.isArray(fields) && fields.length > 0;
|
|
104
|
-
// SOURCES_BINDING-29: validate `fields[]` against the STATIC schema, not
|
|
105
|
-
// the returned rows — an EMPTY result set no longer makes every field
|
|
106
|
-
// look invalid (the "available: " with no fields bug). unknown = a
|
|
107
|
-
// requested field whose top-level segment is not a known key.
|
|
108
|
-
const unknownFields = hasExplicitFields
|
|
109
|
-
? fields.filter((f) => !PAGES_LIST_KNOWN_FIELDS.includes(f.split('.')[0] ?? f))
|
|
110
|
-
: [];
|
|
111
|
-
// DISCOVERY_AUDIT-18: `available_fields` is the STATIC discoverable
|
|
112
|
-
// vocabulary, emitted on EVERY call (an empty page still tells the agent
|
|
113
|
-
// which fields exist). `projected_fields` reflects the keys ACTUALLY in
|
|
114
|
-
// the emitted rows — the full vocabulary in the default no-`fields` case,
|
|
115
|
-
// the requested subset otherwise (LAYOUT_READ-18: no longer the stale
|
|
116
|
-
// 5-key DEFAULT echo while rows carry 11).
|
|
117
|
-
const availableFields = [...PAGES_LIST_KNOWN_FIELDS];
|
|
118
|
-
const projectedFields = hasExplicitFields
|
|
119
|
-
? [...fields]
|
|
120
|
-
: [...PAGES_LIST_KNOWN_FIELDS];
|
|
121
|
-
// SOURCES_BINDING-29: suppress the loud projection warning on an empty
|
|
122
|
-
// result (projection is moot) and when nothing is actually unknown.
|
|
123
|
-
const emitWarning = total > 0 && unknownFields.length > 0;
|
|
124
|
-
const unknownNote = emitWarning
|
|
125
|
-
? ` (unknown projection fields ignored: ${unknownFields.join(', ')}` +
|
|
126
|
-
` — available: ${availableFields.join(', ')})`
|
|
127
|
-
: '';
|
|
128
|
-
const useProjection = hasExplicitFields;
|
|
129
|
-
const projectedColumns = useProjection ? columnsFromFields([...fields]) : undefined;
|
|
130
|
-
const pagedNote = total > slice.length ? ` of ${String(total)}${nextCursor !== undefined ? ', pass cursor for more' : ''}` : '';
|
|
131
|
-
const toolkitResult = tableResult(useProjection ? items : slice, {
|
|
132
|
-
columns: projectedColumns ?? [...PAGES_TABLE_COLUMNS],
|
|
133
|
-
compactColumns: projectedColumns ?? [...PAGES_COMPACT_COLUMNS],
|
|
134
|
-
header: (count) => `${String(count)}${pagedNote} pages${unknownNote}`,
|
|
135
|
-
footer: 'Use yootheme_builder_page_get_schema <id> to inspect.',
|
|
136
|
-
});
|
|
137
|
-
return structuredResult(applyMaxChars(toolkitResult, max_chars), {
|
|
138
|
-
items,
|
|
139
|
-
total,
|
|
140
|
-
returned: slice.length,
|
|
141
|
-
...(nextCursor !== undefined ? { next_cursor: nextCursor } : {}),
|
|
142
|
-
...(typeof data.etag === 'string' ? { etag: data.etag } : {}),
|
|
143
|
-
projected_fields: projectedFields,
|
|
144
|
-
available_fields: availableFields,
|
|
145
|
-
// Emit unknown_fields whenever the caller passed an explicit
|
|
146
|
-
// projection (empty [] = all valid; keeps the F-004 contract), omit
|
|
147
|
-
// it on the default no-`fields` call.
|
|
148
|
-
...(hasExplicitFields ? { unknown_fields: unknownFields } : {}),
|
|
149
|
-
...(emitWarning ? { projection_warning: unknownNote.trim() } : {}),
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
catch (e) {
|
|
153
|
-
return errorResult({
|
|
154
|
-
error: e,
|
|
155
|
-
context: {},
|
|
156
|
-
hint: 'Run yootheme_builder_diagnose to verify connectivity and auth.',
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* G-A (Track-C URL→layout): GET /pages/resolve?url=... → the per-page
|
|
162
|
-
* `template_id` that renders the URL. Returns the structured result on a
|
|
163
|
-
* 200; throws (RestError 404) when the URL renders via a theme template or
|
|
164
|
-
* carries no YT per-page layout — the caller surfaces the steer-to-pages_list
|
|
165
|
-
* hint. Shared by the `pages_resolve` tool AND the `url`-param fast-path in
|
|
166
|
-
* page_get_layout / page_get_schema (one internal REST call → one MCP call
|
|
167
|
-
* yields the layout).
|
|
168
|
-
*/
|
|
169
|
-
export async function resolveUrlToTemplate(client, url) {
|
|
170
|
-
return client.get(`/pages/resolve?url=${encodeURIComponent(url)}`);
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* A-6: resolve a semantic `target` — `GET /pages/resolve?target[special]=home`.
|
|
174
|
-
* The bracket encoding is the ONE wire form both CMS controllers parse (see
|
|
175
|
-
* `./target.ts`).
|
|
176
|
-
*/
|
|
177
|
-
async function resolveTargetToTemplate(client, target) {
|
|
178
|
-
const qs = new URLSearchParams();
|
|
179
|
-
appendTargetParams(qs, target);
|
|
180
|
-
return client.get(`/pages/resolve?${qs.toString()}`);
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* A-6: is this failure an OLD host rejecting the request because it still
|
|
184
|
-
* hard-requires `url`? WP core answers `rest_missing_callback_param` when the
|
|
185
|
-
* route arg is `required`; the pre-A-5 controller answered its own
|
|
186
|
-
* `missing_url`. Either way the fix is "update the plugin", not "fix your
|
|
187
|
-
* target" — and only ever on a target-only call.
|
|
188
|
-
*/
|
|
189
|
-
function isMissingUrlRejection(e) {
|
|
190
|
-
if (!(e instanceof RestError) || e.status !== 400)
|
|
191
|
-
return false;
|
|
192
|
-
const code = e.code ?? '';
|
|
193
|
-
return code.includes('rest_missing_callback_param') || code.includes('missing_url');
|
|
194
|
-
}
|
|
195
|
-
/** A-6: narrow an off-the-wire `matched_by` to the declared enum, else drop it. */
|
|
196
|
-
function knownMatchedBy(value) {
|
|
197
|
-
return TARGET_KEYS.find((key) => key === value);
|
|
198
|
-
}
|
|
199
|
-
export async function handlePagesResolve(client, { url, target }) {
|
|
200
|
-
// A-6 / F205: the exactly-one-of(url, target) contract is validated HERE
|
|
201
|
-
// with typed results — a zod `.refine` would surface as a raw -32602 and
|
|
202
|
-
// strip every hint below. Mirrors the WP/Joomla controllers' own codes so
|
|
203
|
-
// the contract reads the same whether it fired locally or upstream.
|
|
204
|
-
const resolvedTarget = normalizeTarget(target);
|
|
205
|
-
// BUG-4 (shared rule, PHP `PageQuery::malformedTargetError()`): a target bag
|
|
206
|
-
// that survived nothing is a MALFORMED ADDRESS. Checked BEFORE the
|
|
207
|
-
// exactly-one-of(url, target) pair, exactly as both controllers do — so it
|
|
208
|
-
// is never reported as `missing_url` (which claims no address was passed)
|
|
209
|
-
// and, alongside a `url`, is never silently ignored.
|
|
210
|
-
const malformed = malformedTargetError(target, resolvedTarget, {
|
|
211
|
-
context: { url: url ?? null, target: target ?? null },
|
|
212
|
-
hint: 'Each target member must be a non-empty string or number — e.g. '
|
|
213
|
-
+ 'target:{special:"home"} or target:{template_id:"page:4816"}. Or pass `url` instead.',
|
|
214
|
-
});
|
|
215
|
-
if (malformed !== null)
|
|
216
|
-
return malformed;
|
|
217
|
-
const targetKeys = targetKeysOf(resolvedTarget);
|
|
218
|
-
const hasUrl = typeof url === 'string' && url.trim() !== '';
|
|
219
|
-
const hasTarget = targetKeys.length > 0;
|
|
220
|
-
if (hasUrl && hasTarget) {
|
|
221
|
-
return tooManyTargetsError({
|
|
222
|
-
supplied: ['url', ...targetKeys.map((k) => `target.${k}`)],
|
|
223
|
-
context: { url: url ?? null, target: resolvedTarget },
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
if (targetKeys.length > 1) {
|
|
227
|
-
return tooManyTargetsError({
|
|
228
|
-
supplied: targetKeys,
|
|
229
|
-
context: { target: resolvedTarget },
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
if (!hasUrl && !hasTarget) {
|
|
233
|
-
return errorResult({
|
|
234
|
-
error: new RestError({
|
|
235
|
-
status: 400,
|
|
236
|
-
code: 'yootheme_builder_mcp.pages.missing_url',
|
|
237
|
-
message: 'A page address is required: pass `url` or `target`.',
|
|
238
|
-
body: null,
|
|
239
|
-
}),
|
|
240
|
-
context: { url: null, target: {} },
|
|
241
|
-
hint: 'Pass `url` (a public page/article URL), or `target` with exactly one of ' +
|
|
242
|
-
'template_id / post_id / url / special ("home", "blog", "404", "search", ' +
|
|
243
|
-
'"category", "tag", "author", "archive") / title.',
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
try {
|
|
247
|
-
const data = hasTarget
|
|
248
|
-
? await resolveTargetToTemplate(client, resolvedTarget)
|
|
249
|
-
: await resolveUrlToTemplate(client, (url ?? '').trim());
|
|
250
|
-
const matchedBy = knownMatchedBy(data.matched_by);
|
|
251
|
-
return structuredResult(jsonResult(data), {
|
|
252
|
-
template_id: data.template_id,
|
|
253
|
-
// G-A2: post_id is null for a theme-template resolution.
|
|
254
|
-
post_id: data.post_id ?? null,
|
|
255
|
-
type: data.type,
|
|
256
|
-
// Forwarded ONLY when the host sent one — a synthesised label would
|
|
257
|
-
// claim a page name this build has no way to know.
|
|
258
|
-
...(typeof data.label === 'string' && data.label !== '' ? { label: data.label } : {}),
|
|
259
|
-
frontend_url: data.frontend_url ?? null,
|
|
260
|
-
// G-A2: context/resolved_via are additive. An OLDER plugin (pre-G-A2)
|
|
261
|
-
// only ever resolved per-page layouts and omits both — default to the
|
|
262
|
-
// per-page shape so a strict host still accepts the success.
|
|
263
|
-
context: data.context ?? null,
|
|
264
|
-
resolved_via: data.resolved_via ?? 'per_page',
|
|
265
|
-
// A-6: forwarded ONLY when the host sent a value this build knows.
|
|
266
|
-
// A `url` resolve and every pre-A-5 host omit it; an UNKNOWN token
|
|
267
|
-
// from a newer host is dropped rather than tripping the strict
|
|
268
|
-
// outputSchema and failing an otherwise perfect resolve.
|
|
269
|
-
...(matchedBy !== undefined ? { matched_by: matchedBy } : {}),
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
catch (e) {
|
|
273
|
-
// A-6 version-skew: an old host still hard-requires `url`, so a
|
|
274
|
-
// target-only call 400s before its controller ever sees the target.
|
|
275
|
-
// That is an "update the plugin" condition, not a bad address.
|
|
276
|
-
if (hasTarget && isMissingUrlRejection(e)) {
|
|
277
|
-
return serverTooOldError({
|
|
278
|
-
message: 'This site rejected a `target`-only resolve because it still requires `url`.',
|
|
279
|
-
context: { target: resolvedTarget },
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
return errorResult({
|
|
283
|
-
error: e,
|
|
284
|
-
context: { url: url ?? null, target: resolvedTarget },
|
|
285
|
-
// BUG-3 / MM-5: the target-aware hint now lives in `target.js` so
|
|
286
|
-
// `pages_audit` answers the SAME error family with the SAME steer.
|
|
287
|
-
hint: hasTarget
|
|
288
|
-
? TARGET_FAILURE_HINT
|
|
289
|
-
: 'If this 404s, the URL renders via a theme template (not a ' +
|
|
290
|
-
'per-page layout) — use yootheme_builder_pages_list to find its ' +
|
|
291
|
-
'template_id. Verify the URL is a public, singular page/article.',
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
// ─── page_get_layout ────────────────────────────────────────────────
|
|
296
|
-
/**
|
|
297
|
-
* F195 (P0, 2026-06-12) — per-process layout-read dedup cache.
|
|
298
|
-
*
|
|
299
|
-
* The Desktop-E2E #2 forensic showed two identical 84 KB full-layout dumps in
|
|
300
|
-
* a single session (58 % of the 330 KB output budget). The same agent re-read
|
|
301
|
-
* the SAME template at the SAME state — the second dump was pure waste. This
|
|
302
|
-
* module-internal cache records, keyed by `site|template_id`, the LAST etag
|
|
303
|
-
* served as a FULL read. On a subsequent full read whose server-returned etag
|
|
304
|
-
* matches, the handler short-circuits with a one-line `[unchanged]` notice
|
|
305
|
-
* instead of re-emitting the body. `force:true` bypasses; bindings_only reads
|
|
306
|
-
* are never deduped (they are already cheap and are the recommended path).
|
|
307
|
-
*
|
|
308
|
-
* Cache key includes the site so multi-site sessions never cross-contaminate.
|
|
309
|
-
* It is a plain module Map (process-scoped) — exactly the granularity the
|
|
310
|
-
* forensic targets (duplicate reads within one MCP session).
|
|
311
|
-
*/
|
|
312
|
-
const layoutDedupCache = new Map();
|
|
313
|
-
/** Test-only: clear the dedup cache between cases (mirrors the bus reset idiom). */
|
|
314
|
-
export function __resetLayoutDedupCacheForTests() {
|
|
315
|
-
layoutDedupCache.clear();
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Single SSoT unwrap rule for `page_get_layout(flat:true)`.
|
|
319
|
-
*
|
|
320
|
-
* flattenLayout iterates the TOP-LEVEL ENTRIES of whatever it is given.
|
|
321
|
-
* That is correct for a *container* (an array, or an index-keyed object
|
|
322
|
-
* `{0:{...},1:{...}}`) where every entry is itself an element node. It
|
|
323
|
-
* is WRONG for a single root NODE (`{type:'layout', children:[...]}`),
|
|
324
|
-
* whose top-level entries are `type` / `children` / `version` — not
|
|
325
|
-
* element nodes. Handing a root node straight to flattenLayout emits
|
|
326
|
-
* nothing (the C4 / Wave-9 F7 silent-`elements:[]` bug class).
|
|
327
|
-
*
|
|
328
|
-
* Rule: a value that looks like a single root node (`type === 'layout'`
|
|
329
|
-
* with an array `children`) is unwrapped to its `.children` array; any
|
|
330
|
-
* other value passes through untouched so containers and the legacy
|
|
331
|
-
* index-keyed object shape keep working unchanged.
|
|
332
|
-
*/
|
|
333
|
-
function unwrapToWalkableContainer(value) {
|
|
334
|
-
if (value !== null &&
|
|
335
|
-
typeof value === 'object' &&
|
|
336
|
-
!Array.isArray(value)) {
|
|
337
|
-
const obj = value;
|
|
338
|
-
if (obj.type === 'layout' && Array.isArray(obj.children)) {
|
|
339
|
-
return obj.children;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return value;
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* Decide whether a ZERO-element flatten should surface the C4
|
|
346
|
-
* "layout shape not recognized" warning.
|
|
347
|
-
*
|
|
348
|
-
* The decision runs on the RESOLVED walk container (`layoutRoot`, the value
|
|
349
|
-
* actually handed to `flattenLayout` after `unwrapToWalkableContainer`),
|
|
350
|
-
* NOT the raw `data.layout` envelope. That is the F29 calibration
|
|
351
|
-
* (2026-06-10):
|
|
352
|
-
*
|
|
353
|
-
* - An ARRAY (empty or otherwise) is a recognized container shape. A
|
|
354
|
-
* bare root node `{type:'layout', children:[]}` (a freshly-created
|
|
355
|
-
* empty article / per-page layout, or a fresh empty theme template)
|
|
356
|
-
* unwraps to its empty `.children` array, so it lands here and is
|
|
357
|
-
* treated as a GENUINELY empty page → NO warning. This kills the
|
|
358
|
-
* false-positive the raw-envelope check produced (the bare root node
|
|
359
|
-
* is a non-empty OBJECT — keys `type`/`children` — so the old check
|
|
360
|
-
* mistook "empty container" for "had content").
|
|
361
|
-
* - An OBJECT with ZERO keys (e.g. an empty index-keyed container `{}`)
|
|
362
|
-
* is also genuinely empty → NO warning.
|
|
363
|
-
* - An OBJECT with keys that nonetheless flattened to nothing is an
|
|
364
|
-
* unrecognized / future shape masquerading as empty → WARN (the
|
|
365
|
-
* original C4 contract; the `{some_future_key, another}` fixture).
|
|
366
|
-
*
|
|
367
|
-
* @param layoutRoot The resolved walk container passed to flattenLayout.
|
|
368
|
-
*/
|
|
369
|
-
function isUnrecognizedNonEmptyLayout(layoutRoot) {
|
|
370
|
-
if (Array.isArray(layoutRoot)) {
|
|
371
|
-
// Recognized container shape — empty or not, never "unrecognized".
|
|
372
|
-
return false;
|
|
373
|
-
}
|
|
374
|
-
if (layoutRoot !== null && typeof layoutRoot === 'object') {
|
|
375
|
-
// A non-empty object that produced zero elements is the
|
|
376
|
-
// unrecognized-shape case worth warning about; an empty object is
|
|
377
|
-
// a genuinely empty container.
|
|
378
|
-
return Object.keys(layoutRoot).length > 0;
|
|
379
|
-
}
|
|
380
|
-
return false;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* G-A (Track-C URL→layout): resolve the EFFECTIVE template_id a read tool
|
|
384
|
-
* should operate on from the three accepted addressing modes, so ONE MCP
|
|
385
|
-
* tool call reaches a layout from any of them:
|
|
386
|
-
*
|
|
387
|
-
* - `template_id` (highest precedence) — used verbatim.
|
|
388
|
-
* - `post_id` — `String(post_id)` is a bare numeric id the server's C1
|
|
389
|
-
* dispatch resolves to the per-page layout. No extra REST
|
|
390
|
-
* round-trip.
|
|
391
|
-
* - `url` — resolved via GET /pages/resolve first (one internal REST
|
|
392
|
-
* call), then the returned `template_id` is used.
|
|
393
|
-
*
|
|
394
|
-
* Exactly one of the three is required. When `url` does not resolve (theme-
|
|
395
|
-
* template / non-singular URL), the resolve error (with its steer-to-pages_list
|
|
396
|
-
* hint) is returned for the caller to surface unchanged.
|
|
397
|
-
*/
|
|
398
|
-
async function resolveEffectiveTemplateId(client, args) {
|
|
399
|
-
if (args.template_id !== undefined && args.template_id !== '') {
|
|
400
|
-
return { templateId: args.template_id };
|
|
401
|
-
}
|
|
402
|
-
if (args.post_id !== undefined) {
|
|
403
|
-
return { templateId: String(args.post_id) };
|
|
404
|
-
}
|
|
405
|
-
if (args.url !== undefined && args.url !== '') {
|
|
406
|
-
try {
|
|
407
|
-
const resolved = await resolveUrlToTemplate(client, args.url);
|
|
408
|
-
return { templateId: resolved.template_id };
|
|
409
|
-
}
|
|
410
|
-
catch (e) {
|
|
411
|
-
return {
|
|
412
|
-
error: errorResult({
|
|
413
|
-
error: e,
|
|
414
|
-
context: { url: args.url },
|
|
415
|
-
hint: 'This URL did not resolve to a per-page layout or a governing ' +
|
|
416
|
-
'theme template (home/front-page/search/date are not mapped). ' +
|
|
417
|
-
'Use yootheme_builder_pages_list to find its template_id.',
|
|
418
|
-
}),
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
return {
|
|
423
|
-
error: errorResult({
|
|
424
|
-
error: new Error('one of template_id, post_id, or url is required'),
|
|
425
|
-
context: {},
|
|
426
|
-
hint: 'Pass template_id (from pages_list), OR post_id (a numeric ' +
|
|
427
|
-
'WP post-id / Joomla article-id), OR url (a public page URL).',
|
|
428
|
-
}),
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* G1 (V3): coerce the REST `nodes` field into a typed `OutlineNode[]` for the
|
|
433
|
-
* pure render sidecar. The wire shape is the canonical `PageQuery::outline()`
|
|
434
|
-
* projection (depth/label/type/handle/path/bound); this guard tolerates a
|
|
435
|
-
* malformed or absent field by emitting an empty list rather than throwing,
|
|
436
|
-
* so an unexpected payload degrades to an empty outline (never a 500).
|
|
437
|
-
*/
|
|
438
|
-
function parseOutlineNodes(raw) {
|
|
439
|
-
if (!Array.isArray(raw)) {
|
|
440
|
-
return [];
|
|
441
|
-
}
|
|
442
|
-
const out = [];
|
|
443
|
-
for (const item of raw) {
|
|
444
|
-
if (item === null || typeof item !== 'object') {
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
const n = item;
|
|
448
|
-
const boundRaw = n.bound;
|
|
449
|
-
let bound = null;
|
|
450
|
-
if (boundRaw !== null && typeof boundRaw === 'object') {
|
|
451
|
-
const b = boundRaw;
|
|
452
|
-
bound = {
|
|
453
|
-
query_name: typeof b.query_name === 'string' ? b.query_name : '',
|
|
454
|
-
has_condition: b.has_condition === true,
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
out.push({
|
|
458
|
-
depth: typeof n.depth === 'number' && Number.isFinite(n.depth) ? Math.trunc(n.depth) : 0,
|
|
459
|
-
label: typeof n.label === 'string' ? n.label : '',
|
|
460
|
-
type: typeof n.type === 'string' ? n.type : 'unknown',
|
|
461
|
-
handle: typeof n.handle === 'string' ? n.handle : '',
|
|
462
|
-
path: typeof n.path === 'string' ? n.path : '',
|
|
463
|
-
bound,
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
return out;
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* B7 (Glöckle continuation cursor) — build the full-dump TEXT leg windowed at
|
|
470
|
-
* `[offset, offset+max_chars)` and, when more remains, append a `next_cursor`.
|
|
471
|
-
*
|
|
472
|
-
* The truncated full/bindings_only TEXT leg of page_get_layout had NO
|
|
473
|
-
* continuation: once `max_chars` clipped the JSON dump there was no way to
|
|
474
|
-
* fetch the rest of THAT subtree. This windows the SAME serialized JSON
|
|
475
|
-
* `jsonResult(data)` would emit, slices it from `offset` for up to `max_chars`
|
|
476
|
-
* chars, and emits a `next_cursor` (base64url `o:<n>`, the SAME opaque
|
|
477
|
-
* offset-cursor contract pages_list/sources_list use) when the body is clipped
|
|
478
|
-
* so a follow-up call resumes from the offset. The structured leg carries the
|
|
479
|
-
* cursor + offsets verbatim (page_get_layout declares no outputSchema).
|
|
480
|
-
*
|
|
481
|
-
* `max_chars === undefined` AND `offset === 0` returns the whole body with NO
|
|
482
|
-
* cursor — byte-identical to the pre-B7 `applyMaxChars(jsonResult(data),
|
|
483
|
-
* undefined)` no-op. A final slice (nothing left after it) carries no cursor.
|
|
484
|
-
*/
|
|
485
|
-
function windowedFullDump(data, offset, maxChars) {
|
|
486
|
-
const firstBlock = jsonResult(data).content[0];
|
|
487
|
-
const fullText = firstBlock !== undefined && firstBlock.type === 'text' && typeof firstBlock.text === 'string'
|
|
488
|
-
? firstBlock.text
|
|
489
|
-
: '';
|
|
490
|
-
const fullLength = fullText.length;
|
|
491
|
-
const window = clipTextWindow(fullText, offset, maxChars);
|
|
492
|
-
const nextCursor = window.clipped ? encodeOffsetCursor(window.nextOffset) : undefined;
|
|
493
|
-
// The text leg the LLM reads: the windowed slice. When a cursor is emitted
|
|
494
|
-
// the clip marker already rides inside `window.text`; append the resume
|
|
495
|
-
// hint so an agent reading ONLY the text leg can still page.
|
|
496
|
-
const text = nextCursor !== undefined
|
|
497
|
-
? `${window.text}\n[continued] pass cursor:"${nextCursor}" to page_get_layout to read chars ` +
|
|
498
|
-
`${String(window.nextOffset)}–${String(fullLength)} of this layout.`
|
|
499
|
-
: window.text;
|
|
500
|
-
return structuredResult({ content: [{ type: 'text', text }] }, {
|
|
501
|
-
...data,
|
|
502
|
-
...(nextCursor !== undefined ? { next_cursor: nextCursor } : {}),
|
|
503
|
-
char_offset: window.offset,
|
|
504
|
-
char_total: fullLength,
|
|
505
|
-
returned_chars: window.text.length,
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
export async function handlePageGetLayout(client, { template_id, post_id, url, flat, fields, mode, force, cursor, max_chars }) {
|
|
509
|
-
try {
|
|
510
|
-
// G-A: resolve the effective template_id from template_id | post_id | url.
|
|
511
|
-
const effective = await resolveEffectiveTemplateId(client, { template_id, post_id, url });
|
|
512
|
-
if ('error' in effective) {
|
|
513
|
-
return effective.error;
|
|
514
|
-
}
|
|
515
|
-
const templateId = effective.templateId;
|
|
516
|
-
// B7 (Glöckle continuation cursor): an opaque char-offset cursor
|
|
517
|
-
// (base64url `o:<n>`) resumes a previously-clipped full/bindings_only
|
|
518
|
-
// text leg from the offset. A present cursor makes the read a
|
|
519
|
-
// CONTINUATION — it is NEVER served from the [unchanged] dedup cache
|
|
520
|
-
// (the agent is intentionally paging the rest of the dump). `0` (no
|
|
521
|
-
// cursor / start) keeps the pre-B7 behaviour.
|
|
522
|
-
const charOffset = decodeOffsetCursor(cursor);
|
|
523
|
-
const isContinuation = cursor !== undefined && cursor !== '';
|
|
524
|
-
// F195 (P0): forward `mode=bindings_only` so the server returns the
|
|
525
|
-
// trimmed binding skeleton the dynamize/bind workflow needs. G1 (V3):
|
|
526
|
-
// `mode=outline` forwards `?mode=outline` for the flat semantic-outline
|
|
527
|
-
// node list. `full` (default) appends no query param — byte-identical
|
|
528
|
-
// to the pre-F195 request shape.
|
|
529
|
-
const isBindingsOnly = mode === 'bindings_only';
|
|
530
|
-
const isOutline = mode === 'outline';
|
|
531
|
-
const query = isBindingsOnly ? '?mode=bindings_only' : isOutline ? '?mode=outline' : '';
|
|
532
|
-
const data = await client.get(`/pages/${encodeTemplateId(templateId)}/layout${query}`);
|
|
533
|
-
// G1 (V3): outline is the cheapest projection (and, like bindings_only,
|
|
534
|
-
// the recommended map-first path), so it is NEVER deduped — the
|
|
535
|
-
// per-process unchanged-read cache mis-keys on a non-full shape. The
|
|
536
|
-
// flat `nodes[]` are rendered to indented breadcrumb text via the pure
|
|
537
|
-
// sidecar; the full structured payload rides along for structured hosts.
|
|
538
|
-
if (isOutline) {
|
|
539
|
-
const nodes = parseOutlineNodes(data.nodes);
|
|
540
|
-
return structuredResult({ content: [{ type: 'text', text: buildOutlineText(nodes) }] }, data);
|
|
541
|
-
}
|
|
542
|
-
// F195 (P0): per-process dedup of REPEATED full reads. bindings_only
|
|
543
|
-
// is already cheap (and the recommended path), so it is never deduped.
|
|
544
|
-
// The skeleton passes straight through unchanged — EXCEPT B7: when
|
|
545
|
-
// `max_chars` clips it (or the caller resumes with a `cursor`), it gets
|
|
546
|
-
// the SAME char-offset continuation window the full leg does, so the
|
|
547
|
-
// binding skeleton of a very large template is pageable too.
|
|
548
|
-
if (isBindingsOnly) {
|
|
549
|
-
if (max_chars !== undefined || isContinuation) {
|
|
550
|
-
return windowedFullDump(data, charOffset, max_chars);
|
|
551
|
-
}
|
|
552
|
-
return jsonResult(data);
|
|
553
|
-
}
|
|
554
|
-
const etag = typeof data.etag === 'string' ? data.etag : undefined;
|
|
555
|
-
const dedupKey = `${client.getPlatform().baseUrl}|${templateId}`;
|
|
556
|
-
// B7: a WINDOWED read — either a continuation (cursor present) or a
|
|
557
|
-
// first slice (max_chars set) — must NEVER short-circuit on the
|
|
558
|
-
// [unchanged] dedup. The agent explicitly wants a (paged) slice of the
|
|
559
|
-
// body, and the one-line `[unchanged]` notice carries no slice + no
|
|
560
|
-
// cursor, which would strand the pager. Only the un-windowed full read
|
|
561
|
-
// is deduped (the forensic's duplicate-84KB waste this guards).
|
|
562
|
-
const isWindowedRead = isContinuation || max_chars !== undefined;
|
|
563
|
-
if (!isWindowedRead && force !== true && flat !== true && etag !== undefined) {
|
|
564
|
-
const lastServed = layoutDedupCache.get(dedupKey);
|
|
565
|
-
if (lastServed === etag) {
|
|
566
|
-
// Identical (template, etag) already emitted this process —
|
|
567
|
-
// skip the re-dump (the forensic's duplicate-84KB waste).
|
|
568
|
-
return jsonResult({
|
|
569
|
-
unchanged: true,
|
|
570
|
-
template_id: templateId,
|
|
571
|
-
etag,
|
|
572
|
-
note: `[unchanged] layout identical to your previous read (etag ${etag}) — ` +
|
|
573
|
-
're-read skipped; pass force:true to re-fetch.',
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
// Record the etag served for this (nested) full read so a later
|
|
578
|
-
// identical read can be short-circuited. Only nested full reads are
|
|
579
|
-
// tracked — flat/projected reads have a different downstream shape.
|
|
580
|
-
if (flat !== true && etag !== undefined) {
|
|
581
|
-
layoutDedupCache.set(dedupKey, etag);
|
|
582
|
-
}
|
|
583
|
-
if (flat !== true) {
|
|
584
|
-
// Default: nested passthrough — unchanged from pre-G.3, except an
|
|
585
|
-
// OPTIONAL G-B `max_chars` caps the (potentially large) JSON text
|
|
586
|
-
// leg. B7 (Glöckle continuation cursor): when the dump is clipped
|
|
587
|
-
// (by `max_chars` or resumed via `cursor`) it now also emits a
|
|
588
|
-
// `next_cursor` so an agent can page through the REST of the
|
|
589
|
-
// subtree instead of being stuck with the first slice. With no
|
|
590
|
-
// `max_chars` AND no cursor the whole body is returned with no
|
|
591
|
-
// cursor — byte-identical to the pre-B7 `applyMaxChars(…,
|
|
592
|
-
// undefined)` no-op.
|
|
593
|
-
if (max_chars !== undefined || isContinuation) {
|
|
594
|
-
return windowedFullDump(data, charOffset, max_chars);
|
|
595
|
-
}
|
|
596
|
-
return applyMaxChars(jsonResult(data), max_chars);
|
|
597
|
-
}
|
|
598
|
-
// flat: true → depth-first walk on the nested layout. Apply
|
|
599
|
-
// pickFields per element when `fields[]` was passed; echo the
|
|
600
|
-
// projection so the AI knows the per-item shape it received.
|
|
601
|
-
//
|
|
602
|
-
// Several distinct envelope shapes reach this handler — all must
|
|
603
|
-
// flatten to the same element list. Resolution funnels through
|
|
604
|
-
// ONE rule (`unwrapToWalkableContainer`) so a single root NODE
|
|
605
|
-
// (`{type:'layout', children:[...]}`) is never handed to
|
|
606
|
-
// flattenLayout directly:
|
|
607
|
-
//
|
|
608
|
-
// (A) Theme templates: `data.layout = {query, type:'single-post',
|
|
609
|
-
// name:'Post', layout:{type:'layout', children:[...],
|
|
610
|
-
// version}}` — the actual node tree lives under the INNER
|
|
611
|
-
// `layout` field. That inner value is itself a single root
|
|
612
|
-
// NODE (not the index-keyed `{0:{...}}` container the older
|
|
613
|
-
// fixtures assumed). Handing the root node to flattenLayout
|
|
614
|
-
// made it iterate the node's OWN top-level entries
|
|
615
|
-
// (`['type',...]`, `['children',[...]]`, `['version',...]`)
|
|
616
|
-
// and emit nothing — `elements:[]` silently (C4 fix,
|
|
617
|
-
// 2026-06-09; verified on wp-dev5 template bFIb-syj). The
|
|
618
|
-
// inner-root-node case is now unwrapped to its `.children`,
|
|
619
|
-
// unifying it with the per-page path below.
|
|
620
|
-
//
|
|
621
|
-
// Legacy F-208 shape `{name, layout:{0:{...},1:{...}}}`
|
|
622
|
-
// (index-keyed inner container) still works: the inner
|
|
623
|
-
// value is NOT a root node, so it passes through to
|
|
624
|
-
// flattenLayout unchanged.
|
|
625
|
-
//
|
|
626
|
-
// (B) Per-page templates (Wave-9 F7 fix, 2026-05-29): cold-AI
|
|
627
|
-
// #8 reported `elements:[]` for a non-empty per-page
|
|
628
|
-
// template. Per-page layouts come from PerPageLayoutEncoder
|
|
629
|
-
// which decodes to the BARE root node
|
|
630
|
-
// `{type:'layout', children:[{...},{...}]}` — NO outer
|
|
631
|
-
// `{name, layout:{...}}` wrapper. Same root-node unwrap
|
|
632
|
-
// rule as (A), applied at the top level.
|
|
633
|
-
//
|
|
634
|
-
// The unwrap rule (single SSoT): if a value is a single root node
|
|
635
|
-
// (`type === 'layout'` with an array `children`), iterate its
|
|
636
|
-
// `.children` array so the walker sees real element nodes and
|
|
637
|
-
// paths anchor on `/layout/children/0`, `/layout/children/1`, …
|
|
638
|
-
const dataLayout = data.layout;
|
|
639
|
-
const isObjectNode = dataLayout !== null &&
|
|
640
|
-
typeof dataLayout === 'object' &&
|
|
641
|
-
!Array.isArray(dataLayout);
|
|
642
|
-
const layoutObj = isObjectNode ? dataLayout : null;
|
|
643
|
-
const hasInnerLayoutField = layoutObj !== null &&
|
|
644
|
-
'layout' in layoutObj &&
|
|
645
|
-
layoutObj.layout !== null &&
|
|
646
|
-
typeof layoutObj.layout === 'object';
|
|
647
|
-
// Resolve the candidate container ONE hop from the envelope:
|
|
648
|
-
// shape (A) descends into the inner `layout`; everything else
|
|
649
|
-
// starts from `data.layout` directly. Then funnel through the
|
|
650
|
-
// shared root-node unwrap so shapes (A) and (B) — and any future
|
|
651
|
-
// single-root-node envelope — collapse identically.
|
|
652
|
-
const candidate = hasInnerLayoutField ? layoutObj.layout : dataLayout;
|
|
653
|
-
const layoutRoot = unwrapToWalkableContainer(candidate);
|
|
654
|
-
// LAYOUT_READ-7: pass the resolved template id so flat-mode `path`s are
|
|
655
|
-
// fully-qualified (`/templates/<id>/layout/children/0`) — matching the
|
|
656
|
-
// `path` element_list emits. `rel_path` stays the short `/children/0`.
|
|
657
|
-
const flatElements = flattenLayout(layoutRoot, templateId);
|
|
658
|
-
// Non-silent fallback (C4) + F29 calibration: if the walk yields
|
|
659
|
-
// ZERO elements AND the resolved walk container is an unrecognized
|
|
660
|
-
// NON-EMPTY shape, surface a warning so it can never pass silently.
|
|
661
|
-
// A genuinely empty container (an empty array — including a bare
|
|
662
|
-
// `{type:'layout', children:[]}` root that unwrapped to `[]` — or
|
|
663
|
-
// an empty object) is a real empty page and must NOT warn.
|
|
664
|
-
const warning = flatElements.length === 0 && isUnrecognizedNonEmptyLayout(layoutRoot)
|
|
665
|
-
? 'layout shape not recognized - flat view may be incomplete'
|
|
666
|
-
: undefined;
|
|
667
|
-
const projected = projectFields(flatElements, fields,
|
|
668
|
-
// No default-set on layout.flat: keep "all" semantics
|
|
669
|
-
// unless caller opts-in. The echo helper below mirrors that.
|
|
670
|
-
[]);
|
|
671
|
-
const echo = projectedFieldsEcho(fields, undefined);
|
|
672
|
-
// F31 (2026-06-10): align the flat-projection path with F23 — when a
|
|
673
|
-
// caller-requested field appears on NO element (e.g. `label` on a
|
|
674
|
-
// YT4 layout), don't echo it in `projected_fields` with no signal.
|
|
675
|
-
// Compute the projection feedback over the FLAT element rows and
|
|
676
|
-
// surface `unknown_fields` + `available_fields` + a loud
|
|
677
|
-
// `projection_warning` (the shared F23 SSoT helper) so the agent can
|
|
678
|
-
// self-correct on the next call. Default-all callers (no fields[])
|
|
679
|
-
// get no audit overhead — projectionFeedback returns undefined.
|
|
680
|
-
// SOURCES_BINDING-29 (parallel site): an EMPTY flat result cannot
|
|
681
|
-
// observe a field vocabulary, so `projectionFeedback` over zero rows
|
|
682
|
-
// would report EVERY requested field as unknown against an empty
|
|
683
|
-
// `available_fields`. Suppress the feedback entirely on a zero-element
|
|
684
|
-
// flatten — the projection is moot when there is nothing to project.
|
|
685
|
-
const feedback = flatElements.length > 0
|
|
686
|
-
? projectionFeedback(flatElements, fields)
|
|
687
|
-
: undefined;
|
|
688
|
-
const projectionNote = projectionWarning(feedback);
|
|
689
|
-
// 1.0.1 Wave-1.7 F-COLD-3: forward the canonical pointer base
|
|
690
|
-
// through the flat-projection path too so cold agents iterating
|
|
691
|
-
// with `flat: true` see the same hint they get on the nested
|
|
692
|
-
// default payload.
|
|
693
|
-
return jsonResult({
|
|
694
|
-
elements: projected,
|
|
695
|
-
...(warning !== undefined ? { warning } : {}),
|
|
696
|
-
...(feedback !== undefined ? {
|
|
697
|
-
available_fields: [...feedback.available_fields],
|
|
698
|
-
unknown_fields: [...feedback.unknown_fields],
|
|
699
|
-
} : {}),
|
|
700
|
-
// F31: trim the leading space the table-header helper prepends —
|
|
701
|
-
// here it rides in a JSON field, not a header string. Emitted
|
|
702
|
-
// ONLY when there's actually an unknown field to flag.
|
|
703
|
-
...(projectionNote !== '' ? { projection_warning: projectionNote.trimStart() } : {}),
|
|
704
|
-
...(typeof data.etag === 'string' ? { etag: data.etag } : {}),
|
|
705
|
-
...(typeof data.layout_root_pointer === 'string'
|
|
706
|
-
? { layout_root_pointer: data.layout_root_pointer }
|
|
707
|
-
: {}),
|
|
708
|
-
...(typeof data.pointer_hint === 'string'
|
|
709
|
-
? { pointer_hint: data.pointer_hint }
|
|
710
|
-
: {}),
|
|
711
|
-
...(echo !== undefined ? { projected_fields: [...echo] } : {}),
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
catch (e) {
|
|
715
|
-
return errorResult({
|
|
716
|
-
error: e,
|
|
717
|
-
context: { template_id },
|
|
718
|
-
hint: 'Verify the template_id exists via yootheme_builder_pages_list. ' +
|
|
719
|
-
'IDs are case-sensitive.',
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
// ─── page_get_schema ────────────────────────────────────────────────
|
|
724
|
-
export async function handlePageGetSchema(client, { template_id, post_id, url, fields, max_chars }) {
|
|
725
|
-
try {
|
|
726
|
-
// G-A: resolve the effective template_id from template_id | post_id | url.
|
|
727
|
-
const effective = await resolveEffectiveTemplateId(client, { template_id, post_id, url });
|
|
728
|
-
if ('error' in effective) {
|
|
729
|
-
return effective.error;
|
|
730
|
-
}
|
|
731
|
-
const templateId = effective.templateId;
|
|
732
|
-
const data = await client.get(`/pages/${encodeTemplateId(templateId)}/schema`);
|
|
733
|
-
const rawNodes = Array.isArray(data.nodes) ? data.nodes : [];
|
|
734
|
-
const rows = buildSchemaRows(rawNodes.filter((x) => x !== null && typeof x === 'object'));
|
|
735
|
-
// G-B (Glöckle 2026-06-26, P2): `fields[]` projection — DEFAULT_FIELDS_SCHEMA
|
|
736
|
-
// existed but was never wired. Mirror element_list: project both legs,
|
|
737
|
-
// echo `projected_fields`, surface the F23 unknown-field feedback.
|
|
738
|
-
const items = projectFields(rows, fields, DEFAULT_FIELDS_SCHEMA);
|
|
739
|
-
const echo = projectedFieldsEcho(fields, DEFAULT_FIELDS_SCHEMA);
|
|
740
|
-
const feedback = projectionFeedback(rows, fields);
|
|
741
|
-
const unknownNote = projectionWarning(feedback);
|
|
742
|
-
const hasNarrowProjection = Array.isArray(fields) && fields.length > 0;
|
|
743
|
-
// Templates routinely exceed 21 nodes (a typical home page has
|
|
744
|
-
// 30–150 elements). Force compact level so the LLM never gets
|
|
745
|
-
// truncated text — toolkit's resolveDetailLevel honours the
|
|
746
|
-
// explicit override. With a narrow `fields[]` projection, render the
|
|
747
|
-
// projected rows from caller-chosen columns (mirrors element_list).
|
|
748
|
-
//
|
|
749
|
-
// TODO(toolkit-upstream): contribute a `compactWhen: (count) => boolean`
|
|
750
|
-
// field to @getimo/mcp-toolkit's AutoFormatOptions so this
|
|
751
|
-
// can be expressed declaratively on the config object instead
|
|
752
|
-
// of via the third positional argument. Tracked as Round-1.5
|
|
753
|
-
// follow-up (I2).
|
|
754
|
-
const toolkitResult = hasNarrowProjection
|
|
755
|
-
? tableResult(items, {
|
|
756
|
-
columns: columnsFromFields([...fields]),
|
|
757
|
-
header: (count) => `${String(count)} nodes in template "${templateId}"${unknownNote}`,
|
|
758
|
-
footer: 'Use yootheme_builder_element_get <path> for full element data.',
|
|
759
|
-
}, 'compact')
|
|
760
|
-
: tableResult(rows, {
|
|
761
|
-
columns: [...SCHEMA_TABLE_COLUMNS],
|
|
762
|
-
compactColumns: [...SCHEMA_COMPACT_COLUMNS],
|
|
763
|
-
header: (count) => `${String(count)} nodes in template "${templateId}"`,
|
|
764
|
-
footer: 'Use yootheme_builder_element_get <path> for full element data.',
|
|
765
|
-
}, 'compact');
|
|
766
|
-
return structuredResult(applyMaxChars(toolkitResult, max_chars), {
|
|
767
|
-
items,
|
|
768
|
-
total: items.length,
|
|
769
|
-
template_id: templateId,
|
|
770
|
-
...(echo !== undefined ? { projected_fields: [...echo] } : {}),
|
|
771
|
-
...(feedback !== undefined ? {
|
|
772
|
-
available_fields: [...feedback.available_fields],
|
|
773
|
-
unknown_fields: [...feedback.unknown_fields],
|
|
774
|
-
...(unknownNote.trim() !== '' ? { projection_warning: unknownNote.trim() } : {}),
|
|
775
|
-
} : {}),
|
|
776
|
-
});
|
|
777
|
-
}
|
|
778
|
-
catch (e) {
|
|
779
|
-
return errorResult({
|
|
780
|
-
error: e,
|
|
781
|
-
context: { template_id },
|
|
782
|
-
hint: 'Verify the template_id exists via yootheme_builder_pages_list.',
|
|
783
|
-
});
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
// ─── get_etag ───────────────────────────────────────────────────────
|
|
787
|
-
export async function handleGetEtag(client) {
|
|
788
|
-
try {
|
|
789
|
-
const data = await client.get('/etag');
|
|
790
|
-
const toolkitResult = detailResult(buildEtagDetail({
|
|
791
|
-
etag: data.etag,
|
|
792
|
-
generated_at: data.generated_at,
|
|
793
|
-
}));
|
|
794
|
-
return structuredResult(toolkitResult, {
|
|
795
|
-
etag: data.etag,
|
|
796
|
-
...(typeof data.generated_at === 'string'
|
|
797
|
-
? { generated_at: data.generated_at }
|
|
798
|
-
: {}),
|
|
799
|
-
});
|
|
800
|
-
}
|
|
801
|
-
catch (e) {
|
|
802
|
-
return errorResult({
|
|
803
|
-
error: e,
|
|
804
|
-
context: {},
|
|
805
|
-
hint: 'Run yootheme_builder_diagnose to verify auth.',
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
// ─── template_summary (T9 — Audit-v3 B.5 token-efficient overview) ────
|
|
810
|
-
/**
|
|
811
|
-
* T9: a one-call structured overview of a template — element counts by
|
|
812
|
-
* type, binding count, max nesting depth, and named landmarks. Lets the
|
|
813
|
-
* agent grasp a 96-node template for ~1 kB instead of pulling the full
|
|
814
|
-
* element_list dump (20 kB+).
|
|
815
|
-
*/
|
|
816
|
-
export async function handleTemplateSummary(client, { template_id }) {
|
|
817
|
-
try {
|
|
818
|
-
const data = await client.get(`/pages/${encodeTemplateId(template_id)}/summary`);
|
|
819
|
-
// F-AUDIT-2 (2026-05-26): template_summary now declares
|
|
820
|
-
// TEMPLATE_SUMMARY_OUTPUT_SCHEMA. The SDK requires
|
|
821
|
-
// `structuredContent` when an outputSchema is present, otherwise
|
|
822
|
-
// it raises `-32602 Output validation error`. Wrap the raw body
|
|
823
|
-
// with `structuredResult` so the text leg (LLM-readable JSON)
|
|
824
|
-
// stays unchanged AND the structuredContent leg validates.
|
|
825
|
-
//
|
|
826
|
-
// Task #46 Friction-3 (2026-05-29): PHP's `json_encode([])` emits
|
|
827
|
-
// `[]` (array) — not `{}` (object). The REST handler emits
|
|
828
|
-
// `counts_by_type: []` for empty templates, but the outputSchema
|
|
829
|
-
// declares `z.record(z.string(), z.number())` which requires an
|
|
830
|
-
// object. The mismatch surfaces as `-32602 counts_by_type
|
|
831
|
-
// expected record, received array`, swallowing the entire response
|
|
832
|
-
// for any empty / freshly-created template. Normalize array→object
|
|
833
|
-
// here so the schema validates and the agent sees the (valid,
|
|
834
|
-
// empty) summary. Same defensive shape applies to any future
|
|
835
|
-
// map-typed REST field that might come back empty.
|
|
836
|
-
const normalized = {
|
|
837
|
-
...data,
|
|
838
|
-
};
|
|
839
|
-
if (Array.isArray(normalized.counts_by_type)) {
|
|
840
|
-
normalized.counts_by_type = {};
|
|
841
|
-
}
|
|
842
|
-
const toolkitResult = jsonResult(normalized);
|
|
843
|
-
return structuredResult({ content: toolkitResult.content }, normalized);
|
|
844
|
-
}
|
|
845
|
-
catch (e) {
|
|
846
|
-
return errorResult({
|
|
847
|
-
error: e,
|
|
848
|
-
context: { template_id },
|
|
849
|
-
hint: 'Verify the template_id exists via yootheme_builder_pages_list.',
|
|
850
|
-
});
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
// ─── render_preview (F5 + N5 — authenticated post-write render check) ──
|
|
854
|
-
/**
|
|
855
|
-
* F5 + N5 (Glöckle HANDOFF-4/5): the authenticated post-write render
|
|
856
|
-
* HEALTHCHECK. Resolves the EFFECTIVE template_id from `template_id` OR `url`
|
|
857
|
-
* (the SAME `resolveEffectiveTemplateId` precedence page_get_layout uses — a
|
|
858
|
-
* pasted public URL is reverse-resolved via GET /pages/resolve first), then
|
|
859
|
-
* GETs `/pages/{id}/render-preview` which runs the in-process read-only Builder
|
|
860
|
-
* render server-side over the already-authenticated Bearer channel — answering
|
|
861
|
-
* "renders / N items / blank?" where an external cURL 401s behind QA Basic-Auth.
|
|
862
|
-
*
|
|
863
|
-
* Returns the strict RENDER_PREVIEW_OUTPUT_SCHEMA shape: `{rendered, item_count,
|
|
864
|
-
* empty, error?, cache_purge_hint, template_id}`. A render that resolved to zero
|
|
865
|
-
* items, or that threw inside the Builder pipeline (the swallowed YOOtheme
|
|
866
|
-
* render error surfaced as `error`), is a SUCCESS — not a tool error.
|
|
867
|
-
*/
|
|
868
|
-
export async function handleRenderPreview(client, { template_id, post_id, url, expect }) {
|
|
869
|
-
try {
|
|
870
|
-
// WAVE-1 follow-up (a): render_preview now accepts `post_id` too, the SAME
|
|
871
|
-
// three-mode addressing page_get_layout uses — template_id wins, else a
|
|
872
|
-
// bare numeric post/article id, else a `url` reverse-resolved via
|
|
873
|
-
// /pages/resolve. (Cross-file: the RENDER_PREVIEW input schema in
|
|
874
|
-
// pages/builders.ts must also declare `post_id` + the native catalog must
|
|
875
|
-
// carry it — flagged for the coordinator regen.)
|
|
876
|
-
const effective = await resolveEffectiveTemplateId(client, { template_id, post_id, url });
|
|
877
|
-
if ('error' in effective) {
|
|
878
|
-
return effective.error;
|
|
879
|
-
}
|
|
880
|
-
const templateId = effective.templateId;
|
|
881
|
-
// Glöckle HANDOFF-6 #4: an `expect` substring is passed to the render
|
|
882
|
-
// endpoint as a query param (the server greps the rendered HTML and adds
|
|
883
|
-
// {matched, snippet}). A blank value is treated as "no check".
|
|
884
|
-
const wantMatch = typeof expect === 'string' && expect !== '';
|
|
885
|
-
const query = wantMatch ? `?${new URLSearchParams({ expect }).toString()}` : '';
|
|
886
|
-
const data = await client.get(`/pages/${encodeTemplateId(templateId)}/render-preview${query}`);
|
|
887
|
-
// Normalize the REST body into the strict output shape. Defensive
|
|
888
|
-
// coercion keeps a malformed/partial host payload from tripping the
|
|
889
|
-
// strict outputSchema (-32602) — the structured leg MUST validate.
|
|
890
|
-
const payload = {
|
|
891
|
-
template_id: typeof data.template_id === 'string' ? data.template_id : templateId,
|
|
892
|
-
rendered: data.rendered === true,
|
|
893
|
-
item_count: typeof data.item_count === 'number' && Number.isFinite(data.item_count)
|
|
894
|
-
? Math.max(0, Math.trunc(data.item_count))
|
|
895
|
-
: 0,
|
|
896
|
-
empty: data.empty !== false,
|
|
897
|
-
cache_purge_hint: typeof data.cache_purge_hint === 'string' ? data.cache_purge_hint : '',
|
|
898
|
-
...(typeof data.error === 'string' ? { error: data.error } : {}),
|
|
899
|
-
// The {matched, snippet} pair is surfaced ONLY when `expect` was
|
|
900
|
-
// requested. `matched` coerces to a strict boolean; `snippet` is a
|
|
901
|
-
// string when present, else null (a miss / a render that threw).
|
|
902
|
-
...(wantMatch
|
|
903
|
-
? {
|
|
904
|
-
matched: data.matched === true,
|
|
905
|
-
snippet: typeof data.snippet === 'string' ? data.snippet : null,
|
|
906
|
-
}
|
|
907
|
-
: {}),
|
|
908
|
-
};
|
|
909
|
-
return structuredResult(detailResult(buildRenderPreviewDetail(payload)), {
|
|
910
|
-
rendered: payload.rendered,
|
|
911
|
-
item_count: payload.item_count,
|
|
912
|
-
empty: payload.empty,
|
|
913
|
-
cache_purge_hint: payload.cache_purge_hint,
|
|
914
|
-
template_id: payload.template_id,
|
|
915
|
-
...(payload.error !== undefined ? { error: payload.error } : {}),
|
|
916
|
-
...(payload.matched !== undefined ? { matched: payload.matched } : {}),
|
|
917
|
-
...(wantMatch ? { snippet: payload.snippet ?? null } : {}),
|
|
918
|
-
});
|
|
919
|
-
}
|
|
920
|
-
catch (e) {
|
|
921
|
-
return errorResult({
|
|
922
|
-
error: e,
|
|
923
|
-
context: { template_id, post_id, url, expect },
|
|
924
|
-
hint: 'Verify the template_id exists via yootheme_builder_pages_list ' +
|
|
925
|
-
'(or that post_id / the url resolves). Run yootheme_builder_diagnose to check auth.',
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
//# sourceMappingURL=handlers-read.js.map
|