@takazudo/zudo-doc 3.3.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. package/CHANGELOG.md +51 -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/component-tokens.d.ts +1 -1
  38. package/dist/config/component-tokens.js +104 -5
  39. package/dist/config.d.ts +28 -12
  40. package/dist/config.js +11 -2
  41. package/dist/content/component-map.d.ts +0 -16
  42. package/dist/content/component-map.js +2 -4
  43. package/dist/content/index.d.ts +1 -1
  44. package/dist/content/index.js +2 -3
  45. package/dist/content.css +1 -1
  46. package/dist/design-token-panel-bootstrap.d.ts +45 -40
  47. package/dist/design-token-panel-bootstrap.js +98 -21
  48. package/dist/design-token-panel-config/index.js +1 -4
  49. package/dist/doc-body-end-islands/design-token-panel-island.d.ts +15 -0
  50. package/dist/doc-body-end-islands/design-token-panel-island.js +31 -0
  51. package/dist/doc-body-end-islands/index.d.ts +39 -17
  52. package/dist/doc-body-end-islands/index.js +13 -21
  53. package/dist/doc-body-end-islands/theme-pack-switcher-island.d.ts +37 -0
  54. package/dist/doc-body-end-islands/theme-pack-switcher-island.js +18 -0
  55. package/dist/doc-content-header/index.js +1 -1
  56. package/dist/doc-history-area/index.d.ts +10 -4
  57. package/dist/doc-history-area/index.js +3 -2
  58. package/dist/doc-metainfo-area/index.d.ts +1 -0
  59. package/dist/doc-page-props/index.d.ts +7 -23
  60. package/dist/doc-page-renderer/index.d.ts +1 -0
  61. package/dist/doc-page-renderer/index.js +1 -0
  62. package/dist/doc-page-shell/index.js +19 -12
  63. package/dist/doc-pager/index.js +1 -1
  64. package/dist/doc-route-entries/index.d.ts +2 -2
  65. package/dist/doclayout/doc-layout-with-defaults.js +4 -4
  66. package/dist/doclayout/doc-layout.d.ts +8 -0
  67. package/dist/doclayout/doc-layout.js +10 -1
  68. package/dist/docs-schema/index.js +1 -5
  69. package/dist/eject/index.d.ts +16 -0
  70. package/dist/eject/index.js +122 -28
  71. package/dist/extract-headings/index.d.ts +5 -8
  72. package/dist/extract-headings/index.js +2 -9
  73. package/dist/factory-context/index.d.ts +42 -4
  74. package/dist/features.css +80 -45
  75. package/dist/footer/footer.js +1 -0
  76. package/dist/head-with-defaults/index.d.ts +2 -0
  77. package/dist/head-with-defaults/index.js +16 -0
  78. package/dist/header/header.d.ts +10 -5
  79. package/dist/header/header.js +45 -5
  80. package/dist/header/index.d.ts +1 -1
  81. package/dist/header/types.d.ts +30 -1
  82. package/dist/header-with-defaults/index.js +1 -0
  83. package/dist/home-page/index.d.ts +2 -0
  84. package/dist/home-page/index.js +11 -5
  85. package/dist/home-page/prepare-home-data.js +1 -1
  86. package/dist/locale-merge/index.d.ts +9 -14
  87. package/dist/locale-merge/index.js +6 -4
  88. package/dist/mdx-components/index.js +4 -4
  89. package/dist/plugins/claude-resources.d.ts +1 -0
  90. package/dist/plugins/claude-resources.js +4 -2
  91. package/dist/plugins/doc-history.js +1 -1
  92. package/dist/{integrations → plugins/internal}/claude-resources/index.d.ts +1 -16
  93. package/dist/{integrations → plugins/internal}/claude-resources/index.js +0 -9
  94. package/dist/{integrations → plugins/internal}/doc-history/index.d.ts +0 -17
  95. package/dist/{integrations → plugins/internal}/doc-history/index.js +0 -4
  96. package/dist/{integrations → plugins/internal}/doc-history/pre-build.d.ts +2 -4
  97. package/dist/plugins/internal/llms-txt/index.d.ts +7 -0
  98. package/dist/{integrations → plugins/internal}/llms-txt/load.d.ts +1 -1
  99. package/dist/{integrations → plugins/internal}/llms-txt/load.js +2 -2
  100. package/dist/{integrations → plugins/internal}/llms-txt/strip.d.ts +2 -3
  101. package/dist/{integrations → plugins/internal}/llms-txt/strip.js +1 -1
  102. package/dist/{integrations → plugins/internal}/llms-txt/types.d.ts +13 -22
  103. package/dist/{integrations → plugins/internal}/search-index/collect.js +1 -1
  104. package/dist/plugins/internal/theme-packs/copy.d.ts +32 -0
  105. package/dist/plugins/internal/theme-packs/copy.js +45 -0
  106. package/dist/plugins/internal/theme-packs/dev-middleware.d.ts +22 -0
  107. package/dist/plugins/internal/theme-packs/dev-middleware.js +80 -0
  108. package/dist/plugins/internal/theme-packs/index.d.ts +6 -0
  109. package/dist/plugins/internal/theme-packs/index.js +9 -0
  110. package/dist/plugins/internal/theme-packs/resolve.d.ts +17 -0
  111. package/dist/plugins/internal/theme-packs/resolve.js +17 -0
  112. package/dist/plugins/internal/theme-packs/types.d.ts +22 -0
  113. package/dist/plugins/internal/theme-packs/types.js +0 -0
  114. package/dist/plugins/llms-txt.js +1 -1
  115. package/dist/plugins/routes.js +11 -1
  116. package/dist/plugins/search-index.js +1 -1
  117. package/dist/plugins/theme-packs.d.ts +3 -0
  118. package/dist/plugins/theme-packs.js +40 -0
  119. package/dist/preset.d.ts +19 -14
  120. package/dist/preset.js +24 -9
  121. package/dist/route-context/index.js +4 -6
  122. package/dist/route-enumerators/index.d.ts +6 -18
  123. package/dist/route-enumerators/index.js +8 -6
  124. package/dist/routes/404.js +3 -1
  125. package/dist/routes/_chrome.js +2 -2
  126. package/dist/routes/_context.d.ts +7 -3
  127. package/dist/routes/_context.js +2 -0
  128. package/dist/routes/_docs-helpers.js +9 -21
  129. package/dist/safelist.css +1 -1
  130. package/dist/settings.d.ts +27 -12
  131. package/dist/sidebar-toggle-island/index.js +1 -0
  132. package/dist/sidebar-tree/build-tree.d.ts +3 -4
  133. package/dist/sidebar-tree/build-tree.js +4 -3
  134. package/dist/sidebar-tree/index.d.ts +2 -2
  135. package/dist/sidebar-tree/types.d.ts +6 -17
  136. package/dist/site-tree-nav-island/index.d.ts +3 -1
  137. package/dist/site-tree-nav-island/index.js +17 -5
  138. package/dist/site-tree-nav-island/state.d.ts +4 -0
  139. package/dist/site-tree-nav-island/state.js +10 -0
  140. package/dist/tag-helpers/index.d.ts +6 -13
  141. package/dist/tag-helpers/index.js +5 -23
  142. package/dist/tag-pages/index.d.ts +8 -21
  143. package/dist/tag-pages/index.js +14 -10
  144. package/dist/tags-audit.d.ts +16 -44
  145. package/dist/tags-audit.js +9 -172
  146. package/dist/theme/color-scheme-provider.d.ts +2 -3
  147. package/dist/theme/color-scheme-provider.js +2 -10
  148. package/dist/theme/index.d.ts +1 -4
  149. package/dist/theme/index.js +2 -30
  150. package/dist/theme/theme-pack-provider.d.ts +42 -0
  151. package/dist/theme/theme-pack-provider.js +75 -0
  152. package/dist/theme-cli/apply.d.ts +16 -0
  153. package/dist/theme-cli/apply.js +61 -0
  154. package/dist/theme-cli/config-io.d.ts +15 -0
  155. package/dist/theme-cli/config-io.js +51 -0
  156. package/dist/theme-cli/config-rewriter.d.ts +21 -0
  157. package/dist/theme-cli/config-rewriter.js +141 -0
  158. package/dist/theme-cli/config-scanner.d.ts +63 -0
  159. package/dist/theme-cli/config-scanner.js +288 -0
  160. package/dist/theme-cli/index.d.ts +7 -0
  161. package/dist/theme-cli/index.js +38 -0
  162. package/dist/theme-cli/list.d.ts +27 -0
  163. package/dist/theme-cli/list.js +64 -0
  164. package/dist/theme-cli/provenance.d.ts +17 -0
  165. package/dist/theme-cli/provenance.js +35 -0
  166. package/dist/theme-cli/registry.d.ts +14 -0
  167. package/dist/theme-cli/registry.js +13 -0
  168. package/dist/theme-pack-dialog/dialog-state.d.ts +25 -0
  169. package/dist/theme-pack-dialog/dialog-state.js +40 -0
  170. package/dist/theme-pack-dialog/index.d.ts +5 -0
  171. package/dist/theme-pack-dialog/index.js +152 -0
  172. package/dist/theme-pack-dialog/theme-pack-card.d.ts +25 -0
  173. package/dist/theme-pack-dialog/theme-pack-card.js +72 -0
  174. package/dist/theme-pack-switcher/index.d.ts +49 -0
  175. package/dist/theme-pack-switcher/index.js +205 -0
  176. package/dist/theme-pack-switcher/switcher-state.d.ts +56 -0
  177. package/dist/theme-pack-switcher/switcher-state.js +43 -0
  178. package/dist/theme-pack-switcher/theme-pack-sync.d.ts +85 -0
  179. package/dist/theme-pack-switcher/theme-pack-sync.js +121 -0
  180. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-400-latin.woff2 +0 -0
  181. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-700-latin.woff2 +0 -0
  182. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-italic-400-latin.woff2 +0 -0
  183. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-italic-700-latin.woff2 +0 -0
  184. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegibleMono-italic-latin.woff2 +0 -0
  185. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegibleMono-latin.woff2 +0 -0
  186. package/dist/theme-packs/beacon/fonts/OFL.txt +94 -0
  187. package/dist/theme-packs/beacon/meta.json +37 -0
  188. package/dist/theme-packs/beacon/pack.css +442 -0
  189. package/dist/theme-packs/broadsheet/fonts/CourierPrime-400-latin.woff2 +0 -0
  190. package/dist/theme-packs/broadsheet/fonts/CourierPrime-700-latin.woff2 +0 -0
  191. package/dist/theme-packs/broadsheet/fonts/OFL.txt +95 -0
  192. package/dist/theme-packs/broadsheet/fonts/PlayfairDisplay-italic-latin.woff2 +0 -0
  193. package/dist/theme-packs/broadsheet/fonts/PlayfairDisplay-latin.woff2 +0 -0
  194. package/dist/theme-packs/broadsheet/fonts/SourceSerif4-italic-latin.woff2 +0 -0
  195. package/dist/theme-packs/broadsheet/fonts/SourceSerif4-latin.woff2 +0 -0
  196. package/dist/theme-packs/broadsheet/meta.json +38 -0
  197. package/dist/theme-packs/broadsheet/pack.css +448 -0
  198. package/dist/theme-packs/brutalist/fonts/ArchivoBlack-latin.woff2 +0 -0
  199. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  200. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  201. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-700-latin.woff2 +0 -0
  202. package/dist/theme-packs/brutalist/fonts/OFL.txt +95 -0
  203. package/dist/theme-packs/brutalist/fonts/SpaceGrotesk-latin.woff2 +0 -0
  204. package/dist/theme-packs/brutalist/meta.json +38 -0
  205. package/dist/theme-packs/brutalist/pack.css +546 -0
  206. package/dist/theme-packs/default/meta.json +37 -0
  207. package/dist/theme-packs/drift/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  208. package/dist/theme-packs/drift/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  209. package/dist/theme-packs/drift/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  210. package/dist/theme-packs/drift/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  211. package/dist/theme-packs/drift/fonts/IBMPlexSans-italic-latin.woff2 +0 -0
  212. package/dist/theme-packs/drift/fonts/IBMPlexSans-latin-ext.woff2 +0 -0
  213. package/dist/theme-packs/drift/fonts/IBMPlexSans-latin.woff2 +0 -0
  214. package/dist/theme-packs/drift/fonts/OFL.txt +93 -0
  215. package/dist/theme-packs/drift/meta.json +37 -0
  216. package/dist/theme-packs/drift/pack.css +478 -0
  217. package/dist/theme-packs/fjord/fonts/Inter-latin-ext.woff2 +0 -0
  218. package/dist/theme-packs/fjord/fonts/Inter-latin.woff2 +0 -0
  219. package/dist/theme-packs/fjord/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  220. package/dist/theme-packs/fjord/fonts/JetBrainsMono-latin.woff2 +0 -0
  221. package/dist/theme-packs/fjord/fonts/OFL.txt +94 -0
  222. package/dist/theme-packs/fjord/meta.json +37 -0
  223. package/dist/theme-packs/fjord/pack.css +375 -0
  224. package/dist/theme-packs/foundry/fonts/Inter-latin-ext.woff2 +0 -0
  225. package/dist/theme-packs/foundry/fonts/Inter-latin.woff2 +0 -0
  226. package/dist/theme-packs/foundry/fonts/OFL.txt +93 -0
  227. package/dist/theme-packs/foundry/meta.json +37 -0
  228. package/dist/theme-packs/foundry/pack.css +202 -0
  229. package/dist/theme-packs/futura-editorial/fonts/Jost-latin.woff2 +0 -0
  230. package/dist/theme-packs/futura-editorial/fonts/NotoSans-italic-latin.woff2 +0 -0
  231. package/dist/theme-packs/futura-editorial/fonts/NotoSans-latin.woff2 +0 -0
  232. package/dist/theme-packs/futura-editorial/fonts/OFL.txt +95 -0
  233. package/dist/theme-packs/futura-editorial/fonts/SpaceMono-400-latin.woff2 +0 -0
  234. package/dist/theme-packs/futura-editorial/fonts/SpaceMono-700-latin.woff2 +0 -0
  235. package/dist/theme-packs/futura-editorial/meta.json +38 -0
  236. package/dist/theme-packs/futura-editorial/pack.css +313 -0
  237. package/dist/theme-packs/hearth/fonts/Fraunces-italic-latin.woff2 +0 -0
  238. package/dist/theme-packs/hearth/fonts/Fraunces-latin.woff2 +0 -0
  239. package/dist/theme-packs/hearth/fonts/Nunito-latin.woff2 +0 -0
  240. package/dist/theme-packs/hearth/fonts/OFL.txt +95 -0
  241. package/dist/theme-packs/hearth/fonts/SplineSansMono-latin.woff2 +0 -0
  242. package/dist/theme-packs/hearth/meta.json +38 -0
  243. package/dist/theme-packs/hearth/pack.css +385 -0
  244. package/dist/theme-packs/hollow/fonts/OFL.txt +94 -0
  245. package/dist/theme-packs/hollow/fonts/SpaceGrotesk-latin.woff2 +0 -0
  246. package/dist/theme-packs/hollow/fonts/SpaceMono-400-italic-latin.woff2 +0 -0
  247. package/dist/theme-packs/hollow/fonts/SpaceMono-400-latin.woff2 +0 -0
  248. package/dist/theme-packs/hollow/fonts/SpaceMono-700-latin.woff2 +0 -0
  249. package/dist/theme-packs/hollow/meta.json +37 -0
  250. package/dist/theme-packs/hollow/pack.css +428 -0
  251. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-ext-italic.woff2 +0 -0
  252. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-ext.woff2 +0 -0
  253. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-italic.woff2 +0 -0
  254. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin.woff2 +0 -0
  255. package/dist/theme-packs/ledger/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  256. package/dist/theme-packs/ledger/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  257. package/dist/theme-packs/ledger/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  258. package/dist/theme-packs/ledger/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  259. package/dist/theme-packs/ledger/fonts/OFL.txt +94 -0
  260. package/dist/theme-packs/ledger/meta.json +37 -0
  261. package/dist/theme-packs/ledger/pack.css +463 -0
  262. package/dist/theme-packs/manuscript/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
  263. package/dist/theme-packs/manuscript/fonts/CourierPrime-400-latin.woff2 +0 -0
  264. package/dist/theme-packs/manuscript/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
  265. package/dist/theme-packs/manuscript/fonts/CourierPrime-700-latin.woff2 +0 -0
  266. package/dist/theme-packs/manuscript/fonts/EBGaramond-latin-italic.woff2 +0 -0
  267. package/dist/theme-packs/manuscript/fonts/EBGaramond-latin.woff2 +0 -0
  268. package/dist/theme-packs/manuscript/fonts/OFL.txt +94 -0
  269. package/dist/theme-packs/manuscript/meta.json +37 -0
  270. package/dist/theme-packs/manuscript/pack.css +376 -0
  271. package/dist/theme-packs/matcha/fonts/MPLUS1Code-latin.woff2 +0 -0
  272. package/dist/theme-packs/matcha/fonts/OFL.txt +95 -0
  273. package/dist/theme-packs/matcha/fonts/ShipporiMincho-500-latin.woff2 +0 -0
  274. package/dist/theme-packs/matcha/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  275. package/dist/theme-packs/matcha/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  276. package/dist/theme-packs/matcha/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  277. package/dist/theme-packs/matcha/meta.json +38 -0
  278. package/dist/theme-packs/matcha/pack.css +409 -0
  279. package/dist/theme-packs/nocturne/fonts/CormorantGaramond-italic-latin.woff2 +0 -0
  280. package/dist/theme-packs/nocturne/fonts/CormorantGaramond-latin.woff2 +0 -0
  281. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  282. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  283. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-italic-latin.woff2 +0 -0
  284. package/dist/theme-packs/nocturne/fonts/Manrope-latin.woff2 +0 -0
  285. package/dist/theme-packs/nocturne/fonts/OFL.txt +95 -0
  286. package/dist/theme-packs/nocturne/meta.json +38 -0
  287. package/dist/theme-packs/nocturne/pack.css +502 -0
  288. package/dist/theme-packs/observatory/fonts/JosefinSans-latin.woff2 +0 -0
  289. package/dist/theme-packs/observatory/fonts/Jost-italic-latin.woff2 +0 -0
  290. package/dist/theme-packs/observatory/fonts/Jost-latin.woff2 +0 -0
  291. package/dist/theme-packs/observatory/fonts/OFL.txt +95 -0
  292. package/dist/theme-packs/observatory/fonts/SpaceMono-400-latin.woff2 +0 -0
  293. package/dist/theme-packs/observatory/fonts/SpaceMono-700-latin.woff2 +0 -0
  294. package/dist/theme-packs/observatory/fonts/SpaceMono-italic-latin.woff2 +0 -0
  295. package/dist/theme-packs/observatory/meta.json +38 -0
  296. package/dist/theme-packs/observatory/pack.css +728 -0
  297. package/dist/theme-packs/onyx/fonts/CormorantGaramond-italic-latin.woff2 +0 -0
  298. package/dist/theme-packs/onyx/fonts/CormorantGaramond-latin.woff2 +0 -0
  299. package/dist/theme-packs/onyx/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  300. package/dist/theme-packs/onyx/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  301. package/dist/theme-packs/onyx/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  302. package/dist/theme-packs/onyx/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  303. package/dist/theme-packs/onyx/fonts/Jost-latin.woff2 +0 -0
  304. package/dist/theme-packs/onyx/fonts/OFL.txt +95 -0
  305. package/dist/theme-packs/onyx/meta.json +38 -0
  306. package/dist/theme-packs/onyx/pack.css +497 -0
  307. package/dist/theme-packs/phosphor/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  308. package/dist/theme-packs/phosphor/fonts/JetBrainsMono-latin.woff2 +0 -0
  309. package/dist/theme-packs/phosphor/fonts/OFL.txt +94 -0
  310. package/dist/theme-packs/phosphor/fonts/VT323-latin-ext.woff2 +0 -0
  311. package/dist/theme-packs/phosphor/fonts/VT323-latin.woff2 +0 -0
  312. package/dist/theme-packs/phosphor/meta.json +38 -0
  313. package/dist/theme-packs/phosphor/pack.css +493 -0
  314. package/dist/theme-packs/solar/fonts/OFL.txt +94 -0
  315. package/dist/theme-packs/solar/fonts/SourceCodePro-italic-latin.woff2 +0 -0
  316. package/dist/theme-packs/solar/fonts/SourceCodePro-latin.woff2 +0 -0
  317. package/dist/theme-packs/solar/fonts/SourceSans3-italic-latin.woff2 +0 -0
  318. package/dist/theme-packs/solar/fonts/SourceSans3-latin.woff2 +0 -0
  319. package/dist/theme-packs/solar/meta.json +37 -0
  320. package/dist/theme-packs/solar/pack.css +380 -0
  321. package/dist/theme-packs/sumi/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  322. package/dist/theme-packs/sumi/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  323. package/dist/theme-packs/sumi/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  324. package/dist/theme-packs/sumi/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  325. package/dist/theme-packs/sumi/fonts/OFL.txt +95 -0
  326. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-600-latin.woff2 +0 -0
  327. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-700-latin.woff2 +0 -0
  328. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-800-latin.woff2 +0 -0
  329. package/dist/theme-packs/sumi/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  330. package/dist/theme-packs/sumi/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  331. package/dist/theme-packs/sumi/meta.json +38 -0
  332. package/dist/theme-packs/sumi/pack.css +502 -0
  333. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  334. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  335. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-600-latin.woff2 +0 -0
  336. package/dist/theme-packs/swissgrid/fonts/Inter-latin-ext.woff2 +0 -0
  337. package/dist/theme-packs/swissgrid/fonts/Inter-latin.woff2 +0 -0
  338. package/dist/theme-packs/swissgrid/fonts/InterTight-latin.woff2 +0 -0
  339. package/dist/theme-packs/swissgrid/fonts/OFL.txt +95 -0
  340. package/dist/theme-packs/swissgrid/meta.json +38 -0
  341. package/dist/theme-packs/swissgrid/pack.css +518 -0
  342. package/dist/theme-packs/washi/fonts/MPlus1Code-400-latin.woff2 +0 -0
  343. package/dist/theme-packs/washi/fonts/MPlus1Code-500-latin.woff2 +0 -0
  344. package/dist/theme-packs/washi/fonts/OFL.txt +95 -0
  345. package/dist/theme-packs/washi/fonts/ShipporiMincho-500-latin.woff2 +0 -0
  346. package/dist/theme-packs/washi/fonts/ShipporiMincho-600-latin.woff2 +0 -0
  347. package/dist/theme-packs/washi/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  348. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  349. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  350. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-700-latin.woff2 +0 -0
  351. package/dist/theme-packs/washi/meta.json +38 -0
  352. package/dist/theme-packs/washi/pack.css +479 -0
  353. package/dist/theme-packs-registry/index.d.ts +5 -0
  354. package/dist/theme-packs-registry/index.js +30 -0
  355. package/dist/theme-packs-registry/load-registry.d.ts +23 -0
  356. package/dist/theme-packs-registry/load-registry.js +64 -0
  357. package/dist/theme-packs-registry/meta-schema.d.ts +70 -0
  358. package/dist/theme-packs-registry/meta-schema.js +38 -0
  359. package/dist/theme-packs-registry/resolve-enabled-packs.d.ts +25 -0
  360. package/dist/theme-packs-registry/resolve-enabled-packs.js +43 -0
  361. package/dist/theme-packs-registry/token-manifest.d.ts +19 -0
  362. package/dist/theme-packs-registry/token-manifest.js +57 -0
  363. package/dist/theme-packs-registry/validator.d.ts +35 -0
  364. package/dist/theme-packs-registry/validator.js +284 -0
  365. package/dist/theme-toggle/color-scheme-sync.d.ts +2 -4
  366. package/dist/toc/mobile-toc.js +1 -1
  367. package/dist/versions-page/index.d.ts +2 -2
  368. package/dist/versions-page/index.js +8 -8
  369. package/eject/breadcrumb/breadcrumb.tsx +4 -4
  370. package/eject/breadcrumb/find-path.ts +2 -2
  371. package/eject/breadcrumb/index.ts +1 -1
  372. package/eject/breadcrumb/types.ts +0 -6
  373. package/eject/code-group/index.tsx +2 -2
  374. package/eject/doc-history/index.tsx +1 -1
  375. package/eject/doc-pager/index.tsx +1 -1
  376. package/eject/footer/footer.tsx +1 -0
  377. package/eject/header/header.tsx +86 -21
  378. package/eject/header/index.ts +3 -0
  379. package/eject/header/types.ts +39 -1
  380. package/eject/sidebar-toggle-island/index.tsx +7 -1
  381. package/eject/site-tree-nav-island/index.tsx +15 -3
  382. package/eject/site-tree-nav-island/state.ts +9 -0
  383. package/eject/theme-toggle/color-scheme-sync.ts +2 -4
  384. package/eject/toc/mobile-toc.tsx +9 -1
  385. package/package.json +35 -29
  386. package/routes-src/404.tsx +4 -1
  387. package/routes-src/_chrome.tsx +6 -5
  388. package/routes-src/_context.ts +4 -0
  389. package/routes-src/_docs-helpers.ts +9 -29
  390. package/routes-src/_virtual.d.ts +4 -0
  391. package/virtual-modules.d.ts +4 -0
  392. package/zfb-config-shim.d.ts +40 -18
  393. package/dist/integrations/llms-txt/index.d.ts +0 -33
  394. package/dist/theme/color-tweak-export-modal.d.ts +0 -16
  395. package/dist/theme/color-tweak-export-modal.js +0 -138
  396. package/dist/theme/design-token-serde.d.ts +0 -183
  397. package/dist/theme/design-token-serde.js +0 -346
  398. package/dist/theme/design-token-types.d.ts +0 -13
  399. package/dist/theme/design-token-types.js +0 -6
  400. package/dist/theme/iframe-bridge.d.ts +0 -42
  401. package/dist/theme/iframe-bridge.js +0 -72
  402. /package/dist/{integrations → plugins/internal}/claude-resources/escape-for-mdx.d.ts +0 -0
  403. /package/dist/{integrations → plugins/internal}/claude-resources/escape-for-mdx.js +0 -0
  404. /package/dist/{integrations → plugins/internal}/claude-resources/generate.d.ts +0 -0
  405. /package/dist/{integrations → plugins/internal}/claude-resources/generate.js +0 -0
  406. /package/dist/{integrations → plugins/internal}/doc-history/pre-build.js +0 -0
  407. /package/dist/{integrations → plugins/internal}/llms-txt/dev-middleware.d.ts +0 -0
  408. /package/dist/{integrations → plugins/internal}/llms-txt/dev-middleware.js +0 -0
  409. /package/dist/{integrations → plugins/internal}/llms-txt/emit.d.ts +0 -0
  410. /package/dist/{integrations → plugins/internal}/llms-txt/emit.js +0 -0
  411. /package/dist/{integrations → plugins/internal}/llms-txt/generate.d.ts +0 -0
  412. /package/dist/{integrations → plugins/internal}/llms-txt/generate.js +0 -0
  413. /package/dist/{integrations → plugins/internal}/llms-txt/index.js +0 -0
  414. /package/dist/{integrations → plugins/internal}/llms-txt/types.js +0 -0
  415. /package/dist/{integrations → plugins/internal}/search-index/build-emitter.d.ts +0 -0
  416. /package/dist/{integrations → plugins/internal}/search-index/build-emitter.js +0 -0
  417. /package/dist/{integrations → plugins/internal}/search-index/collect.d.ts +0 -0
  418. /package/dist/{integrations → plugins/internal}/search-index/dev-middleware.d.ts +0 -0
  419. /package/dist/{integrations → plugins/internal}/search-index/dev-middleware.js +0 -0
  420. /package/dist/{integrations → plugins/internal}/search-index/index.d.ts +0 -0
  421. /package/dist/{integrations → plugins/internal}/search-index/index.js +0 -0
  422. /package/dist/{integrations → plugins/internal}/search-index/types.d.ts +0 -0
  423. /package/dist/{integrations → plugins/internal}/search-index/types.js +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,57 @@ All notable changes to `@takazudo/zudo-doc` are documented in this file.
