@takazudo/zudo-doc 3.3.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +2 -2
  3. package/bin/tag-cli-config.ts +126 -0
  4. package/bin/tags-audit-runner.ts +60 -76
  5. package/bin/tags-audit.mjs +17 -36
  6. package/bin/tags-suggest-runner.ts +429 -0
  7. package/bin/tags-suggest.mjs +30 -0
  8. package/bin/zudo-doc.mjs +78 -25
  9. package/dist/breadcrumb/breadcrumb.d.ts +4 -4
  10. package/dist/breadcrumb/find-path.d.ts +2 -2
  11. package/dist/breadcrumb/index.d.ts +1 -1
  12. package/dist/breadcrumb/types.d.ts +0 -5
  13. package/dist/chrome/derive.d.ts +16 -10
  14. package/dist/chrome/derive.js +53 -4
  15. package/dist/chrome/index.d.ts +13 -10
  16. package/dist/chrome/index.js +12 -6
  17. package/dist/chrome/primary-slots.d.ts +21 -0
  18. package/dist/chrome/primary-slots.js +59 -0
  19. package/dist/chrome-bindings.d.ts +68 -0
  20. package/dist/code-syntax/code-block-enhancer-script.d.ts +4 -0
  21. package/dist/code-syntax/code-block-enhancer-script.js +7 -4
  22. package/dist/code-syntax/code-block-enhancer.d.ts +2 -2
  23. package/dist/code-syntax/code-block-enhancer.js +1 -3
  24. package/dist/code-syntax/index.d.ts +5 -5
  25. package/dist/code-syntax/index.js +4 -13
  26. package/dist/code-syntax/mermaid-init-script.d.ts +1 -22
  27. package/dist/code-syntax/mermaid-init-script.js +0 -2
  28. package/dist/code-syntax/mermaid-init.d.ts +0 -1
  29. package/dist/code-syntax/mermaid-init.js +3 -4
  30. package/dist/code-syntax/tabs-init.d.ts +0 -1
  31. package/dist/code-syntax/tabs-init.js +1 -3
  32. package/dist/code-syntax/tabs.d.ts +0 -1
  33. package/dist/code-syntax/tabs.js +1 -3
  34. package/dist/color-scheme-utils.d.ts +71 -3
  35. package/dist/color-scheme-utils.js +137 -0
  36. package/dist/color-schemes-defaults/index.js +13 -0
  37. package/dist/config.d.ts +28 -12
  38. package/dist/config.js +11 -2
  39. package/dist/content/component-map.d.ts +0 -16
  40. package/dist/content/component-map.js +2 -4
  41. package/dist/content/index.d.ts +1 -1
  42. package/dist/content/index.js +2 -3
  43. package/dist/content.css +1 -1
  44. package/dist/design-token-panel-bootstrap.d.ts +45 -40
  45. package/dist/design-token-panel-bootstrap.js +98 -21
  46. package/dist/design-token-panel-config/index.js +1 -4
  47. package/dist/doc-body-end-islands/design-token-panel-island.d.ts +15 -0
  48. package/dist/doc-body-end-islands/design-token-panel-island.js +31 -0
  49. package/dist/doc-body-end-islands/index.d.ts +39 -17
  50. package/dist/doc-body-end-islands/index.js +13 -21
  51. package/dist/doc-body-end-islands/theme-pack-switcher-island.d.ts +37 -0
  52. package/dist/doc-body-end-islands/theme-pack-switcher-island.js +18 -0
  53. package/dist/doc-content-header/index.js +1 -1
  54. package/dist/doc-history-area/index.d.ts +10 -4
  55. package/dist/doc-history-area/index.js +3 -2
  56. package/dist/doc-metainfo-area/index.d.ts +1 -0
  57. package/dist/doc-page-props/index.d.ts +7 -23
  58. package/dist/doc-page-renderer/index.d.ts +1 -0
  59. package/dist/doc-page-renderer/index.js +1 -0
  60. package/dist/doc-page-shell/index.js +19 -12
  61. package/dist/doc-pager/index.js +1 -1
  62. package/dist/doc-route-entries/index.d.ts +2 -2
  63. package/dist/doclayout/doc-layout-with-defaults.js +4 -4
  64. package/dist/doclayout/doc-layout.d.ts +8 -0
  65. package/dist/doclayout/doc-layout.js +10 -1
  66. package/dist/docs-schema/index.js +1 -5
  67. package/dist/eject/index.d.ts +16 -0
  68. package/dist/eject/index.js +122 -28
  69. package/dist/extract-headings/index.d.ts +5 -8
  70. package/dist/extract-headings/index.js +2 -9
  71. package/dist/factory-context/index.d.ts +42 -4
  72. package/dist/features.css +55 -43
  73. package/dist/footer/footer.js +1 -0
  74. package/dist/head-with-defaults/index.d.ts +2 -0
  75. package/dist/head-with-defaults/index.js +16 -0
  76. package/dist/header/header.d.ts +10 -5
  77. package/dist/header/header.js +45 -5
  78. package/dist/header/index.d.ts +1 -1
  79. package/dist/header/types.d.ts +30 -1
  80. package/dist/header-with-defaults/index.js +1 -0
  81. package/dist/home-page/index.d.ts +2 -0
  82. package/dist/home-page/index.js +11 -5
  83. package/dist/home-page/prepare-home-data.js +1 -1
  84. package/dist/locale-merge/index.d.ts +9 -14
  85. package/dist/locale-merge/index.js +6 -4
  86. package/dist/mdx-components/index.js +4 -4
  87. package/dist/plugins/claude-resources.d.ts +1 -0
  88. package/dist/plugins/claude-resources.js +4 -2
  89. package/dist/plugins/doc-history.js +1 -1
  90. package/dist/{integrations → plugins/internal}/claude-resources/index.d.ts +1 -16
  91. package/dist/{integrations → plugins/internal}/claude-resources/index.js +0 -9
  92. package/dist/{integrations → plugins/internal}/doc-history/index.d.ts +0 -17
  93. package/dist/{integrations → plugins/internal}/doc-history/index.js +0 -4
  94. package/dist/{integrations → plugins/internal}/doc-history/pre-build.d.ts +2 -4
  95. package/dist/plugins/internal/llms-txt/index.d.ts +7 -0
  96. package/dist/{integrations → plugins/internal}/llms-txt/load.d.ts +1 -1
  97. package/dist/{integrations → plugins/internal}/llms-txt/load.js +2 -2
  98. package/dist/{integrations → plugins/internal}/llms-txt/strip.d.ts +2 -3
  99. package/dist/{integrations → plugins/internal}/llms-txt/strip.js +1 -1
  100. package/dist/{integrations → plugins/internal}/llms-txt/types.d.ts +13 -22
  101. package/dist/{integrations → plugins/internal}/search-index/collect.js +1 -1
  102. package/dist/plugins/internal/theme-packs/copy.d.ts +32 -0
  103. package/dist/plugins/internal/theme-packs/copy.js +45 -0
  104. package/dist/plugins/internal/theme-packs/dev-middleware.d.ts +22 -0
  105. package/dist/plugins/internal/theme-packs/dev-middleware.js +80 -0
  106. package/dist/plugins/internal/theme-packs/index.d.ts +6 -0
  107. package/dist/plugins/internal/theme-packs/index.js +9 -0
  108. package/dist/plugins/internal/theme-packs/resolve.d.ts +17 -0
  109. package/dist/plugins/internal/theme-packs/resolve.js +17 -0
  110. package/dist/plugins/internal/theme-packs/types.d.ts +22 -0
  111. package/dist/plugins/internal/theme-packs/types.js +0 -0
  112. package/dist/plugins/llms-txt.js +1 -1
  113. package/dist/plugins/routes.js +11 -1
  114. package/dist/plugins/search-index.js +1 -1
  115. package/dist/plugins/theme-packs.d.ts +3 -0
  116. package/dist/plugins/theme-packs.js +40 -0
  117. package/dist/preset.d.ts +19 -14
  118. package/dist/preset.js +24 -9
  119. package/dist/route-context/index.js +4 -6
  120. package/dist/route-enumerators/index.d.ts +6 -18
  121. package/dist/route-enumerators/index.js +8 -6
  122. package/dist/routes/404.js +3 -1
  123. package/dist/routes/_chrome.js +2 -2
  124. package/dist/routes/_context.d.ts +7 -3
  125. package/dist/routes/_context.js +2 -0
  126. package/dist/routes/_docs-helpers.js +9 -21
  127. package/dist/safelist.css +1 -1
  128. package/dist/settings.d.ts +27 -12
  129. package/dist/sidebar-tree/build-tree.d.ts +3 -4
  130. package/dist/sidebar-tree/build-tree.js +4 -3
  131. package/dist/sidebar-tree/index.d.ts +2 -2
  132. package/dist/sidebar-tree/types.d.ts +6 -17
  133. package/dist/site-tree-nav-island/index.d.ts +3 -1
  134. package/dist/site-tree-nav-island/index.js +17 -5
  135. package/dist/site-tree-nav-island/state.d.ts +4 -0
  136. package/dist/site-tree-nav-island/state.js +10 -0
  137. package/dist/tag-helpers/index.d.ts +6 -13
  138. package/dist/tag-helpers/index.js +5 -23
  139. package/dist/tag-pages/index.d.ts +8 -21
  140. package/dist/tag-pages/index.js +14 -10
  141. package/dist/tags-audit.d.ts +16 -44
  142. package/dist/tags-audit.js +9 -172
  143. package/dist/theme/color-scheme-provider.d.ts +2 -3
  144. package/dist/theme/color-scheme-provider.js +2 -10
  145. package/dist/theme/index.d.ts +1 -4
  146. package/dist/theme/index.js +2 -30
  147. package/dist/theme/theme-pack-provider.d.ts +42 -0
  148. package/dist/theme/theme-pack-provider.js +75 -0
  149. package/dist/theme-cli/apply.d.ts +16 -0
  150. package/dist/theme-cli/apply.js +61 -0
  151. package/dist/theme-cli/config-io.d.ts +15 -0
  152. package/dist/theme-cli/config-io.js +51 -0
  153. package/dist/theme-cli/config-rewriter.d.ts +21 -0
  154. package/dist/theme-cli/config-rewriter.js +141 -0
  155. package/dist/theme-cli/config-scanner.d.ts +63 -0
  156. package/dist/theme-cli/config-scanner.js +288 -0
  157. package/dist/theme-cli/index.d.ts +7 -0
  158. package/dist/theme-cli/index.js +38 -0
  159. package/dist/theme-cli/list.d.ts +27 -0
  160. package/dist/theme-cli/list.js +64 -0
  161. package/dist/theme-cli/provenance.d.ts +17 -0
  162. package/dist/theme-cli/provenance.js +35 -0
  163. package/dist/theme-cli/registry.d.ts +14 -0
  164. package/dist/theme-cli/registry.js +13 -0
  165. package/dist/theme-pack-dialog/dialog-state.d.ts +25 -0
  166. package/dist/theme-pack-dialog/dialog-state.js +40 -0
  167. package/dist/theme-pack-dialog/index.d.ts +5 -0
  168. package/dist/theme-pack-dialog/index.js +152 -0
  169. package/dist/theme-pack-dialog/theme-pack-card.d.ts +25 -0
  170. package/dist/theme-pack-dialog/theme-pack-card.js +72 -0
  171. package/dist/theme-pack-switcher/index.d.ts +49 -0
  172. package/dist/theme-pack-switcher/index.js +205 -0
  173. package/dist/theme-pack-switcher/switcher-state.d.ts +56 -0
  174. package/dist/theme-pack-switcher/switcher-state.js +43 -0
  175. package/dist/theme-pack-switcher/theme-pack-sync.d.ts +85 -0
  176. package/dist/theme-pack-switcher/theme-pack-sync.js +121 -0
  177. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-400-latin.woff2 +0 -0
  178. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-700-latin.woff2 +0 -0
  179. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-italic-400-latin.woff2 +0 -0
  180. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-italic-700-latin.woff2 +0 -0
  181. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegibleMono-italic-latin.woff2 +0 -0
  182. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegibleMono-latin.woff2 +0 -0
  183. package/dist/theme-packs/beacon/fonts/OFL.txt +94 -0
  184. package/dist/theme-packs/beacon/meta.json +37 -0
  185. package/dist/theme-packs/beacon/pack.css +442 -0
  186. package/dist/theme-packs/broadsheet/fonts/CourierPrime-400-latin.woff2 +0 -0
  187. package/dist/theme-packs/broadsheet/fonts/CourierPrime-700-latin.woff2 +0 -0
  188. package/dist/theme-packs/broadsheet/fonts/OFL.txt +95 -0
  189. package/dist/theme-packs/broadsheet/fonts/PlayfairDisplay-italic-latin.woff2 +0 -0
  190. package/dist/theme-packs/broadsheet/fonts/PlayfairDisplay-latin.woff2 +0 -0
  191. package/dist/theme-packs/broadsheet/fonts/SourceSerif4-italic-latin.woff2 +0 -0
  192. package/dist/theme-packs/broadsheet/fonts/SourceSerif4-latin.woff2 +0 -0
  193. package/dist/theme-packs/broadsheet/meta.json +38 -0
  194. package/dist/theme-packs/broadsheet/pack.css +448 -0
  195. package/dist/theme-packs/brutalist/fonts/ArchivoBlack-latin.woff2 +0 -0
  196. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  197. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  198. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-700-latin.woff2 +0 -0
  199. package/dist/theme-packs/brutalist/fonts/OFL.txt +95 -0
  200. package/dist/theme-packs/brutalist/fonts/SpaceGrotesk-latin.woff2 +0 -0
  201. package/dist/theme-packs/brutalist/meta.json +38 -0
  202. package/dist/theme-packs/brutalist/pack.css +546 -0
  203. package/dist/theme-packs/default/meta.json +37 -0
  204. package/dist/theme-packs/drift/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  205. package/dist/theme-packs/drift/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  206. package/dist/theme-packs/drift/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  207. package/dist/theme-packs/drift/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  208. package/dist/theme-packs/drift/fonts/IBMPlexSans-italic-latin.woff2 +0 -0
  209. package/dist/theme-packs/drift/fonts/IBMPlexSans-latin-ext.woff2 +0 -0
  210. package/dist/theme-packs/drift/fonts/IBMPlexSans-latin.woff2 +0 -0
  211. package/dist/theme-packs/drift/fonts/OFL.txt +93 -0
  212. package/dist/theme-packs/drift/meta.json +37 -0
  213. package/dist/theme-packs/drift/pack.css +478 -0
  214. package/dist/theme-packs/fjord/fonts/Inter-latin-ext.woff2 +0 -0
  215. package/dist/theme-packs/fjord/fonts/Inter-latin.woff2 +0 -0
  216. package/dist/theme-packs/fjord/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  217. package/dist/theme-packs/fjord/fonts/JetBrainsMono-latin.woff2 +0 -0
  218. package/dist/theme-packs/fjord/fonts/OFL.txt +94 -0
  219. package/dist/theme-packs/fjord/meta.json +37 -0
  220. package/dist/theme-packs/fjord/pack.css +375 -0
  221. package/dist/theme-packs/foundry/fonts/Inter-latin-ext.woff2 +0 -0
  222. package/dist/theme-packs/foundry/fonts/Inter-latin.woff2 +0 -0
  223. package/dist/theme-packs/foundry/fonts/OFL.txt +93 -0
  224. package/dist/theme-packs/foundry/meta.json +37 -0
  225. package/dist/theme-packs/foundry/pack.css +202 -0
  226. package/dist/theme-packs/futura-editorial/fonts/Jost-latin.woff2 +0 -0
  227. package/dist/theme-packs/futura-editorial/fonts/NotoSans-italic-latin.woff2 +0 -0
  228. package/dist/theme-packs/futura-editorial/fonts/NotoSans-latin.woff2 +0 -0
  229. package/dist/theme-packs/futura-editorial/fonts/OFL.txt +95 -0
  230. package/dist/theme-packs/futura-editorial/fonts/SpaceMono-400-latin.woff2 +0 -0
  231. package/dist/theme-packs/futura-editorial/fonts/SpaceMono-700-latin.woff2 +0 -0
  232. package/dist/theme-packs/futura-editorial/meta.json +38 -0
  233. package/dist/theme-packs/futura-editorial/pack.css +313 -0
  234. package/dist/theme-packs/hearth/fonts/Fraunces-italic-latin.woff2 +0 -0
  235. package/dist/theme-packs/hearth/fonts/Fraunces-latin.woff2 +0 -0
  236. package/dist/theme-packs/hearth/fonts/Nunito-latin.woff2 +0 -0
  237. package/dist/theme-packs/hearth/fonts/OFL.txt +95 -0
  238. package/dist/theme-packs/hearth/fonts/SplineSansMono-latin.woff2 +0 -0
  239. package/dist/theme-packs/hearth/meta.json +38 -0
  240. package/dist/theme-packs/hearth/pack.css +385 -0
  241. package/dist/theme-packs/hollow/fonts/OFL.txt +94 -0
  242. package/dist/theme-packs/hollow/fonts/SpaceGrotesk-latin.woff2 +0 -0
  243. package/dist/theme-packs/hollow/fonts/SpaceMono-400-italic-latin.woff2 +0 -0
  244. package/dist/theme-packs/hollow/fonts/SpaceMono-400-latin.woff2 +0 -0
  245. package/dist/theme-packs/hollow/fonts/SpaceMono-700-latin.woff2 +0 -0
  246. package/dist/theme-packs/hollow/meta.json +37 -0
  247. package/dist/theme-packs/hollow/pack.css +428 -0
  248. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-ext-italic.woff2 +0 -0
  249. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-ext.woff2 +0 -0
  250. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-italic.woff2 +0 -0
  251. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin.woff2 +0 -0
  252. package/dist/theme-packs/ledger/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  253. package/dist/theme-packs/ledger/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  254. package/dist/theme-packs/ledger/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  255. package/dist/theme-packs/ledger/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  256. package/dist/theme-packs/ledger/fonts/OFL.txt +94 -0
  257. package/dist/theme-packs/ledger/meta.json +37 -0
  258. package/dist/theme-packs/ledger/pack.css +463 -0
  259. package/dist/theme-packs/manuscript/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
  260. package/dist/theme-packs/manuscript/fonts/CourierPrime-400-latin.woff2 +0 -0
  261. package/dist/theme-packs/manuscript/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
  262. package/dist/theme-packs/manuscript/fonts/CourierPrime-700-latin.woff2 +0 -0
  263. package/dist/theme-packs/manuscript/fonts/EBGaramond-latin-italic.woff2 +0 -0
  264. package/dist/theme-packs/manuscript/fonts/EBGaramond-latin.woff2 +0 -0
  265. package/dist/theme-packs/manuscript/fonts/OFL.txt +94 -0
  266. package/dist/theme-packs/manuscript/meta.json +37 -0
  267. package/dist/theme-packs/manuscript/pack.css +376 -0
  268. package/dist/theme-packs/matcha/fonts/MPLUS1Code-latin.woff2 +0 -0
  269. package/dist/theme-packs/matcha/fonts/OFL.txt +95 -0
  270. package/dist/theme-packs/matcha/fonts/ShipporiMincho-500-latin.woff2 +0 -0
  271. package/dist/theme-packs/matcha/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  272. package/dist/theme-packs/matcha/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  273. package/dist/theme-packs/matcha/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  274. package/dist/theme-packs/matcha/meta.json +38 -0
  275. package/dist/theme-packs/matcha/pack.css +409 -0
  276. package/dist/theme-packs/nocturne/fonts/CormorantGaramond-italic-latin.woff2 +0 -0
  277. package/dist/theme-packs/nocturne/fonts/CormorantGaramond-latin.woff2 +0 -0
  278. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  279. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  280. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-italic-latin.woff2 +0 -0
  281. package/dist/theme-packs/nocturne/fonts/Manrope-latin.woff2 +0 -0
  282. package/dist/theme-packs/nocturne/fonts/OFL.txt +95 -0
  283. package/dist/theme-packs/nocturne/meta.json +38 -0
  284. package/dist/theme-packs/nocturne/pack.css +502 -0
  285. package/dist/theme-packs/observatory/fonts/JosefinSans-latin.woff2 +0 -0
  286. package/dist/theme-packs/observatory/fonts/Jost-italic-latin.woff2 +0 -0
  287. package/dist/theme-packs/observatory/fonts/Jost-latin.woff2 +0 -0
  288. package/dist/theme-packs/observatory/fonts/OFL.txt +95 -0
  289. package/dist/theme-packs/observatory/fonts/SpaceMono-400-latin.woff2 +0 -0
  290. package/dist/theme-packs/observatory/fonts/SpaceMono-700-latin.woff2 +0 -0
  291. package/dist/theme-packs/observatory/fonts/SpaceMono-italic-latin.woff2 +0 -0
  292. package/dist/theme-packs/observatory/meta.json +38 -0
  293. package/dist/theme-packs/observatory/pack.css +728 -0
  294. package/dist/theme-packs/onyx/fonts/CormorantGaramond-italic-latin.woff2 +0 -0
  295. package/dist/theme-packs/onyx/fonts/CormorantGaramond-latin.woff2 +0 -0
  296. package/dist/theme-packs/onyx/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  297. package/dist/theme-packs/onyx/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  298. package/dist/theme-packs/onyx/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  299. package/dist/theme-packs/onyx/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  300. package/dist/theme-packs/onyx/fonts/Jost-latin.woff2 +0 -0
  301. package/dist/theme-packs/onyx/fonts/OFL.txt +95 -0
  302. package/dist/theme-packs/onyx/meta.json +38 -0
  303. package/dist/theme-packs/onyx/pack.css +497 -0
  304. package/dist/theme-packs/phosphor/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  305. package/dist/theme-packs/phosphor/fonts/JetBrainsMono-latin.woff2 +0 -0
  306. package/dist/theme-packs/phosphor/fonts/OFL.txt +94 -0
  307. package/dist/theme-packs/phosphor/fonts/VT323-latin-ext.woff2 +0 -0
  308. package/dist/theme-packs/phosphor/fonts/VT323-latin.woff2 +0 -0
  309. package/dist/theme-packs/phosphor/meta.json +38 -0
  310. package/dist/theme-packs/phosphor/pack.css +493 -0
  311. package/dist/theme-packs/solar/fonts/OFL.txt +94 -0
  312. package/dist/theme-packs/solar/fonts/SourceCodePro-italic-latin.woff2 +0 -0
  313. package/dist/theme-packs/solar/fonts/SourceCodePro-latin.woff2 +0 -0
  314. package/dist/theme-packs/solar/fonts/SourceSans3-italic-latin.woff2 +0 -0
  315. package/dist/theme-packs/solar/fonts/SourceSans3-latin.woff2 +0 -0
  316. package/dist/theme-packs/solar/meta.json +37 -0
  317. package/dist/theme-packs/solar/pack.css +380 -0
  318. package/dist/theme-packs/sumi/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  319. package/dist/theme-packs/sumi/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  320. package/dist/theme-packs/sumi/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  321. package/dist/theme-packs/sumi/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  322. package/dist/theme-packs/sumi/fonts/OFL.txt +95 -0
  323. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-600-latin.woff2 +0 -0
  324. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-700-latin.woff2 +0 -0
  325. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-800-latin.woff2 +0 -0
  326. package/dist/theme-packs/sumi/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  327. package/dist/theme-packs/sumi/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  328. package/dist/theme-packs/sumi/meta.json +38 -0
  329. package/dist/theme-packs/sumi/pack.css +502 -0
  330. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  331. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  332. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-600-latin.woff2 +0 -0
  333. package/dist/theme-packs/swissgrid/fonts/Inter-latin-ext.woff2 +0 -0
  334. package/dist/theme-packs/swissgrid/fonts/Inter-latin.woff2 +0 -0
  335. package/dist/theme-packs/swissgrid/fonts/InterTight-latin.woff2 +0 -0
  336. package/dist/theme-packs/swissgrid/fonts/OFL.txt +95 -0
  337. package/dist/theme-packs/swissgrid/meta.json +38 -0
  338. package/dist/theme-packs/swissgrid/pack.css +518 -0
  339. package/dist/theme-packs/washi/fonts/MPlus1Code-400-latin.woff2 +0 -0
  340. package/dist/theme-packs/washi/fonts/MPlus1Code-500-latin.woff2 +0 -0
  341. package/dist/theme-packs/washi/fonts/OFL.txt +95 -0
  342. package/dist/theme-packs/washi/fonts/ShipporiMincho-500-latin.woff2 +0 -0
  343. package/dist/theme-packs/washi/fonts/ShipporiMincho-600-latin.woff2 +0 -0
  344. package/dist/theme-packs/washi/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  345. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  346. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  347. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-700-latin.woff2 +0 -0
  348. package/dist/theme-packs/washi/meta.json +38 -0
  349. package/dist/theme-packs/washi/pack.css +479 -0
  350. package/dist/theme-packs-registry/index.d.ts +5 -0
  351. package/dist/theme-packs-registry/index.js +30 -0
  352. package/dist/theme-packs-registry/load-registry.d.ts +23 -0
  353. package/dist/theme-packs-registry/load-registry.js +64 -0
  354. package/dist/theme-packs-registry/meta-schema.d.ts +70 -0
  355. package/dist/theme-packs-registry/meta-schema.js +38 -0
  356. package/dist/theme-packs-registry/resolve-enabled-packs.d.ts +25 -0
  357. package/dist/theme-packs-registry/resolve-enabled-packs.js +43 -0
  358. package/dist/theme-packs-registry/token-manifest.d.ts +19 -0
  359. package/dist/theme-packs-registry/token-manifest.js +57 -0
  360. package/dist/theme-packs-registry/validator.d.ts +35 -0
  361. package/dist/theme-packs-registry/validator.js +284 -0
  362. package/dist/theme-toggle/color-scheme-sync.d.ts +2 -4
  363. package/dist/versions-page/index.d.ts +2 -2
  364. package/dist/versions-page/index.js +8 -8
  365. package/eject/breadcrumb/breadcrumb.tsx +4 -4
  366. package/eject/breadcrumb/find-path.ts +2 -2
  367. package/eject/breadcrumb/index.ts +1 -1
  368. package/eject/breadcrumb/types.ts +0 -6
  369. package/eject/code-group/index.tsx +2 -2
  370. package/eject/doc-history/index.tsx +1 -1
  371. package/eject/doc-pager/index.tsx +1 -1
  372. package/eject/footer/footer.tsx +1 -0
  373. package/eject/header/header.tsx +86 -21
  374. package/eject/header/index.ts +3 -0
  375. package/eject/header/types.ts +39 -1
  376. package/eject/site-tree-nav-island/index.tsx +15 -3
  377. package/eject/site-tree-nav-island/state.ts +9 -0
  378. package/eject/theme-toggle/color-scheme-sync.ts +2 -4
  379. package/package.json +35 -29
  380. package/routes-src/404.tsx +4 -1
  381. package/routes-src/_chrome.tsx +6 -5
  382. package/routes-src/_context.ts +4 -0
  383. package/routes-src/_docs-helpers.ts +9 -29
  384. package/routes-src/_virtual.d.ts +4 -0
  385. package/virtual-modules.d.ts +4 -0
  386. package/zfb-config-shim.d.ts +40 -18
  387. package/dist/integrations/llms-txt/index.d.ts +0 -33
  388. package/dist/theme/color-tweak-export-modal.d.ts +0 -16
  389. package/dist/theme/color-tweak-export-modal.js +0 -138
  390. package/dist/theme/design-token-serde.d.ts +0 -183
  391. package/dist/theme/design-token-serde.js +0 -346
  392. package/dist/theme/design-token-types.d.ts +0 -13
  393. package/dist/theme/design-token-types.js +0 -6
  394. package/dist/theme/iframe-bridge.d.ts +0 -42
  395. package/dist/theme/iframe-bridge.js +0 -72
  396. /package/dist/{integrations → plugins/internal}/claude-resources/escape-for-mdx.d.ts +0 -0
  397. /package/dist/{integrations → plugins/internal}/claude-resources/escape-for-mdx.js +0 -0
  398. /package/dist/{integrations → plugins/internal}/claude-resources/generate.d.ts +0 -0
  399. /package/dist/{integrations → plugins/internal}/claude-resources/generate.js +0 -0
  400. /package/dist/{integrations → plugins/internal}/doc-history/pre-build.js +0 -0
  401. /package/dist/{integrations → plugins/internal}/llms-txt/dev-middleware.d.ts +0 -0
  402. /package/dist/{integrations → plugins/internal}/llms-txt/dev-middleware.js +0 -0
  403. /package/dist/{integrations → plugins/internal}/llms-txt/emit.d.ts +0 -0
  404. /package/dist/{integrations → plugins/internal}/llms-txt/emit.js +0 -0
  405. /package/dist/{integrations → plugins/internal}/llms-txt/generate.d.ts +0 -0
  406. /package/dist/{integrations → plugins/internal}/llms-txt/generate.js +0 -0
  407. /package/dist/{integrations → plugins/internal}/llms-txt/index.js +0 -0
  408. /package/dist/{integrations → plugins/internal}/llms-txt/types.js +0 -0
  409. /package/dist/{integrations → plugins/internal}/search-index/build-emitter.d.ts +0 -0
  410. /package/dist/{integrations → plugins/internal}/search-index/build-emitter.js +0 -0
  411. /package/dist/{integrations → plugins/internal}/search-index/collect.d.ts +0 -0
  412. /package/dist/{integrations → plugins/internal}/search-index/dev-middleware.d.ts +0 -0
  413. /package/dist/{integrations → plugins/internal}/search-index/dev-middleware.js +0 -0
  414. /package/dist/{integrations → plugins/internal}/search-index/index.d.ts +0 -0
  415. /package/dist/{integrations → plugins/internal}/search-index/index.js +0 -0
  416. /package/dist/{integrations → plugins/internal}/search-index/types.d.ts +0 -0
  417. /package/dist/{integrations → plugins/internal}/search-index/types.js +0 -0
