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