4
4
 
5
5
  The format is based on Keep a Changelog, and release notes are generated from the changelog MDX pages.
6
6
 
7
+ ## [4.1.0] - 2026-07-18
8
+
9
+ ### Features
10
+
11
+ - Theme-pack fonts now reach the app shell (header, sidebar, TOC, breadcrumb, pager) via a global body font seam, with per-surface chrome font tokens for finer control (f84b2bd2)
12
+
13
+ ### Bug Fixes
14
+
15
+ - Per-surface chrome font knobs anchor to the seam token instead of relying on inheritance (dbd95365)
16
+ - Docs: corrected the false claim that mobile chrome strips theme-pack font tokens — mobile hooks receive them like desktop (3cbe0d45, 493f76dc)
17
+ - E2E: theme-pack font specs assert the body font-family directly, target the bundled foundry pack, and wait for switcher hydration (d88e4c5a, 218e8844)
18
+ - Reverted a hand-edited generated CHANGELOG.md — it is corpus-generated (ef43274c)
19
+
20
+ ### Other Changes
21
+
22
+ - Toolchain: @takazudo/zfb family (zfb, zfb-runtime, zfb-adapter-cloudflare, zfb-md-wasm) adopted through 0.1.0-next.89 (02268414)
23
+ - Bilingual docs for the chrome font seam tokens and the mobile reach caveat (58cf6fc2)
24
+ - Durable e2e regression spec for the chrome font seam (69af425e)
25
+
26
+ ## [4.0.0] - 2026-07-17
27
+
28
+ ### Breaking Changes
29
+
30
+ - Current-only compatibility contract: legacy integration subpaths, the tag alias/deprecation runtime, legacy token storage bridges, legacy Syntect markup support, legacy doc-history contracts, and the legacy link-checker entrypoints are removed (c8b6d3da, 08338a8f, 701b4aea, 16edbe8b, e8ce8929, cc2bb792, f2c9b925)
31
+ - Heading IDs are hierarchical-only; the legacy flat-ID fallback is gone (390064ff)
32
+ - Doc entries use the current zfb entry model exclusively (df048e30)
33
+
34
+ ### Features
35
+
36
+ - Theme pack system: pack registry with config census and validator, asset delivery pipeline (build, npm tarball, dev), runtime switching engine with FOUC-safe bootstrap, bottom-right switcher flyout, browse-all theme grid dialog, and a `zudo-doc theme list|apply` CLI (aab0014f, 9eddd9ba, f5f83b43, adf81c9a, 07b77eb1, a33f66ef)
37
+ - 20 official theme packs shipped across four batches — foundry, swissgrid, broadsheet, ledger, manuscript, futura-editorial, washi, sumi, matcha, hearth, hollow, fjord, nocturne, drift, onyx, phosphor, observatory, solar, beacon, brutalist — with the full 21-pack catalog (including default) synced into create-zudo-doc and the preset generator (487b1761)
38
+ - Stable DOM hooks for theme packs: `data-footer`, `data-doc-pager`, `data-doc-description`, and `data-theme-pack-switcher` / `data-switcher-card` / `data-switcher-launcher`; all 20 packs retargeted onto the hooks and every changed pack's `meta.json` version bumped for the stylesheet cache buster (c8bb4421, ac654a8a, 2b2a46d5, b5fffb01, d7c67ca7)
39
+ - Restored pack styling that previously lacked hooks: foundry's pager hover wash and broadsheet's classified-ad flyout frame (850a30fb)
40
+ - Semantic syntax-highlight class mode: document fences render `hi-*` token classes with a stable token contract, mapped by `features.css` (c1237dcd, c305fdf8, 920be3d2)
41
+ - AI chat exact daily spend cap enforced via a Durable Object, with paid-call admission control and an operations runbook (0b46e23c, 15e3b891, 491116c5)
42
+ - Chrome customization: typed primary replacement slots (`Header`, `Footer`, `Sidebar`, `Toc`, `Breadcrumb`, `DocPager`), a named header-component registry, binding-aware eject warnings, and end-to-end proof (a3ae76cc, 9d8e7901, 5346b2ef, 0e92dbc2)
43
+ - create-zudo-doc: `footerCopyright` feature defaults to on; theme-pack scaffold prompt and programmatic `themePack` option (51307cd4, acf20690, b287e94d)
44
+
45
+ ### Bug Fixes
46
+
47
+ - onyx: the decorative gold outline on the switcher card and browse-all dialog no longer masks the keyboard focus-visible ring (11d5cc0f)
48
+ - ledger: DocPager selector no longer over-matches NavCardGrid on auto-index pages (eff8e1b8)
49
+ - Light-mode WCAG contrast corrections across several packs after review (46e1e6b2)
50
+
51
+ ### Other Changes
52
+
53
+ - Theme pack architecture ADR, hardened Decisions 6.5/6.6 (stable-hook list, h2–h4 gradient carve-out), and a new durable `theme-pack-authoring.md` pack-author reference (4f5cc90c, ed287e1a, 4856c44b)
54
+ - Theme gallery reference docs (EN+JA) covering the full pack catalog (2b73cffa, 3068fbca)
55
+ - Scaffold customization docs overhaul: customization ladder, chrome bindings, custom components guide, route injection, color-token guidance (8a54b3df)
56
+ - Toolchain: zfb family adopted through next.87; zdtp 0.4.8 (151f09bb, efc3afdc)
57
+
7
58
  ## [3.3.0] - 2026-07-12