package/dist/features.css CHANGED
@@ -20,6 +20,8 @@
20
20
  * --text-{small,caption}
21
21
  * --leading-relaxed
22
22
  * --zd-fg
23
+ * --zd-code-{bg,fg}
24
+ * --zd-syntax-{comment,string,number,keyword,callable,type,name,inserted,deleted}
23
25
  * --zd-sidebar-w
24
26
  * --zd-header-h
25
27
  * --zd-transition-slow
@@ -46,11 +48,11 @@ header[data-header] {
46
48
  position: relative;
47
49
  }
48
50
 
49
- pre[class^="syntect-"].word-wrap {
51
+ :is(pre.hi-root, .tab-panel pre).word-wrap {
50
52
  overflow-x: hidden;
51
53
  }
52
54
 
53
- pre[class^="syntect-"].word-wrap code {
55
+ :is(pre.hi-root, .tab-panel pre).word-wrap code {
54
56
  white-space: pre-wrap;
55
57
  overflow-wrap: anywhere;
56
58
  }
@@ -139,38 +141,49 @@ pre[class^="syntect-"].word-wrap code {
139
141
  * Code-block syntax-highlight token color rule
140
142
  * ======================================== */
141
143
 
142
- /* Code-block token colors come from CSS custom properties in two cases on this
143
- * site, both resolved here via light-dark():
144
- *
145
- * 1. Build-time zfb DUAL-theme syntect (codeHighlight.themeLight/themeDark
146
- * in zfb.config.ts). Emits <pre class="syntect-dual"> whose token spans
147
- * carry style="--shiki-light:#X;--shiki-dark:#Y" (no `color` declaration)
148
- * and whose <pre> carries --shiki-{light,dark}-bg. Zero client JS.
149
- *
150
- * 2. Runtime — the HtmlPreview component's Shiki blocks (<pre class="shiki">),
151
- * which emit the same --shiki-* custom properties.
152
- *
153
- * Both resolve through the `color-scheme` property, which ColorSchemeProvider /
154
- * ThemeToggle toggle per active theme — the same mechanism the palette tokens
155
- * use — so code follows the in-page light/dark switch.
156
- *
157
- * Compatibility: SINGLE-theme syntect (the zfb default, NOT used here) instead
158
- * bakes inline style="color:#hex". This rule deliberately uses NO !important so
159
- * that such an inline `color` — a higher-precedence author declaration — still
160
- * wins, leaving single-theme output untouched. The --shiki-* spans have no
161
- * inline `color`, so the rule applies cleanly. Same logic for background-color
162
- * on the <pre>. See zudolab/zudo-doc#1457.
163
- *
164
- * NOTE: the zdtp design-token panel does NOT highlight code — its Shiki
165
- * integration is a no-op stub upstream. Earlier revisions of this comment
166
- * wrongly attributed the --shiki-* vars to a zdtp client-side re-highlight. */
167
- /* Token color + font-style on the spans (and harmlessly on the <pre>/<code>,
168
- * where the per-token --shiki-* vars are undefined so the declaration is
169
- * ignored). */
144
+ /* zfb's default class-mode stylesheet lives in `@layer zfb-hi`. This adapter
145
+ * stays unlayered, so zudo's semantic design tokens win without specificity or
146
+ * import-order coupling. The indirections deliberately stay as var() values:
147
+ * ColorSchemeProvider and the Design Token Panel can replace any --zd-* source
148
+ * live, and existing highlighted DOM recomputes without a renderer pass. */
149
+ :root {
150
+ --zfb-hi-fg: var(--zd-code-fg);
151
+ --zfb-hi-bg: var(--zd-code-bg);
152
+ --zfb-hi-esc: var(--zd-syntax-string);
153
+ --zfb-hi-op: var(--zd-code-fg);
154
+ --zfb-hi-com: var(--zd-syntax-comment);
155
+ --zfb-hi-str: var(--zd-syntax-string);
156
+ --zfb-hi-num: var(--zd-syntax-number);
157
+ --zfb-hi-const: var(--zd-syntax-number);
158
+ --zfb-hi-kw: var(--zd-syntax-keyword);
159
+ --zfb-hi-fn: var(--zd-syntax-callable);
160
+ --zfb-hi-ty: var(--zd-syntax-type);
161
+ --zfb-hi-ns: var(--zd-syntax-type);
162
+ --zfb-hi-prop: var(--zd-syntax-name);
163
+ --zfb-hi-var: var(--zd-syntax-name);
164
+ --zfb-hi-tag: var(--zd-syntax-name);
165
+ --zfb-hi-attr: var(--zd-syntax-name);
166
+ --zfb-hi-punct: var(--zd-code-fg);
167
+ --zfb-hi-ins: var(--zd-syntax-inserted);
168
+ --zfb-hi-ins-bg: color-mix(
169
+ in srgb,
170
+ var(--zd-syntax-inserted) 15%,
171
+ var(--zd-code-bg)
172
+ );
173
+ --zfb-hi-del: var(--zd-syntax-deleted);
174
+ --zfb-hi-del-bg: color-mix(
175
+ in srgb,
176
+ var(--zd-syntax-deleted) 15%,
177
+ var(--zd-code-bg)
178
+ );
179
+ --zfb-hi-hd: var(--zd-syntax-keyword);
180
+ }
181
+
182
+ /* HTML Preview remains on Shiki until #2742. Its dual-theme variables resolve
183
+ * through color-scheme. These selectors intentionally exclude `.hi-root`,
184
+ * whose colors come from the semantic bridge above. */
170
185
  [data-theme] .shiki,
171
- [data-theme] .shiki span,
172
- [data-theme] pre[class^="syntect-"],
173
- [data-theme] pre[class^="syntect-"] span {
186
+ [data-theme] .shiki span {
174
187
  color: light-dark(var(--shiki-light), var(--shiki-dark));
175
188
  font-style: light-dark(
176
189
  var(--shiki-light-font-style, inherit),
@@ -183,8 +196,7 @@ pre[class^="syntect-"].word-wrap code {
183
196
  * painting them per-span would lay an opaque base background over the
184
197
  * translucent line-/word-highlight backgrounds that sit on the enclosing
185
198
  * .line span (see .line.highlighted below). */
186
- [data-theme] .shiki,
187
- [data-theme] pre[class^="syntect-"] {
199
+ [data-theme] .shiki {
188
200
  background-color: light-dark(var(--shiki-light-bg), var(--shiki-dark-bg));
189
201
  }
190
202
 
@@ -212,13 +224,13 @@ pre[class^="syntect-"].word-wrap code {
212
224
  * zfb emits data-line-highlight="true" on the <span class="line"> element
213
225
  * (verified empirically at next.13). The .highlighted class form is kept for
214
226
  * forward-compat in case a future zfb version emits both. */
215
- pre[class^="syntect-"] .line.highlighted,
216
- pre[class^="syntect-"] [data-line-highlight="true"] {
227
+ pre.hi-root .line.highlighted,
228
+ pre.hi-root [data-line-highlight="true"] {
217
229
  background-color: color-mix(in srgb, var(--color-accent) 15%, transparent);
218
230
  }
219
231
 
220
232
  /* Word highlighting via /word/ meta syntax */
221
- pre[class^="syntect-"] .line .highlighted-word {
233
+ pre.hi-root .line .highlighted-word {
222
234
  background-color: color-mix(in srgb, var(--color-accent) 25%, transparent);
223
235
  border-bottom: 1px solid var(--color-accent);
224
236
  }
@@ -242,7 +254,7 @@ pre[class^="syntect-"] .line .highlighted-word {
242
254
  padding: var(--spacing-vsp-2xs) var(--spacing-hsp-lg);
243
255
  }
244
256
 
245
- .code-block-container pre[class^="syntect-"] {
257
+ .code-block-container pre.hi-root {
246
258
  margin-top: 0 !important;
247
259
  border-top-left-radius: 0;
248
260
  border-top-right-radius: 0;
@@ -253,10 +265,10 @@ pre[class^="syntect-"] .line .highlighted-word {
253
265
  *
254
266
  * zfb's :::code-group emits <CodeGroup tabs={[...]}> with one
255
267
  * <pre data-lang="…">{RAW text}</pre> child per fence. These <pre> elements
256
- * are NOT syntect-highlighted (the Rust pipeline doesn't highlight inside
257
- * code-group fences), so they get no `.syntect-*` class. Apply explicit
258
- * code-block visual treatment via tokens to match the syntect-highlighted
259
- * code blocks surrounding them.
268
+ * are NOT syntax-highlighted (the Rust pipeline doesn't highlight inside
269
+ * code-group fences), so they get no `.hi-root` class. Apply explicit
270
+ * code-block visual treatment via tokens to match the highlighted code blocks
271
+ * surrounding them.
260
272
  * ======================================== */
261
273
 
262
274
  .code-group-panel pre[data-lang] {
@@ -11,6 +11,7 @@ function Footer(props) {
11
11
  "footer",
12
12
  {
13
13
  class: "border-t border-muted bg-surface",
14
+ "data-footer": true,
14
15
  ...persistKey ? { "data-zfb-transition-persist": persistKey } : {},
15
16
  children: /* @__PURE__ */ jsxs("div", { class: "mx-auto max-w-[clamp(50rem,75vw,90rem)] px-hsp-xl py-vsp-xl lg:px-hsp-2xl lg:py-vsp-2xl", children: [
16
17
  hasColumns && /* @__PURE__ */ jsxs("div", { class: "grid grid-cols-1 gap-vsp-lg sm:grid-cols-2 lg:grid-cols-[repeat(auto-fit,minmax(12rem,1fr))]", children: [
@@ -31,6 +31,8 @@ export interface HeadWithDefaultsSettings {
31
31
  siteName: string;
32
32
  colorMode?: ColorSchemeProviderColorMode | null | false;
33
33
  sidebarResizer?: boolean;
34
+ /** Configured theme-pack slug (ADR `docs/adr/theme-packs.md`, #2822). */
35
+ themePack?: string;
34
36
  }
35
37
  /**
36
38
  * Create a `HeadWithDefaults` component from the unified {@link ChromeContext}
@@ -2,6 +2,10 @@ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
2
2
  import { OgTags, TwitterCard } from "../head/index.js";
3
3
  import { SIDEBAR_RESIZER_RESTORE_SCRIPT } from "../sidebar-resizer/index.js";
4
4
  import ColorSchemeProvider from "../theme/color-scheme-provider.js";
5
+ import ThemePackProvider, {
6
+ themePackVersionMap
7
+ } from "../theme/theme-pack-provider.js";
8
+ import { DEFAULT_THEME_PACK_SLUG } from "../theme-pack-switcher/theme-pack-sync.js";
5
9
  import { deriveComposeMetaTitle, deriveColorSchemeGenerators } from "../chrome/derive.js";
6
10
  import { assertChromeContext } from "../chrome/assert-chrome-context.js";
7
11
  function createHeadWithDefaults(ctx) {
@@ -11,6 +15,10 @@ function createHeadWithDefaults(ctx) {
11
15
  const withBase = ctx.withBase;
12
16
  const absoluteUrl = ctx.absoluteUrl;
13
17
  const { generateCssCustomProperties, generateLightDarkCssProperties } = deriveColorSchemeGenerators(ctx);
18
+ const themePackRegistry = ctx.themePackRegistry;
19
+ const themePackEnabled = themePackRegistry !== null ? themePackVersionMap(themePackRegistry) : null;
20
+ const themePackConfigured = settings.themePack ?? DEFAULT_THEME_PACK_SLUG;
21
+ const themePackBase = withBase("/");
14
22
  function HeadWithDefaults({
15
23
  title,
16
24
  description,
@@ -48,6 +56,14 @@ function createHeadWithDefaults(ctx) {
48
56
  }
49
57
  ),
50
58
  /* @__PURE__ */ jsx(ColorSchemeProvider, { cssText, colorMode }),
59
+ themePackEnabled !== null && /* @__PURE__ */ jsx(
60
+ ThemePackProvider,
61
+ {
62
+ configuredSlug: themePackConfigured,
63
+ enabled: themePackEnabled,
64
+ base: themePackBase
65
+ }
66
+ ),
51
67
  settings.sidebarResizer && /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: SIDEBAR_RESIZER_RESTORE_SCRIPT } }),
52
68
  /* @__PURE__ */ jsx("link", { rel: "icon", href: withBase("/favicon.ico"), sizes: "any" }),
53
69
  /* @__PURE__ */ jsx("link", { rel: "icon", type: "image/png", sizes: "32x32", href: withBase("/favicon-32x32.png") }),
@@ -1,7 +1,7 @@
1
1
  /** @jsxRuntime automatic */
2
2
  /** @jsxImportSource preact */
3
3
  import type { ComponentChildren, JSX } from "preact";
4
- import type { HeaderNavItem, HeaderRightItem, Locale } from "./types.js";
4
+ import type { HeaderNavItem, HeaderRightComponentRegistry, HeaderRightItem, Locale } from "./types.js";
5
5
  /**
6
6
  * Boundary helpers the host injects into `<Header>`. These are the URL
7
7
  * builders the legacy header.tsx used to import from `@/utils/base` —
@@ -71,10 +71,9 @@ export interface HeaderProps {
71
71
  /** Replacement for the `<Search />` Astro child. */
72
72
  search?: ComponentChildren;
73
73
  /**
74
- * When provided, emits `data-zfb-transition-persist={persistKey}` on the
74
+ * Emits `data-zfb-transition-persist={persistKey}` on the
75
75
  * `<header>` element so zfb's client-router preserves DOM-node identity
76
- * across same-locale View Transition swaps. Omit to disable persist
77
- * (back-compat default — the header is re-rendered on every swap).
76
+ * across same-locale View Transition swaps.
78
77
  *
79
78
  * **Locale keying**: callers MUST key by locale (e.g. `"header-en"`,
80
79
  * `"header-ja"`). Cross-locale swaps must NOT share the same key; a
@@ -90,7 +89,7 @@ export interface HeaderProps {
90
89
  * for consistency, matching the Astro reference implementation
91
90
  * (zudolab/zudo-doc#1546).
92
91
  */
93
- persistKey?: string;
92
+ persistKey: string;
94
93
  /** Site-name string shown in the logo anchor (host `settings.siteName`). */
95
94
  siteName: string;
96
95
  /** Header-nav items in render order (host `settings.headerNav`). */
@@ -105,6 +104,12 @@ export interface HeaderProps {
105
104
  * wrapper, matching prior behaviour.
106
105
  */
107
106
  headerRightItems: HeaderRightItem[];
107
+ /**
108
+ * Host-callable renderers for project-owned component names. The registry is
109
+ * carried through `chromeBindingsModule`; it is never part of the serialized
110
+ * settings payload. Package built-in names are reserved.
111
+ */
112
+ headerRightComponents?: HeaderRightComponentRegistry;
108
113
  /**
109
114
  * Whether the host has a `colorMode` config. Required because the
110
115
  * `theme-toggle` right-item is two-gated: the filter drops it when
@@ -25,6 +25,7 @@ function Header(props) {
25
25
  siteName,
26
26
  headerNav,
27
27
  headerRightItems,
28
+ headerRightComponents,
28
29
  colorModeEnabled,
29
30
  hasLocales,
30
31
  hasVersions,
@@ -37,6 +38,7 @@ function Header(props) {
37
38
  const pathWithoutBase = urlHelpers.stripBase(currentPath);
38
39
  const matchPath = pathForMatch(pathWithoutBase, lang, i18n.defaultLocale);
39
40
  const activeNavPath = computeActiveNavPath(headerNav, matchPath);
41
+ const rightItemDispatch = createRightItemDispatch(headerRightComponents);
40
42
  return /* @__PURE__ */ jsxs(
41
43
  "header",
42
44
  {
@@ -114,7 +116,8 @@ function Header(props) {
114
116
  search,
115
117
  colorModeEnabled,
116
118
  hasLocales
117
- }
119
+ },
120
+ rightItemDispatch
118
121
  ))
119
122
  }
120
123
  ),
@@ -268,7 +271,14 @@ function SlotWrapper({
268
271
  }) {
269
272
  return /* @__PURE__ */ jsx("div", { class: className, children }, `right-${index}`);
270
273
  }
271
- const RIGHT_ITEM_DISPATCH = {
274
+ const BUILTIN_COMPONENT_NAMES = [
275
+ "theme-toggle",
276
+ "language-switcher",
277
+ "version-switcher",
278
+ "github-link",
279
+ "search"
280
+ ];
281
+ const BASE_RIGHT_ITEM_DISPATCH = {
272
282
  "trigger:design-token-panel": (_item, index) => /* @__PURE__ */ jsx(
273
283
  TriggerButton,
274
284
  {
@@ -385,10 +395,40 @@ const RIGHT_ITEM_DISPATCH = {
385
395
  );
386
396
  }
387
397
  };
388
- function renderRightItem(item, index, ctx) {
398
+ function createRightItemDispatch(hostRegistry) {
399
+ const dispatch = new Map(
400
+ Object.entries(BASE_RIGHT_ITEM_DISPATCH)
401
+ );
402
+ if (hostRegistry === void 0) return dispatch;
403
+ for (const [name, component] of Object.entries(hostRegistry)) {
404
+ if (BUILTIN_COMPONENT_NAMES.includes(name)) {
405
+ throw new Error(
406
+ `[zudo-doc] Duplicate header-right component name "${name}" at chromeBindings.headerRightComponents[${JSON.stringify(name)}]: built-in names are reserved and cannot be shadowed. Remove this registry entry or choose a project-owned name.`
407
+ );
408
+ }
409
+ if (typeof component !== "function") {
410
+ throw new TypeError(
411
+ `[zudo-doc] Invalid header-right component "${name}" at chromeBindings.headerRightComponents[${JSON.stringify(name)}]: expected a callable renderer.`
412
+ );
413
+ }
414
+ dispatch.set(`component:${name}`, (item, index, ctx) => {
415
+ if (item.type !== "component") return null;
416
+ const CustomComponent = component;
417
+ return /* @__PURE__ */ jsx(SlotWrapper, { index, children: /* @__PURE__ */ jsx(CustomComponent, { item, index, ...ctx }) });
418
+ });
419
+ }
420
+ return dispatch;
421
+ }
422
+ function renderRightItem(item, index, ctx, dispatch) {
389
423
  const key = item.type === "trigger" ? `trigger:${item.trigger}` : item.type === "component" ? `component:${item.component}` : item.type;
390
- const handler = RIGHT_ITEM_DISPATCH[key];
391
- return handler ? handler(item, index, ctx) : null;
424
+ const handler = dispatch.get(key);
425
+ if (handler) return handler(item, index, ctx);
426
+ if (item.type === "component") {
427
+ throw new Error(
428
+ `[zudo-doc] Unknown header-right component "${item.component}" at Header.headerRightItems[${index}].component. Register a callable renderer as chromeBindings.headerRightComponents["${item.component}"] through settings.chromeBindingsModule, or use a built-in name: ${BUILTIN_COMPONENT_NAMES.join(", ")}.`
429
+ );
430
+ }
431
+ return null;
392
432
  }
393
433
  export {
394
434
  Header
@@ -9,7 +9,7 @@
9
9
  * so downstream tests / custom layouts can reuse them without rebuilding
10
10
  * the `pathForMatch` / `computeActiveNavPath` regex logic.
11
11
  */
12
- export type { Locale, HeaderNavChildItem, HeaderNavItem, HeaderRightComponentItem, HeaderRightComponentName, HeaderRightHtmlItem, HeaderRightItem, HeaderRightLinkItem, HeaderRightTriggerItem, HeaderRightTriggerName, } from "./types.js";
12
+ export type { Locale, HeaderNavChildItem, HeaderNavItem, HeaderRightBuiltinComponentName, HeaderRightComponentItem, HeaderRightComponentName, HeaderRightComponentProps, HeaderRightComponentRegistry, HeaderRightHtmlItem, HeaderRightItem, HeaderRightLinkItem, HeaderRightTriggerItem, HeaderRightTriggerName, } from "./types.js";
13
13
  export { filterHeaderRightItems, type HeaderRightItemFlags, } from "./right-items.js";
14
14
  export { Header, type HeaderProps } from "./header.js";
15
15
  export { computeActiveNavPath, isNavItemActive, pathForMatch, type NavItemLike, } from "./nav-active.js";
@@ -1,3 +1,4 @@
1
+ import type { ComponentChildren } from "preact";
1
2
  /**
2
3
  * Locale code as seen by the header. Widened from the host's literal
3
4
  * union (`"en" | "ja" | …`) to plain `string` at the v2 boundary so the
@@ -14,12 +15,40 @@ export interface HeaderNavChildItem {
14
15
  export interface HeaderNavItem extends HeaderNavChildItem {
15
16
  children?: HeaderNavChildItem[];
16
17
  }
17
- export type HeaderRightComponentName = "theme-toggle" | "language-switcher" | "version-switcher" | "github-link" | "search";
18
+ export type HeaderRightBuiltinComponentName = "theme-toggle" | "language-switcher" | "version-switcher" | "github-link" | "search";
19
+ /**
20
+ * A serializable name resolved against the package built-ins plus the host's
21
+ * `headerRightComponents` chrome-binding registry. The intersection preserves
22
+ * built-in autocomplete while allowing project-owned names.
23
+ */
24
+ export type HeaderRightComponentName = HeaderRightBuiltinComponentName | (string & {});
18
25
  export type HeaderRightTriggerName = "design-token-panel" | "ai-chat";
19
26
  export interface HeaderRightComponentItem {
20
27
  type: "component";
21
28
  component: HeaderRightComponentName;
22
29
  }
30
+ /**
31
+ * Exact props passed to a host `headerRightComponents` renderer. They mirror
32
+ * the existing header-right dispatch context; no callable enters the
33
+ * serialized {@link HeaderRightComponentItem}.
34
+ */
35
+ export interface HeaderRightComponentProps {
36
+ /** The serialized item that selected this renderer. */
37
+ item: HeaderRightComponentItem;
38
+ /** Zero-based position in the rendered `headerRightItems` array. */
39
+ index: number;
40
+ lang: Locale | undefined;
41
+ githubRepoUrl: string | null;
42
+ githubLabel: string;
43
+ themeToggle: ComponentChildren;
44
+ languageSwitcher: ComponentChildren;
45
+ versionSwitcher: ComponentChildren;
46
+ search: ComponentChildren;
47
+ colorModeEnabled: boolean;
48
+ hasLocales: boolean;
49
+ }
50
+ /** A callable-only host registry keyed by serialized component name. */
51
+ export type HeaderRightComponentRegistry = Record<string, (props: HeaderRightComponentProps) => ComponentChildren>;
23
52
  export interface HeaderRightTriggerItem {
24
53
  type: "trigger";
25
54
  trigger: HeaderRightTriggerName;
@@ -149,6 +149,7 @@ function createHeaderWithDefaults(ctx) {
149
149
  siteName: settings.siteName,
150
150
  headerNav: settings.headerNav,
151
151
  headerRightItems,
152
+ headerRightComponents: ctx.hostBindings.headerRightComponents,
152
153
  colorModeEnabled: Boolean(settings.colorMode),
153
154
  hasLocales: locales.length > 1,
154
155
  hasVersions: Boolean(settings.versions),
@@ -30,6 +30,8 @@ export interface HomePageViewProps {
30
30
  tree: DocNavNode[];
31
31
  /** Ordered category prefixes, passed through to `SiteTreeNav`. */
32
32
  categoryOrder: string[];
33
+ /** Root-category slugs that should start collapsed in `SiteTreeNav`. */
34
+ initiallyCollapsedCategorySlugs?: string[];
33
35
  /** Unique tag count for the current locale — gates the "all tags" section
34
36
  * together with `settings.docTags`. */
35
37
  tagCount: number;
@@ -3,9 +3,9 @@ import { Island } from "@takazudo/zfb";
3
3
  import { DocLayoutWithDefaults } from "../doclayout/index.js";
4
4
  import { SiteTreeNav } from "../site-tree-nav-island/index.js";
5
5
  import { createHeadWithDefaults } from "../head-with-defaults/index.js";
6
- import { createHeaderWithDefaults } from "../header-with-defaults/index.js";
7
- import { createFooterWithDefaults } from "../footer-with-defaults/index.js";
6
+ import { resolveThemePackSsrSlug } from "../theme/theme-pack-provider.js";
8
7
  import { deriveComposeMetaTitle, deriveBodyEndIslands } from "../chrome/derive.js";
8
+ import { derivePrimaryChromeSlots } from "../chrome/primary-slots.js";
9
9
  import { assertChromeContext } from "../chrome/assert-chrome-context.js";
10
10
  import { prepareHomeData } from "./prepare-home-data.js";
11
11
  function createHomePageView(ctx) {
@@ -16,15 +16,19 @@ function createHomePageView(ctx) {
16
16
  const defaultLocale = ctx.defaultLocale;
17
17
  const composeMetaTitle = deriveComposeMetaTitle(ctx);
18
18
  const HeadWithDefaults = createHeadWithDefaults(ctx);
19
- const HeaderWithDefaults = createHeaderWithDefaults(ctx);
20
- const FooterWithDefaults = createFooterWithDefaults(ctx);
19
+ const { Header: HeaderWithDefaults, Footer: FooterWithDefaults } = derivePrimaryChromeSlots(ctx);
21
20
  const BodyEndIslands = deriveBodyEndIslands(ctx);
22
21
  const homeExtras = ctx.hostBindings.homeExtras;
22
+ const dataThemePack = resolveThemePackSsrSlug(
23
+ ctx.themePackRegistry,
24
+ ctx.settings
25
+ );
23
26
  function HomePageView({
24
27
  locale,
25
28
  extras,
26
29
  tree,
27
30
  categoryOrder,
31
+ initiallyCollapsedCategorySlugs,
28
32
  tagCount,
29
33
  wide
30
34
  }) {
@@ -39,6 +43,7 @@ function createHomePageView(ctx) {
39
43
  title: composeMetaTitle(settings.siteName),
40
44
  head: /* @__PURE__ */ jsx(HeadWithDefaults, { title: settings.siteName }),
41
45
  lang: locale,
46
+ dataThemePack,
42
47
  noindex: settings.noindex,
43
48
  hideSidebar: true,
44
49
  hideToc: true,
@@ -99,7 +104,8 @@ function createHomePageView(ctx) {
99
104
  {
100
105
  tree,
101
106
  categoryOrder,
102
- categoryIgnore: ["inbox", "develop"]
107
+ categoryIgnore: ["inbox", "develop"],
108
+ initiallyCollapsedCategorySlugs
103
109
  }
104
110
  )
105
111
  }),
@@ -28,7 +28,7 @@ function prepareHomeData(ctx, locale, options) {
28
28
  const grouped = ctx.groupSatelliteNodes(tree, categoryOrder);
29
29
  const tagCount = ctx.collectTags(
30
30
  navDocs.filter((d) => !d.data.category_no_page),
31
- (id, data) => data.slug ?? ctx.toRouteSlug(id)
31
+ (entrySlug, data) => data.slug ?? ctx.toRouteSlug(entrySlug)
32
32
  ).size;
33
33
  return { tree: grouped, categoryOrder, tagCount };
34
34
  }
@@ -1,12 +1,11 @@
1
1
  /**
2
2
  * Minimal structural interface for a docs entry.
3
3
  *
4
- * Structurally compatible with the host's `DocsEntry` from
5
- * `@/types/docs-entry`. Callers pass their concrete entry arrays and
6
- * TypeScript's structural typing ensures compatibility.
4
+ * Structurally compatible with a current zfb collection entry. Callers pass
5
+ * concrete entry arrays and TypeScript preserves the subtype in the result.
7
6
  */
8
7
  export interface MergeDocsEntry {
9
- id: string;
8
+ slug: string;
10
9
  data: {
11
10
  slug?: string;
12
11
  unlisted?: boolean;
@@ -58,13 +57,10 @@ export interface MergeLocaleDocsOptions<T extends MergeDocsEntry = MergeDocsEntr
58
57
  * Only called when `applyDefaultLocaleOnlyFilter` is true. The host stub
59
58
  * passes `isDefaultLocaleOnlyPath` from `@/utils/base`.
60
59
  *
61
- * When omitted (or when `applyDefaultLocaleOnlyFilter` is false), no path
62
- * filtering is applied.
63
- *
64
- * Example: host passes `(path) => isDefaultLocaleOnlyPath(path)` where
65
- * `isDefaultLocaleOnlyPath` is from `src/utils/base.ts`.
60
+ * Required explicitly so the merge never silently omits the current
61
+ * default-locale-only path contract.
66
62
  */
67
- isDefaultLocaleOnlyPath?: (path: string) => boolean;
63
+ isDefaultLocaleOnlyPath: (path: string) => boolean;
68
64
  }
69
65
  /**
70
66
  * Result of mergeLocaleDocs.
@@ -103,10 +99,9 @@ export interface MergeLocaleDocsResult<T extends MergeDocsEntry = MergeDocsEntry
103
99
  * Locale docs take priority; base docs fill in slugs not covered by the locale
104
100
  * collection. Optionally excludes default-locale-only paths and/or unlisted pages.
105
101
  *
106
- * **Slug keying**: slug identity uses `d.data.slug ?? d.id`. Since `loadDocs`
107
- * already strips the `/index` suffix (via `stripIndexSuffix` in `pages/_data.ts`),
108
- * this key is consistent across all call sites regardless of whether they
109
- * loaded docs via `loadDocs` or `bridgeEntries`.
102
+ * **Slug keying**: slug identity uses the explicit frontmatter override or
103
+ * the canonical route form of the current zfb `entry.slug`. This preserves
104
+ * root `index` and nested index-page behavior without mutating the entries.
110
105
  *
111
106
  * **Array identity**: returns a fresh array on each call — see
112
107
  * {@link MergeLocaleDocsResult} for caching guidance.
@@ -1,3 +1,4 @@
1
+ import { toRouteSlug } from "../slug/index.js";
1
2
  function mergeLocaleDocs(options) {
2
3
  const {
3
4
  baseDocs,
@@ -8,13 +9,14 @@ function mergeLocaleDocs(options) {
8
9
  } = options;
9
10
  const filteredLocale = keepUnlisted ? localeDocs : localeDocs.filter((d) => !d.data.unlisted);
10
11
  const filteredBase = keepUnlisted ? baseDocs : baseDocs.filter((d) => !d.data.unlisted);
11
- const localeSlugSet = new Set(filteredLocale.map((d) => d.data.slug ?? d.id));
12
+ const routeSlug = (entry) => entry.data.slug ?? toRouteSlug(entry.slug);
13
+ const localeSlugSet = new Set(filteredLocale.map(routeSlug));
12
14
  let fallbackDocs = filteredBase.filter(
13
- (d) => !localeSlugSet.has(d.data.slug ?? d.id)
15
+ (entry) => !localeSlugSet.has(routeSlug(entry))
14
16
  );
15
- if (applyDefaultLocaleOnlyFilter && isDefaultLocaleOnlyPath) {
17
+ if (applyDefaultLocaleOnlyFilter) {
16
18
  fallbackDocs = fallbackDocs.filter(
17
- (d) => !isDefaultLocaleOnlyPath(`/docs/${d.data.slug ?? d.id}`)
19
+ (entry) => !isDefaultLocaleOnlyPath("/docs/" + routeSlug(entry))
18
20
  );
19
21
  }
20
22
  return {
@@ -1,5 +1,5 @@
1
1
  import { toChildArray } from "preact";
2
- import { htmlOverrides } from "../content/index.js";
2
+ import { defaultComponents } from "../content/index.js";
3
3
  import { makeAdmonition } from "../content-admonition/index.js";
4
4
  import { CodeGroup } from "../code-group/index.js";
5
5
  import { Tabs } from "../code-syntax/index.js";
@@ -105,7 +105,7 @@ function makeEnlargeableParagraph(imageEnlarge, ContentImg) {
105
105
  }
106
106
  }
107
107
  }
108
- return htmlOverrides.p(props);
108
+ return defaultComponents.p(props);
109
109
  };
110
110
  }
111
111
  function createMdxComponents(options) {
@@ -119,11 +119,11 @@ function createMdxComponents(options) {
119
119
  const CategoryTreeNavBound = (props) => navData.CategoryTreeNav({ ...props, lang: locale });
120
120
  const SiteTreeNavBound = (props) => navData.SiteTreeNav({ ...props, lang: locale });
121
121
  return {
122
- ...htmlOverrides,
122
+ ...defaultComponents,
123
123
  // img override: rewrites root-relative src to include settings.base.
124
124
  img: ContentImg,
125
125
  // p override: wraps block-level images in <figure class="zd-enlargeable">.
126
- // Must come AFTER ...htmlOverrides to override ContentParagraph.
126
+ // Must come AFTER ...defaultComponents to override ContentParagraph.
127
127
  p: EnlargeableParagraph,
128
128
  // Admonitions — real typed Preact components emitting the
129
129
  // `.admonition` / `data-admonition` structure the design-system CSS
@@ -1,3 +1,4 @@
1
1
  import type { ZfbPlugin } from "@takazudo/zfb/plugins";
2
+ export { runClaudeResourcesPreStep } from "./internal/claude-resources/index.js";
2
3
  declare const plugin: ZfbPlugin;
3
4
  export default plugin;
@@ -1,4 +1,5 @@
1
- import { runClaudeResourcesPreStep } from "../integrations/claude-resources/index.js";
1
+ import { runClaudeResourcesPreStep } from "./internal/claude-resources/index.js";
2
+ import { runClaudeResourcesPreStep as runClaudeResourcesPreStep2 } from "./internal/claude-resources/index.js";
2
3
  const PLUGIN_NAME = "@takazudo/zudo-doc-claude-resources";
3
4
  const plugin = {
4
5
  name: PLUGIN_NAME,
@@ -25,5 +26,6 @@ const plugin = {
25
26
  };
26
27
  var claude_resources_default = plugin;
27
28
  export {
28
- claude_resources_default as default
29
+ claude_resources_default as default,
30
+ runClaudeResourcesPreStep2 as runClaudeResourcesPreStep
29
31
  };
@@ -2,7 +2,7 @@ import {
2
2
  runDocHistoryMetaStep,
3
3
  runDocHistoryPostBuild,
4
4
  createDocHistoryDevMiddleware
5
- } from "../integrations/doc-history/index.js";
5
+ } from "./internal/doc-history/index.js";
6
6
  import { connectToZfbHandler } from "./connect-adapter.js";
7
7
  import { getBasePrefix } from "./plugin-utils.js";
8
8
  const plugin = {
@@ -1,10 +1,5 @@
1
1
  import { generateClaudeResourcesDocs, type ClaudeResourcesConfig } from "./generate.js";
2
- export interface ZfbPluginConfig {
3
- name: string;
4
- options?: Record<string, unknown>;
5
- }
6
- export declare const CLAUDE_RESOURCES_PLUGIN_NAME = "@takazudo/zudo-doc-claude-resources";
7
- /** Options accepted by both the plugin entry and the imperative runner. */
2
+ /** Options accepted by the plugin's generator runner. */
8
3
  export interface ClaudeResourcesPluginOptions {
9
4
  /**
10
5
  * Path to the project's `.claude/` directory holding `commands/`,
@@ -40,16 +35,6 @@ export interface ClaudeResourcesPluginOptions {
40
35
  */
41
36
  docsDir?: string;
42
37
  }
43
- /**
44
- * Declarative plugin entry for `zfb.config.ts`. Returns the
45
- * `{ name, options }` shape that zfb's plugins array consumes.
46
- *
47
- * v0 note: zfb does not yet invoke plugin lifecycles, so registering the
48
- * plugin alone does not run generation today. Pair it with a call to
49
- * `runClaudeResourcesPreStep` from a `prebuild`-style script until the
50
- * lifecycle hook lands. The plugin entry itself is forward-compatible.
51
- */
52
- export declare function claudeResourcesPlugin(options: ClaudeResourcesPluginOptions): ZfbPluginConfig;
53
38
  /**
54
39
  * Imperative pre-step runner. Resolves relative paths against
55
40
  * `projectRoot` (defaults to `process.cwd()`) and invokes the underlying