@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
@@ -0,0 +1,141 @@
1
+ import {
2
+ ConfigSyntaxError,
3
+ findMatchingBrace,
4
+ findZudoDocCallParens,
5
+ isPlainStringLiteralSpan,
6
+ skipWhitespaceAndComments,
7
+ splitTopLevelMembers
8
+ } from "./config-scanner.js";
9
+ function manualHint(slug) {
10
+ return `Add the field manually inside your zudoDoc({ ... }) call: themePack: ${JSON.stringify(slug)}`;
11
+ }
12
+ function refuse(reason, slug) {
13
+ return { ok: false, reason: `${reason} ${manualHint(slug)}` };
14
+ }
15
+ function detectIndent(source, members) {
16
+ const ref = members[0];
17
+ const refPos = ref ? ref.keyStart ?? ref.memberStart : null;
18
+ if (refPos !== null && refPos !== void 0) {
19
+ const newlineIdx = source.lastIndexOf("\n", refPos);
20
+ const lineStart = newlineIdx === -1 ? 0 : newlineIdx + 1;
21
+ const line = source.slice(lineStart, refPos);
22
+ if (/^[ \t]*$/.test(line) && line.length > 0) return line;
23
+ }
24
+ return " ";
25
+ }
26
+ function applyThemePackToConfigSource(source, slug) {
27
+ let calls;
28
+ try {
29
+ calls = findZudoDocCallParens(source);
30
+ } catch (err) {
31
+ return refuse(
32
+ `could not parse zfb.config.ts (${err.message}).`,
33
+ slug
34
+ );
35
+ }
36
+ if (calls.length === 0) {
37
+ return refuse(
38
+ "no zudoDoc(...) call found in zfb.config.ts. This CLI only rewrites the canonical generated shape: export default defineConfig(zudoDoc({ ... })).",
39
+ slug
40
+ );
41
+ }
42
+ if (calls.length > 1) {
43
+ return refuse(
44
+ `found ${calls.length} zudoDoc(...) call sites in zfb.config.ts \u2014 cannot safely determine which one to rewrite.`,
45
+ slug
46
+ );
47
+ }
48
+ const openParenIdx = calls[0];
49
+ let braceOpenIdx;
50
+ let braceCloseIdx;
51
+ let afterBrace;
52
+ try {
53
+ braceOpenIdx = skipWhitespaceAndComments(source, openParenIdx + 1);
54
+ if (source[braceOpenIdx] !== "{") {
55
+ return refuse(
56
+ "zudoDoc(...) is not called with a plain object literal (found a computed or non-literal argument instead of zudoDoc({ ... })). This CLI only rewrites the canonical generated shape.",
57
+ slug
58
+ );
59
+ }
60
+ braceCloseIdx = findMatchingBrace(source, braceOpenIdx);
61
+ afterBrace = skipWhitespaceAndComments(source, braceCloseIdx + 1);
62
+ } catch (err) {
63
+ return refuse(
64
+ `could not parse zfb.config.ts (${err.message}).`,
65
+ slug
66
+ );
67
+ }
68
+ const afterOptionalComma = source[afterBrace] === "," ? skipWhitespaceAndComments(source, afterBrace + 1) : afterBrace;
69
+ if (source[afterOptionalComma] !== ")") {
70
+ return refuse(
71
+ "zudoDoc(...) is called with more than one argument \u2014 not the canonical single-object-literal shape.",
72
+ slug
73
+ );
74
+ }
75
+ let members;
76
+ try {
77
+ members = splitTopLevelMembers(source, braceOpenIdx + 1, braceCloseIdx);
78
+ } catch (err) {
79
+ return refuse(
80
+ `could not parse zfb.config.ts (${err.message}).`,
81
+ slug
82
+ );
83
+ }
84
+ const spread = members.find((m) => m.isSpread);
85
+ if (spread) {
86
+ return refuse(
87
+ "zudoDoc({ ...spread }) uses a spread argument \u2014 not the canonical generated shape. This CLI only rewrites a literal, hand-editable field list.",
88
+ slug
89
+ );
90
+ }
91
+ const newValueLiteral = JSON.stringify(slug);
92
+ const themePackMembers = members.filter((m) => m.key === "themePack");
93
+ if (themePackMembers.length > 1) {
94
+ return refuse(
95
+ 'zfb.config.ts declares "themePack" more than once inside zudoDoc({ ... }). This CLI only rewrites a single canonical field; remove the duplicate and re-run.',
96
+ slug
97
+ );
98
+ }
99
+ const themePackMember = themePackMembers[0];
100
+ if (themePackMember) {
101
+ if (themePackMember.valueStart === null || themePackMember.valueEnd === null) {
102
+ return refuse(
103
+ 'the existing "themePack" field in zfb.config.ts is not a simple `key: value` property this CLI understands.',
104
+ slug
105
+ );
106
+ }
107
+ if (!isPlainStringLiteralSpan(source, themePackMember.valueStart, themePackMember.valueEnd)) {
108
+ return refuse(
109
+ `the existing "themePack" field's value is not a plain string literal \u2014 cannot safely rewrite it without risking corruption.`,
110
+ slug
111
+ );
112
+ }
113
+ const newSource2 = source.slice(0, themePackMember.valueStart) + newValueLiteral + source.slice(themePackMember.valueEnd);
114
+ return { ok: true, source: newSource2, changed: newSource2 !== source, mode: "replaced" };
115
+ }
116
+ const colorModeMember = members.find((m) => m.key === "colorMode");
117
+ const colorSchemeMember = members.find((m) => m.key === "colorScheme");
118
+ const anchor = colorModeMember ?? colorSchemeMember ?? null;
119
+ const indent = detectIndent(source, members);
120
+ if (anchor) {
121
+ const insertAt2 = anchor.commaIndex !== null ? anchor.commaIndex + 1 : anchor.memberEnd;
122
+ const prefix = anchor.commaIndex !== null ? "" : ",";
123
+ const insertText2 = `${prefix}
124
+ ${indent}themePack: ${newValueLiteral},`;
125
+ const newSource2 = source.slice(0, insertAt2) + insertText2 + source.slice(insertAt2);
126
+ return {
127
+ ok: true,
128
+ source: newSource2,
129
+ changed: true,
130
+ mode: colorModeMember ? "inserted-after-color-mode" : "inserted-after-color-scheme"
131
+ };
132
+ }
133
+ const insertAt = braceOpenIdx + 1;
134
+ const insertText = `
135
+ ${indent}themePack: ${newValueLiteral},`;
136
+ const newSource = source.slice(0, insertAt) + insertText + source.slice(insertAt);
137
+ return { ok: true, source: newSource, changed: true, mode: "inserted-first" };
138
+ }
139
+ export {
140
+ applyThemePackToConfigSource
141
+ };
@@ -0,0 +1,63 @@
1
+ /** Thrown when the scanner hits config-file syntax it cannot safely reason
2
+ * about. Callers MUST catch this and refuse cleanly (never proceed with a
3
+ * partial/guessed rewrite). */
4
+ export declare class ConfigSyntaxError extends Error {
5
+ constructor(message: string);
6
+ }
7
+ /** Skip a single/double-quoted string literal starting at `i`. Throws on an
8
+ * unterminated string (including one broken by a literal, unescaped
9
+ * newline — invalid in JS/TS for these quote kinds). */
10
+ export declare function skipStringLiteral(source: string, i: number): number;
11
+ /** Skip whitespace and comments starting at `i`, stopping at the first
12
+ * "real" character (or `source.length`). */
13
+ export declare function skipWhitespaceAndComments(source: string, i: number): number;
14
+ /**
15
+ * Find every top-level `zudoDoc(` call site (outside strings/comments),
16
+ * returning the index of each call's opening `(`. An identifier match
17
+ * requires an exact `zudoDoc` token (not a substring of a longer
18
+ * identifier) immediately followed — modulo whitespace/comments — by `(`.
19
+ */
20
+ export declare function findZudoDocCallParens(source: string): number[];
21
+ /**
22
+ * Find the index of the `}` matching the `{` at `openIndex`, skipping
23
+ * strings/comments/template literals so their content can never be mistaken
24
+ * for structure. Throws `ConfigSyntaxError` if unterminated.
25
+ */
26
+ export declare function findMatchingBrace(source: string, openIndex: number): number;
27
+ /** One top-level member of an object literal body (a `key: value` property
28
+ * or a `...spread` element). `key`/`valueStart`/`valueEnd` are `null` when
29
+ * the member's shape is not a simple `key: value` this scanner recognizes
30
+ * (e.g. a computed key, shorthand property) — such members are safe to
31
+ * leave untouched but cannot be used as a rewrite target or anchor. */
32
+ export interface TopLevelMember {
33
+ /** Start of this member's raw span (right after the previous comma, or
34
+ * the object body's start). */
35
+ memberStart: number;
36
+ /** End of this member's raw span, trimmed of trailing whitespace (right
37
+ * before its separating comma, or the object body's end). */
38
+ memberEnd: number;
39
+ /** Index of the comma separating this member from the next, or `null` if
40
+ * this is the last member and has no trailing comma. */
41
+ commaIndex: number | null;
42
+ isSpread: boolean;
43
+ key: string | null;
44
+ keyStart: number | null;
45
+ keyEnd: number | null;
46
+ colonIndex: number | null;
47
+ /** Trimmed start/end of the value expression (after the colon). */
48
+ valueStart: number | null;
49
+ valueEnd: number | null;
50
+ }
51
+ /**
52
+ * Split an object literal's body (the span strictly between its `{`/`}`)
53
+ * into top-level members — commas nested inside arrays/objects/calls do not
54
+ * split. Throws `ConfigSyntaxError` on unbalanced brackets or unsupported
55
+ * syntax within the body.
56
+ */
57
+ export declare function splitTopLevelMembers(source: string, bodyStart: number, bodyEnd: number): TopLevelMember[];
58
+ /** True iff `source[start..end)` is EXACTLY one single/double-quoted string
59
+ * literal (no surrounding characters). Used to confirm a field's existing
60
+ * value is safe to replace wholesale. */
61
+ export declare function isPlainStringLiteralSpan(source: string, start: number, end: number): boolean;
62
+ /** Unquote a `"..."`/`'...'` string literal span into its raw string value. */
63
+ export declare function unquoteStringLiteralSpan(source: string, start: number, end: number): string;
@@ -0,0 +1,288 @@
1
+ class ConfigSyntaxError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "ConfigSyntaxError";
5
+ }
6
+ }
7
+ const IDENT_START_RE = /[A-Za-z_$]/;
8
+ const IDENT_PART_RE = /[A-Za-z0-9_$]/;
9
+ function isWhitespace(ch) {
10
+ return ch === " " || ch === " " || ch === "\n" || ch === "\r";
11
+ }
12
+ function skipLineComment(source, i) {
13
+ let j = i + 2;
14
+ while (j < source.length && source[j] !== "\n") j++;
15
+ return j;
16
+ }
17
+ function skipBlockComment(source, i) {
18
+ const end = source.indexOf("*/", i + 2);
19
+ if (end === -1) {
20
+ throw new ConfigSyntaxError("unterminated block comment (/* ... */) in zfb.config.ts");
21
+ }
22
+ return end + 2;
23
+ }
24
+ function skipStringLiteral(source, i) {
25
+ const quote = source[i];
26
+ let j = i + 1;
27
+ while (j < source.length) {
28
+ const c = source[j];
29
+ if (c === "\\") {
30
+ j += 2;
31
+ continue;
32
+ }
33
+ if (c === quote) return j + 1;
34
+ if (c === "\n") break;
35
+ j++;
36
+ }
37
+ throw new ConfigSyntaxError(`unterminated string literal (${quote}...) in zfb.config.ts`);
38
+ }
39
+ function skipSimpleTemplateLiteral(source, i) {
40
+ let j = i + 1;
41
+ while (j < source.length) {
42
+ const c = source[j];
43
+ if (c === "\\") {
44
+ j += 2;
45
+ continue;
46
+ }
47
+ if (c === "`") return j + 1;
48
+ if (c === "$" && source[j + 1] === "{") {
49
+ throw new ConfigSyntaxError(
50
+ "template literal interpolation (`${...}`) in zfb.config.ts is not supported by the theme CLI's config parser"
51
+ );
52
+ }
53
+ j++;
54
+ }
55
+ throw new ConfigSyntaxError("unterminated template literal (`...`) in zfb.config.ts");
56
+ }
57
+ function trySkipToken(source, i) {
58
+ const c = source[i];
59
+ const c2 = source[i + 1];
60
+ if (c === "/" && c2 === "/") return skipLineComment(source, i);
61
+ if (c === "/" && c2 === "*") return skipBlockComment(source, i);
62
+ if (c === '"' || c === "'") return skipStringLiteral(source, i);
63
+ if (c === "`") return skipSimpleTemplateLiteral(source, i);
64
+ return null;
65
+ }
66
+ function skipWhitespaceAndComments(source, i) {
67
+ let pos = i;
68
+ while (pos < source.length) {
69
+ const c = source[pos];
70
+ if (isWhitespace(c)) {
71
+ pos++;
72
+ continue;
73
+ }
74
+ if (c === "/" && source[pos + 1] === "/") {
75
+ pos = skipLineComment(source, pos);
76
+ continue;
77
+ }
78
+ if (c === "/" && source[pos + 1] === "*") {
79
+ pos = skipBlockComment(source, pos);
80
+ continue;
81
+ }
82
+ break;
83
+ }
84
+ return pos;
85
+ }
86
+ function hasSignificantContent(source, start, end) {
87
+ return skipWhitespaceAndComments(source, start) < end;
88
+ }
89
+ function findZudoDocCallParens(source) {
90
+ const result = [];
91
+ let i = 0;
92
+ while (i < source.length) {
93
+ const skip = trySkipToken(source, i);
94
+ if (skip !== null) {
95
+ i = skip;
96
+ continue;
97
+ }
98
+ const c = source[i];
99
+ if (IDENT_START_RE.test(c)) {
100
+ let j = i + 1;
101
+ while (j < source.length && IDENT_PART_RE.test(source[j])) j++;
102
+ if (source.slice(i, j) === "zudoDoc") {
103
+ const parenIdx = skipWhitespaceAndComments(source, j);
104
+ if (source[parenIdx] === "(") result.push(parenIdx);
105
+ }
106
+ i = j;
107
+ continue;
108
+ }
109
+ i++;
110
+ }
111
+ return result;
112
+ }
113
+ function findMatchingBrace(source, openIndex) {
114
+ if (source[openIndex] !== "{") {
115
+ throw new ConfigSyntaxError("internal error: findMatchingBrace called at a non-'{' position");
116
+ }
117
+ let depth = 1;
118
+ let i = openIndex + 1;
119
+ while (i < source.length) {
120
+ const skip = trySkipToken(source, i);
121
+ if (skip !== null) {
122
+ i = skip;
123
+ continue;
124
+ }
125
+ const c = source[i];
126
+ if (c === "{") {
127
+ depth++;
128
+ } else if (c === "}") {
129
+ depth--;
130
+ if (depth === 0) return i;
131
+ }
132
+ i++;
133
+ }
134
+ throw new ConfigSyntaxError(
135
+ 'unterminated object literal \u2014 missing closing "}" for the zudoDoc({...}) call'
136
+ );
137
+ }
138
+ function unquoteSimple(literal) {
139
+ if (literal.length < 2) return literal;
140
+ const quote = literal[0];
141
+ if (quote !== '"' && quote !== "'") return literal;
142
+ const inner = literal.slice(1, -1);
143
+ let out = "";
144
+ for (let i = 0; i < inner.length; i++) {
145
+ const c = inner[i];
146
+ if (c === "\\") {
147
+ const next = inner[i + 1];
148
+ switch (next) {
149
+ case "n":
150
+ out += "\n";
151
+ break;
152
+ case "t":
153
+ out += " ";
154
+ break;
155
+ case "r":
156
+ out += "\r";
157
+ break;
158
+ default:
159
+ out += next ?? "";
160
+ }
161
+ i++;
162
+ continue;
163
+ }
164
+ out += c;
165
+ }
166
+ return out;
167
+ }
168
+ function parseMember(source, rawStart, rawEnd, commaIndex) {
169
+ const base = {
170
+ memberStart: rawStart,
171
+ commaIndex,
172
+ isSpread: false,
173
+ key: null,
174
+ keyStart: null,
175
+ keyEnd: null,
176
+ colonIndex: null,
177
+ valueStart: null,
178
+ valueEnd: null
179
+ };
180
+ let trimmedEnd = rawEnd;
181
+ while (trimmedEnd > rawStart && isWhitespace(source[trimmedEnd - 1])) trimmedEnd--;
182
+ const i0 = skipWhitespaceAndComments(source, rawStart);
183
+ if (i0 >= trimmedEnd) {
184
+ return { ...base, memberEnd: trimmedEnd };
185
+ }
186
+ if (source.slice(i0, i0 + 3) === "...") {
187
+ return { ...base, memberEnd: trimmedEnd, isSpread: true };
188
+ }
189
+ const c = source[i0];
190
+ let key = null;
191
+ let keyStart = null;
192
+ let keyEnd = null;
193
+ let i = i0;
194
+ if (c === '"' || c === "'") {
195
+ keyStart = i;
196
+ keyEnd = skipStringLiteral(source, i);
197
+ key = unquoteSimple(source.slice(keyStart, keyEnd));
198
+ i = keyEnd;
199
+ } else if (IDENT_START_RE.test(c)) {
200
+ keyStart = i;
201
+ let j = i + 1;
202
+ while (j < trimmedEnd && IDENT_PART_RE.test(source[j])) j++;
203
+ keyEnd = j;
204
+ key = source.slice(keyStart, keyEnd);
205
+ i = j;
206
+ } else {
207
+ return { ...base, memberEnd: trimmedEnd };
208
+ }
209
+ const afterKey = skipWhitespaceAndComments(source, i);
210
+ if (source[afterKey] !== ":") {
211
+ return { ...base, memberEnd: trimmedEnd, key, keyStart, keyEnd };
212
+ }
213
+ const colonIndex = afterKey;
214
+ const valueStart = skipWhitespaceAndComments(source, colonIndex + 1);
215
+ return {
216
+ ...base,
217
+ memberEnd: trimmedEnd,
218
+ key,
219
+ keyStart,
220
+ keyEnd,
221
+ colonIndex,
222
+ valueStart,
223
+ valueEnd: trimmedEnd
224
+ };
225
+ }
226
+ function splitTopLevelMembers(source, bodyStart, bodyEnd) {
227
+ const members = [];
228
+ let memberStart = bodyStart;
229
+ let depth = 0;
230
+ let i = bodyStart;
231
+ while (i < bodyEnd) {
232
+ const skip = trySkipToken(source, i);
233
+ if (skip !== null) {
234
+ i = Math.min(skip, bodyEnd);
235
+ continue;
236
+ }
237
+ const c = source[i];
238
+ if (c === "{" || c === "[" || c === "(") {
239
+ depth++;
240
+ i++;
241
+ continue;
242
+ }
243
+ if (c === "}" || c === "]" || c === ")") {
244
+ depth--;
245
+ if (depth < 0) {
246
+ throw new ConfigSyntaxError(
247
+ "unbalanced brackets while scanning the zudoDoc({...}) object body"
248
+ );
249
+ }
250
+ i++;
251
+ continue;
252
+ }
253
+ if (c === "," && depth === 0) {
254
+ members.push(parseMember(source, memberStart, i, i));
255
+ i++;
256
+ memberStart = i;
257
+ continue;
258
+ }
259
+ i++;
260
+ }
261
+ if (hasSignificantContent(source, memberStart, bodyEnd)) {
262
+ members.push(parseMember(source, memberStart, bodyEnd, null));
263
+ }
264
+ return members;
265
+ }
266
+ function isPlainStringLiteralSpan(source, start, end) {
267
+ if (start >= end) return false;
268
+ const quote = source[start];
269
+ if (quote !== '"' && quote !== "'") return false;
270
+ try {
271
+ return skipStringLiteral(source, start) === end;
272
+ } catch {
273
+ return false;
274
+ }
275
+ }
276
+ function unquoteStringLiteralSpan(source, start, end) {
277
+ return unquoteSimple(source.slice(start, end));
278
+ }
279
+ export {
280
+ ConfigSyntaxError,
281
+ findMatchingBrace,
282
+ findZudoDocCallParens,
283
+ isPlainStringLiteralSpan,
284
+ skipStringLiteral,
285
+ skipWhitespaceAndComments,
286
+ splitTopLevelMembers,
287
+ unquoteStringLiteralSpan
288
+ };
@@ -0,0 +1,7 @@
1
+ export { listThemePacks, formatThemeList, type ThemeListRow, type ThemeListResult, type ListThemePacksOptions, } from "./list.js";
2
+ export { applyThemePack, type ApplyThemePackOptions, type ApplyThemePackResult } from "./apply.js";
3
+ export { loadInstalledThemePackCatalog, type LoadInstalledThemePackCatalogOptions, type ThemePackRegistry, type ThemePackRegistryEntry, } from "./registry.js";
4
+ export { detectActiveThemePack, resolveZfbConfigPath, ZFB_CONFIG_FILENAME, type DetectActiveThemePackResult, } from "./config-io.js";
5
+ export { applyThemePackToConfigSource, type ApplyThemePackToSourceOk, type ApplyThemePackToSourceRefusal, type ApplyThemePackToSourceResult, } from "./config-rewriter.js";
6
+ export { readThemePackProvenance, writeThemePackProvenance, ZUDO_DOC_JSON_FILENAME, THEME_PACK_PROVENANCE_SCHEMA_VERSION, type ThemePackProvenance, } from "./provenance.js";
7
+ export { ConfigSyntaxError } from "./config-scanner.js";
@@ -0,0 +1,38 @@
1
+ import {
2
+ listThemePacks,
3
+ formatThemeList
4
+ } from "./list.js";
5
+ import { applyThemePack } from "./apply.js";
6
+ import {
7
+ loadInstalledThemePackCatalog
8
+ } from "./registry.js";
9
+ import {
10
+ detectActiveThemePack,
11
+ resolveZfbConfigPath,
12
+ ZFB_CONFIG_FILENAME
13
+ } from "./config-io.js";
14
+ import {
15
+ applyThemePackToConfigSource
16
+ } from "./config-rewriter.js";
17
+ import {
18
+ readThemePackProvenance,
19
+ writeThemePackProvenance,
20
+ ZUDO_DOC_JSON_FILENAME,
21
+ THEME_PACK_PROVENANCE_SCHEMA_VERSION
22
+ } from "./provenance.js";
23
+ import { ConfigSyntaxError } from "./config-scanner.js";
24
+ export {
25
+ ConfigSyntaxError,
26
+ THEME_PACK_PROVENANCE_SCHEMA_VERSION,
27
+ ZFB_CONFIG_FILENAME,
28
+ ZUDO_DOC_JSON_FILENAME,
29
+ applyThemePack,
30
+ applyThemePackToConfigSource,
31
+ detectActiveThemePack,
32
+ formatThemeList,
33
+ listThemePacks,
34
+ loadInstalledThemePackCatalog,
35
+ readThemePackProvenance,
36
+ resolveZfbConfigPath,
37
+ writeThemePackProvenance
38
+ };
@@ -0,0 +1,27 @@
1
+ import { type LoadInstalledThemePackCatalogOptions } from "./registry.js";
2
+ export interface ThemeListRow {
3
+ slug: string;
4
+ name: string;
5
+ mode: "light" | "dark";
6
+ version: string;
7
+ description: string;
8
+ active: boolean;
9
+ }
10
+ export interface ThemeListResult {
11
+ rows: ThemeListRow[];
12
+ activeSlug: string;
13
+ /** `false` when the active slug is a fallback (zfb.config.ts missing or
14
+ * not confidently parseable) rather than a confirmed reading. */
15
+ activeDetected: boolean;
16
+ }
17
+ export interface ListThemePacksOptions extends LoadInstalledThemePackCatalogOptions {
18
+ cwd?: string;
19
+ }
20
+ /** Resolve the installed catalog + the project's active pack slug. Pure
21
+ * data — see `formatThemeList` for the printable rendering. */
22
+ export declare function listThemePacks(options?: ListThemePacksOptions): Promise<ThemeListResult>;
23
+ /** Render a `ListThemePacksOptions` result as a human-readable table for
24
+ * the terminal. Kept separate from `listThemePacks` so tests can assert on
25
+ * structured data without scraping ANSI-colored strings, and separately on
26
+ * this formatter's plain-text content. */
27
+ export declare function formatThemeList(result: ThemeListResult): string;
@@ -0,0 +1,64 @@
1
+ import pc from "picocolors";
2
+ import { detectActiveThemePack } from "./config-io.js";
3
+ import {
4
+ loadInstalledThemePackCatalog
5
+ } from "./registry.js";
6
+ async function listThemePacks(options = {}) {
7
+ const cwd = options.cwd ?? process.cwd();
8
+ const catalog = loadInstalledThemePackCatalog(options);
9
+ const { slug: activeSlug, detected: activeDetected } = await detectActiveThemePack(cwd);
10
+ const rows = catalog.map((entry) => ({
11
+ slug: entry.slug,
12
+ name: entry.meta.name,
13
+ mode: entry.meta.mode,
14
+ version: entry.meta.version,
15
+ description: entry.meta.description,
16
+ active: entry.slug === activeSlug
17
+ }));
18
+ return { rows, activeSlug, activeDetected };
19
+ }
20
+ function padEnd(text, width) {
21
+ return text.length >= width ? text : text + " ".repeat(width - text.length);
22
+ }
23
+ function formatThemeList(result) {
24
+ const { rows, activeSlug, activeDetected } = result;
25
+ if (rows.length === 0) {
26
+ return pc.yellow("No theme packs found in the installed @takazudo/zudo-doc package.");
27
+ }
28
+ const slugWidth = Math.max(4, ...rows.map((r) => r.slug.length));
29
+ const nameWidth = Math.max(4, ...rows.map((r) => r.name.length));
30
+ const modeWidth = Math.max(4, ...rows.map((r) => r.mode.length));
31
+ const versionWidth = Math.max(7, ...rows.map((r) => r.version.length));
32
+ const lines = [];
33
+ lines.push(pc.bold(`Installed theme packs (${rows.length}):`));
34
+ lines.push("");
35
+ lines.push(
36
+ " " + pc.dim(
37
+ `${padEnd("SLUG", slugWidth)} ${padEnd("NAME", nameWidth)} ${padEnd("MODE", modeWidth)} ${padEnd("VERSION", versionWidth)} DESCRIPTION`
38
+ )
39
+ );
40
+ for (const row of rows) {
41
+ const marker = row.active ? pc.green("*") : " ";
42
+ const activeSuffix = row.active ? pc.green(" (active)") : "";
43
+ lines.push(
44
+ `${marker} ${padEnd(row.slug, slugWidth)} ${padEnd(row.name, nameWidth)} ${padEnd(row.mode, modeWidth)} ${padEnd(row.version, versionWidth)} ${row.description}${activeSuffix}`
45
+ );
46
+ }
47
+ lines.push("");
48
+ if (activeDetected) {
49
+ lines.push(`Active theme pack: ${pc.bold(activeSlug)}`);
50
+ } else {
51
+ lines.push(
52
+ pc.dim(
53
+ `Active theme pack: ${activeSlug} (default \u2014 no zfb.config.ts "themePack" field found or readable)`
54
+ )
55
+ );
56
+ }
57
+ lines.push("");
58
+ lines.push(pc.dim("Run `zudo-doc theme apply <slug>` to switch."));
59
+ return lines.join("\n");
60
+ }
61
+ export {
62
+ formatThemeList,
63
+ listThemePacks
64
+ };
@@ -0,0 +1,17 @@
1
+ export declare const ZUDO_DOC_JSON_FILENAME = ".zudo-doc.json";
2
+ export declare const THEME_PACK_PROVENANCE_SCHEMA_VERSION: 1;
3
+ export interface ThemePackProvenance {
4
+ schemaVersion: typeof THEME_PACK_PROVENANCE_SCHEMA_VERSION;
5
+ slug: string;
6
+ packVersion: string;
7
+ /** ISO 8601 timestamp of the apply that produced this record. */
8
+ appliedAt: string;
9
+ }
10
+ /** Merge-write the `themePack` provenance key, preserving every other
11
+ * top-level key already in `.zudo-doc.json` (notably `ejected` /
12
+ * `packageVersion`, written by `zudo-doc eject`). Creates the file if
13
+ * absent. */
14
+ export declare function writeThemePackProvenance(cwd: string, entry: ThemePackProvenance): Promise<void>;
15
+ /** Read back the current `themePack` provenance entry, or `null` if absent
16
+ * / the file doesn't exist / the key is malformed. */
17
+ export declare function readThemePackProvenance(cwd: string): Promise<ThemePackProvenance | null>;
@@ -0,0 +1,35 @@
1
+ import fs from "fs-extra";
2
+ import path from "node:path";
3
+ const ZUDO_DOC_JSON_FILENAME = ".zudo-doc.json";
4
+ const THEME_PACK_PROVENANCE_SCHEMA_VERSION = 1;
5
+ function provenancePath(cwd) {
6
+ return path.join(cwd, ZUDO_DOC_JSON_FILENAME);
7
+ }
8
+ async function readExisting(cwd) {
9
+ const filePath = provenancePath(cwd);
10
+ if (!await fs.pathExists(filePath)) return {};
11
+ try {
12
+ return await fs.readJson(filePath);
13
+ } catch {
14
+ return {};
15
+ }
16
+ }
17
+ async function writeThemePackProvenance(cwd, entry) {
18
+ const existing = await readExisting(cwd);
19
+ existing.themePack = entry;
20
+ await fs.writeJson(provenancePath(cwd), existing, { spaces: 2 });
21
+ }
22
+ async function readThemePackProvenance(cwd) {
23
+ const existing = await readExisting(cwd);
24
+ const themePack = existing.themePack;
25
+ if (themePack && typeof themePack === "object") {
26
+ return themePack;
27
+ }
28
+ return null;
29
+ }
30
+ export {
31
+ THEME_PACK_PROVENANCE_SCHEMA_VERSION,
32
+ ZUDO_DOC_JSON_FILENAME,
33
+ readThemePackProvenance,
34
+ writeThemePackProvenance
35
+ };