8
59
 
9
60
  ### Features
package/README.md CHANGED
@@ -8,14 +8,14 @@ instead of editing the generated markdown directly.
8
8
 
9
9
  This package provides the missing-by-design framework concerns:
10
10
 
11
- - **Sidebar tree builder** (`./sidebar-tree`) — turns collection entries + `_category_.json` into a sidebar `SidebarNode[]`.
11
+ - **Sidebar tree builder** (`./sidebar-tree`) — turns collection entries + `_category_.json` into breadcrumb/navigation nodes.
12
12
  - **Theme controls** (`./theme`) — color scheme provider + design-token tweak panel (Preact island that wraps an iframe).
13
13
  - **Theme toggle (bare)** (`./theme-toggle`) — the un-wrapped ThemeToggle component for call sites that compose their own `<Island>` (the `./theme` barrel exports an Island-wrapped variant of the same component).
14
14
  - **TOC** (`./toc`) — desktop and mobile TOC Preact islands fed by MDX `headings` export.
15
15
  - **Breadcrumb** (`./breadcrumb`) — JSX breadcrumb fed by the sidebar tree.
16
16
  - **DocLayout** (`./doclayout`) — composable layout shell with explicit `<Header>`, `<Sidebar>`, `<Main>`, `<Toc>`, `<Footer>` props; ships a `<DocLayoutWithDefaults>` wrapper that holds the 16 `create-zudo-doc` injection anchors.
17
17
  - **View Transitions** (`./transitions`) — native View Transitions API shim (Chrome/Edge/Safari 18+); persistent regions via `view-transition-name`. No-op fallback in Firefox.
18
- - **Head injection** (`./head`) — canonical, og:\*, twitter:\*, robots, preload hints, RSS link, sitemap link, theme-color — byte-equal to today's legacy doc-layout output.
18
+ - **Head injection** (`./head`) — canonical, og:\*, twitter:\*, robots, preload hints, RSS link, sitemap link, and theme-color output.
19
19
  - **SSR-skip wrappers** (`./ssr-skip`) — `<AiChatModalIsland>`, `<ImageEnlargeIsland>`, `<DesignTokenTweakPanelIsland>`, `<MockInitIsland>` — wrap zfb's `<Island ssrFallback>` with the right fallback markup so doc pages don't have to re-implement the SSR-skip pattern.
20
20
 
21
21
  ## Optional peer dependency: shiki
@@ -0,0 +1,126 @@
1
+ import { pathToFileURL } from "node:url";
2
+ import { isAbsolute, resolve } from "node:path";
3
+
4
+ import type { TagCliConfig } from "@takazudo/zudo-doc/tags-audit";
5
+
6
+ const GOVERNANCE_MODES = new Set(["off", "warn", "strict"]);
7
+
8
+ function invalidConfig(configPath: string, detail: string): Error {
9
+ return new Error(`Invalid tag CLI config "${configPath}": ${detail}`);
10
+ }
11
+
12
+ function validateConfig(value: unknown, configPath: string): TagCliConfig {
13
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
14
+ throw invalidConfig(configPath, "the module must default-export an object");
15
+ }
16
+
17
+ const config = value as Record<string, unknown>;
18
+ if (
19
+ !Array.isArray(config.contentDirs) ||
20
+ config.contentDirs.length === 0 ||
21
+ config.contentDirs.some(
22
+ (dir) =>
23
+ typeof dir !== "string" ||
24
+ dir.trim().length === 0 ||
25
+ isAbsolute(dir),
26
+ )
27
+ ) {
28
+ throw invalidConfig(
29
+ configPath,
30
+ "`contentDirs` must be a non-empty array of project-relative paths",
31
+ );
32
+ }
33
+ if (
34
+ !Array.isArray(config.vocabulary) ||
35
+ config.vocabulary.some(
36
+ (entry) =>
37
+ entry === null ||
38
+ typeof entry !== "object" ||
39
+ typeof (entry as { id?: unknown }).id !== "string" ||
40
+ (entry as { id: string }).id.trim().length === 0,
41
+ )
42
+ ) {
43
+ throw invalidConfig(
44
+ configPath,
45
+ "`vocabulary` must be an array of entries with non-empty string ids",
46
+ );
47
+ }
48
+ if (
49
+ typeof config.governance !== "string" ||
50
+ !GOVERNANCE_MODES.has(config.governance)
51
+ ) {
52
+ throw invalidConfig(
53
+ configPath,
54
+ "`governance` must be one of \"off\", \"warn\", or \"strict\"",
55
+ );
56
+ }
57
+ if (typeof config.vocabularyActive !== "boolean") {
58
+ throw invalidConfig(configPath, "`vocabularyActive` must be a boolean");
59
+ }
60
+
61
+ return config as unknown as TagCliConfig;
62
+ }
63
+
64
+ export async function loadTagCliConfig(
65
+ configInput: string | undefined,
66
+ cwd = process.cwd(),
67
+ ): Promise<{ config: TagCliConfig; configPath: string }> {
68
+ if (!configInput || configInput.trim().length === 0) {
69
+ throw new Error(
70
+ "Missing required tag CLI config. Pass `--config <path>` to a module that default-exports TagCliConfig.",
71
+ );
72
+ }
73
+
74
+ const configPath = isAbsolute(configInput)
75
+ ? resolve(configInput)
76
+ : resolve(cwd, configInput);
77
+
78
+ let loaded: { default?: unknown };
79
+ try {
80
+ loaded = (await import(pathToFileURL(configPath).href)) as {
81
+ default?: unknown;
82
+ };
83
+ } catch (error) {
84
+ const detail = error instanceof Error ? error.message : String(error);
85
+ throw new Error(`Could not load tag CLI config "${configPath}": ${detail}`);
86
+ }
87
+
88
+ return {
89
+ config: validateConfig(loaded.default, configPath),
90
+ configPath,
91
+ };
92
+ }
93
+
94
+ /** Package-manager `--` separators must not hide CLI options from the runner. */
95
+ export function withoutForwardingSeparators(argv: string[]): string[] {
96
+ return argv.filter((arg) => arg !== "--");
97
+ }
98
+
99
+ export function takeTagCliConfigInput(argv: string[]): {
100
+ configInput: string | undefined;
101
+ argv: string[];
102
+ } {
103
+ const normalized = withoutForwardingSeparators(argv);
104
+ const rest: string[] = [];
105
+ let configInput: string | undefined;
106
+
107
+ for (let index = 0; index < normalized.length; index++) {
108
+ const arg = normalized[index]!;
109
+ if (arg === "--config" || arg === "-c") {
110
+ const value = normalized[index + 1];
111
+ if (!value || value.startsWith("-")) {
112
+ throw new Error(`Option \`${arg}\` requires a path.`);
113
+ }
114
+ configInput = value;
115
+ index++;
116
+ continue;
117
+ }
118
+ if (arg.startsWith("--config=")) {
119
+ configInput = arg.slice("--config=".length);
120
+ continue;
121
+ }
122
+ rest.push(arg);
123
+ }
124
+
125
+ return { configInput, argv: rest };
126
+ }
@@ -6,20 +6,18 @@
6
6
  * bin/tags-audit.mjs via tsx so it can:
7
7
  * 1. Import the compiled core logic from this package
8
8
  * (@takazudo/zudo-doc/tags-audit).
9
- * 2. Dynamically import the project's TypeScript config files
10
- * (src/config/settings.ts, src/config/tag-vocabulary.ts)
9
+ * 2. Load the one project config module explicitly passed with `--config`
11
10
  * via tsx's TypeScript-aware loader.
12
11
  *
13
12
  * This file is published as-is in the package's `bin/` directory.
14
13
  * Do NOT compile it — it is only ever run through tsx.
15
14
  *
16
15
  * Flags:
17
- * --fix rewrite alias tags to canonical ids, byte-stable
18
16
  * --ci force non-zero exit on any hard issue regardless of governance
19
17
  * --json emit the report as JSON instead of colorized text
20
18
  */
21
19
 
22
- import { join, resolve } from "node:path";
20
+ import { resolve } from "node:path";
23
21
 
24
22
  import pc from "picocolors";
25
23
  import pluralize from "pluralize";
@@ -27,100 +25,86 @@ import stringSimilarity from "string-similarity";
27
25
 
28
26
  import {
29
27
  audit,
30
- applyFixes,
31
- computeRewrites,
32
28
  formatTextReport,
33
29
  hasHardIssues,
34
30
  type AuditOptions,
35
31
  } from "@takazudo/zudo-doc/tags-audit";
32
+ import {
33
+ loadTagCliConfig,
34
+ takeTagCliConfigInput,
35
+ } from "./tag-cli-config.ts";
36
36
 
37
37
  // ── Project root ───────────────────────────────────────────────────────────
38
38
 
39
39
  const ROOT_DIR = process.cwd();
40
40
 
41
- // ── Dynamic import of project-specific TypeScript config ───────────────────
42
- // tsx (which runs this file) handles the TypeScript imports below.
41
+ // ── CLI flags ──────────────────────────────────────────────────────────────
43
42
 
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- const settingsModule = await import(resolve(ROOT_DIR, "src/config/settings.ts")) as any;
46
- const settings = settingsModule.settings as {
47
- docsDir: string;
48
- tagGovernance: "off" | "warn" | "strict";
49
- tagVocabulary: boolean;
50
- locales?: Record<string, { label?: string; dir: string }>;
51
- };
43
+ async function main(): Promise<void> {
44
+ const parsed = takeTagCliConfigInput(process.argv.slice(2));
45
+ const argv = parsed.argv;
46
+ const flags = {
47
+ ci: argv.includes("--ci"),
48
+ json: argv.includes("--json"),
49
+ };
52
50
 
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- const vocabModule = await import(resolve(ROOT_DIR, "src/config/tag-vocabulary.ts")) as any;
55
- const tagVocabulary: readonly { id: string; [k: string]: unknown }[] =
56
- vocabModule.tagVocabulary ?? [];
51
+ const unknownArgs = argv.filter(
52
+ (arg) => arg !== "--ci" && arg !== "--json",
53
+ );
54
+ if (unknownArgs.length > 0) {
55
+ throw new Error(`Unknown option: ${unknownArgs[0]}`);
56
+ }
57
57
 
58
- // ── CLI flags ──────────────────────────────────────────────────────────────
58
+ const { config } = await loadTagCliConfig(parsed.configInput, ROOT_DIR);
59
59
 
60
- const argv = process.argv.slice(2);
61
- const flags = {
62
- fix: argv.includes("--fix"),
63
- ci: argv.includes("--ci"),
64
- json: argv.includes("--json"),
65
- };
60
+ // ── Resolve content directories from explicit config ─────────────────────
66
61
 
67
- // ── Resolve content directories from settings ──────────────────────────────
62
+ const contentDirs = config.contentDirs.map((dir) => resolve(ROOT_DIR, dir));
68
63
 
69
- const docsDir = join(ROOT_DIR, settings.docsDir);
70
- const localeDirs = Object.values(settings.locales ?? {}).map((l) =>
71
- join(ROOT_DIR, l.dir),
72
- );
73
- const contentDirs = [docsDir, ...localeDirs];
64
+ // ── Audit mode ───────────────────────────────────────────────────────────
74
65
 
75
- const vocabularyActive =
76
- Boolean(settings.tagVocabulary) && settings.tagGovernance !== "off";
66
+ const opts: AuditOptions = {
67
+ rootDir: ROOT_DIR,
68
+ contentDirs,
69
+ vocabulary: config.vocabulary,
70
+ governance: config.governance,
71
+ vocabularyActive: config.vocabularyActive,
72
+ nearDupHelpers: {
73
+ singular: pluralize.singular,
74
+ compareTwoStrings: stringSimilarity.compareTwoStrings,
75
+ },
76
+ };
77
77
 
78
- // ── Fix mode ───────────────────────────────────────────────────────────────
78
+ const report = await audit(opts);
79
79
 
80
- if (flags.fix) {
81
- const rewrites = computeRewrites(tagVocabulary);
82
- const touched = await applyFixes(contentDirs, rewrites, ROOT_DIR);
83
80
  if (flags.json) {
84
- process.stdout.write(JSON.stringify({ fixed: touched }, null, 2) + "\n");
85
- } else if (touched.length === 0) {
86
- console.log(pc.green("✓ No alias rewrites needed"));
81
+ process.stdout.write(JSON.stringify(report, null, 2) + "\n");
87
82
  } else {
88
- console.log(pc.green(`✓ Rewrote aliases in ${touched.length} file(s):`));
89
- for (const f of touched) console.log(` ${f}`);
83
+ console.log(
84
+ formatTextReport(
85
+ report,
86
+ config.governance,
87
+ config.vocabularyActive,
88
+ pc,
89
+ ),
90
+ );
90
91
  }
91
- process.exit(0);
92
- }
93
92
 
94
- // ── Audit mode ─────────────────────────────────────────────────────────────
95
-
96
- const opts: AuditOptions = {
97
- rootDir: ROOT_DIR,
98
- contentDirs,
99
- vocabulary: tagVocabulary,
100
- governance: settings.tagGovernance,
101
- vocabularyActive,
102
- nearDupHelpers: {
103
- singular: pluralize.singular,
104
- compareTwoStrings: stringSimilarity.compareTwoStrings,
105
- },
106
- };
107
-
108
- const report = await audit(opts);
109
-
110
- if (flags.json) {
111
- process.stdout.write(JSON.stringify(report, null, 2) + "\n");
112
- } else {
113
- console.log(formatTextReport(report, settings.tagGovernance, vocabularyActive, pc));
93
+ const hardIssues = hasHardIssues(report);
94
+ if (hardIssues && (flags.ci || config.governance === "strict")) {
95
+ process.exit(1);
96
+ }
97
+ if (hardIssues) {
98
+ console.error(
99
+ pc.yellow(
100
+ "Note: tag issues found but running in non-strict mode (exit 0). Use --ci to fail.",
101
+ ),
102
+ );
103
+ }
114
104
  }
115
105
 
116
- const hardIssues = hasHardIssues(report);
117
- if (hardIssues && (flags.ci || settings.tagGovernance === "strict")) {
106
+ main().catch((error) => {
107
+ const message = error instanceof Error ? error.message : String(error);
108
+ process.stderr.write(`[tags-audit] ERROR: ${message}\n`);
118
109
  process.exit(1);
119
- }
120
- if (hardIssues) {
121
- console.error(
122
- pc.yellow(
123
- "Note: tag issues found but running in non-strict mode (exit 0). Use --ci to fail.",
124
- ),
125
- );
126
- }
110
+ });
@@ -3,24 +3,18 @@
3
3
  //
4
4
  // Package bin: vocabulary-aware audit of frontmatter tags.
5
5
  //
6
- // Spawns tsx (from the project's node_modules) to run the TypeScript runner
6
+ // Spawns the package-owned tsx dependency to run the TypeScript runner
7
7
  // (bin/tags-audit-runner.ts) which imports the compiled core logic from this
8
- // package plus the project's TypeScript config files (settings.ts,
9
- // tag-vocabulary.ts) via dynamic import.
10
- //
11
- // Requires tsx in the project's devDependencies. pnpm puts ./node_modules/.bin
12
- // in PATH for npm scripts, so `pnpm run tags:audit` always finds tsx.
8
+ // package plus the one project config module explicitly passed with --config.
13
9
  //
14
10
  // Usage (via package.json scripts):
15
- // tags-audit # report only (exit 0 in warn mode)
16
- // tags-audit --fix # rewrite alias tags in place
17
- // tags-audit --ci # force exit 1 on any hard issue
18
- // tags-audit --json # emit JSON report
11
+ // tags-audit --config ./src/config/tag-vocabulary.ts
12
+ // tags-audit --config ./src/config/tag-vocabulary.ts --ci
13
+ // tags-audit --config ./src/config/tag-vocabulary.ts -- --json
19
14
 
20
15
  import { spawnSync } from "node:child_process";
21
16
  import { resolve, dirname } from "node:path";
22
17
  import { fileURLToPath } from "node:url";
23
- import { existsSync } from "node:fs";
24
18
 
25
19
  const __dirname = dirname(fileURLToPath(import.meta.url));
26
20
 
@@ -28,35 +22,22 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
28
22
  // tsx treats it as a TypeScript file and handles the import graph.
29
23
  const RUNNER_PATH = resolve(__dirname, "tags-audit-runner.ts");
30
24
 
31
- // Locate tsx in the project's node_modules/.bin.
32
- // Walk up from cwd to handle monorepo setups where node_modules is hoisted.
33
- function findTsxBin() {
34
- let dir = process.cwd();
35
- for (let i = 0; i < 10; i++) {
36
- const candidate = resolve(dir, "node_modules/.bin/tsx");
37
- if (existsSync(candidate)) return candidate;
38
- const parent = dirname(dir);
39
- if (parent === dir) break;
40
- dir = parent;
41
- }
42
- // Last resort: tsx on PATH (e.g. globally installed or nix-shell)
43
- return "tsx";
44
- }
45
-
46
- const tsxBin = findTsxBin();
25
+ const tsxCli = fileURLToPath(import.meta.resolve("tsx/cli"));
47
26
 
48
- const result = spawnSync(tsxBin, [RUNNER_PATH, ...process.argv.slice(2)], {
49
- stdio: "inherit",
50
- env: process.env,
51
- cwd: process.cwd(),
52
- });
27
+ const result = spawnSync(
28
+ process.execPath,
29
+ [tsxCli, RUNNER_PATH, ...process.argv.slice(2)],
30
+ {
31
+ stdio: "inherit",
32
+ env: process.env,
33
+ cwd: process.cwd(),
34
+ },
35
+ );
53
36
 
54
37
  if (result.error) {
55
- // tsx binary not found or failed to spawn
56
38
  process.stderr.write(
57
- `\n[tags-audit] ERROR: Could not run tsx to execute the tags-audit runner.\n` +
58
- ` Ensure tsx is in your project's devDependencies and run \`pnpm install\`.\n` +
59
- ` tsx searched for: ${tsxBin}\n\n`,
39
+ `\n[tags-audit] ERROR: Could not start the package tag-audit runner.\n` +
40
+ ` Reinstall @takazudo/zudo-doc and try again.\n\n`,
60
41
  );
61
42
  process.exit(1);
62
43
  }