create-zudo-doc 3.1.0 → 3.3.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 (127) hide show
  1. package/dist/claude-md-gen.d.ts +8 -0
  2. package/dist/claude-md-gen.js +43 -26
  3. package/dist/compose.d.ts +14 -20
  4. package/dist/compose.js +15 -25
  5. package/dist/features/body-foot-util.d.ts +8 -4
  6. package/dist/features/body-foot-util.js +8 -4
  7. package/dist/features/claude-resources.d.ts +12 -0
  8. package/dist/features/claude-resources.js +13 -6
  9. package/dist/features/design-token-panel.d.ts +0 -12
  10. package/dist/features/design-token-panel.js +32 -93
  11. package/dist/features/doc-history.d.ts +18 -3
  12. package/dist/features/doc-history.js +45 -60
  13. package/dist/features/doc-tags.d.ts +9 -13
  14. package/dist/features/doc-tags.js +10 -26
  15. package/dist/features/dynamic-page-transition.d.ts +19 -30
  16. package/dist/features/dynamic-page-transition.js +21 -209
  17. package/dist/features/footer-taglist.d.ts +1 -1
  18. package/dist/features/footer-taglist.js +1 -1
  19. package/dist/features/footer.d.ts +3 -2
  20. package/dist/features/footer.js +3 -2
  21. package/dist/features/i18n.d.ts +13 -8
  22. package/dist/features/i18n.js +14 -9
  23. package/dist/features/image-enlarge.d.ts +7 -26
  24. package/dist/features/image-enlarge.js +7 -26
  25. package/dist/features/llms-txt.d.ts +3 -5
  26. package/dist/features/llms-txt.js +3 -5
  27. package/dist/features/search.d.ts +7 -3
  28. package/dist/features/search.js +7 -3
  29. package/dist/features/sidebar-resizer.d.ts +4 -8
  30. package/dist/features/sidebar-resizer.js +4 -8
  31. package/dist/features/sidebar-toggle.d.ts +7 -7
  32. package/dist/features/sidebar-toggle.js +7 -7
  33. package/dist/features/tag-governance.d.ts +14 -7
  34. package/dist/features/tag-governance.js +52 -8
  35. package/dist/features/tauri.d.ts +13 -10
  36. package/dist/features/tauri.js +16 -52
  37. package/dist/features/versioning.d.ts +12 -24
  38. package/dist/features/versioning.js +13 -39
  39. package/dist/index.js +2 -3
  40. package/dist/preset.d.ts +1 -0
  41. package/dist/preset.js +5 -0
  42. package/dist/prompts.d.ts +2 -0
  43. package/dist/prompts.js +1 -0
  44. package/dist/scaffold.d.ts +13 -6
  45. package/dist/scaffold.js +78 -59
  46. package/dist/utils.d.ts +10 -0
  47. package/dist/utils.js +14 -0
  48. package/dist/zfb-config-gen.d.ts +32 -20
  49. package/dist/zfb-config-gen.js +400 -53
  50. package/package.json +2 -2
  51. package/templates/base/pages/docs/[[...slug]].tsx +59 -0
  52. package/templates/base/pages/index.tsx +6 -41
  53. package/templates/base/scripts/setup-doc-skill.sh +261 -0
  54. package/templates/base/src/styles/global.css +15 -340
  55. package/templates/base/tsconfig.json +3 -26
  56. package/templates/features/i18n/files/pages/[locale]/docs/[[...slug]].tsx +88 -0
  57. package/templates/features/tagGovernance/files/scripts/tags-suggest.ts +3 -1
  58. package/dist/settings-gen.d.ts +0 -2
  59. package/dist/settings-gen.js +0 -319
  60. package/templates/base/.htmlvalidate.json +0 -5
  61. package/templates/base/.zfb/doc-history-meta.json +0 -1
  62. package/templates/base/pages/_data.ts +0 -160
  63. package/templates/base/pages/lib/_body-end-islands.tsx +0 -165
  64. package/templates/base/pages/lib/_chrome.ts +0 -167
  65. package/templates/base/pages/lib/_details.tsx +0 -29
  66. package/templates/base/pages/lib/_doc-route-entries.ts +0 -10
  67. package/templates/base/pages/lib/_extract-headings.ts +0 -37
  68. package/templates/base/pages/lib/_frontmatter-preview-data.ts +0 -27
  69. package/templates/base/pages/lib/_nav-source-cache.ts +0 -100
  70. package/templates/base/pages/lib/_nav-source-docs.ts +0 -17
  71. package/templates/base/pages/lib/_preset-generator.tsx +0 -81
  72. package/templates/base/pages/lib/_route-context.ts +0 -32
  73. package/templates/base/pages/lib/_search-widget.tsx +0 -17
  74. package/templates/base/pages/lib/doc-page-props.ts +0 -30
  75. package/templates/base/pages/lib/locale-merge.ts +0 -59
  76. package/templates/base/scripts/run-b4push.sh +0 -102
  77. package/templates/base/src/components/ai-chat-modal.tsx +0 -18
  78. package/templates/base/src/components/content/code-group.tsx +0 -3
  79. package/templates/base/src/components/content/content-admonition.tsx +0 -4
  80. package/templates/base/src/components/desktop-sidebar-toggle.tsx +0 -15
  81. package/templates/base/src/components/doc-history.tsx +0 -21
  82. package/templates/base/src/components/image-enlarge.tsx +0 -24
  83. package/templates/base/src/components/preset-generator.tsx +0 -14
  84. package/templates/base/src/components/sidebar-toggle.tsx +0 -6
  85. package/templates/base/src/components/sidebar-tree.tsx +0 -6
  86. package/templates/base/src/config/color-scheme-utils.ts +0 -69
  87. package/templates/base/src/config/color-schemes.ts +0 -165
  88. package/templates/base/src/config/docs-schema.ts +0 -95
  89. package/templates/base/src/config/frontmatter-preview-defaults.ts +0 -27
  90. package/templates/base/src/config/frontmatter-preview-renderers.tsx +0 -46
  91. package/templates/base/src/config/i18n.ts +0 -239
  92. package/templates/base/src/config/settings-types.ts +0 -45
  93. package/templates/base/src/config/sidebars.ts +0 -66
  94. package/templates/base/src/config/tag-vocabulary-types.ts +0 -4
  95. package/templates/base/src/config/tag-vocabulary.ts +0 -20
  96. package/templates/base/src/config/z-index-tokens.ts +0 -128
  97. package/templates/base/src/types/docs-entry.ts +0 -28
  98. package/templates/base/src/types/heading.ts +0 -5
  99. package/templates/base/src/types/locale.ts +0 -10
  100. package/templates/base/src/utils/base.ts +0 -164
  101. package/templates/base/src/utils/docs.ts +0 -446
  102. package/templates/base/src/utils/git-info.ts +0 -70
  103. package/templates/base/src/utils/github.ts +0 -22
  104. package/templates/base/src/utils/nav-scope.ts +0 -34
  105. package/templates/base/src/utils/sidebar.ts +0 -36
  106. package/templates/base/src/utils/slug.ts +0 -10
  107. package/templates/base/src/utils/smart-break.tsx +0 -12
  108. package/templates/base/src/utils/tags.ts +0 -83
  109. package/templates/base/zfb-shim.d.ts +0 -178
  110. package/templates/features/bodyFootUtil/files/src/utils/github.ts +0 -22
  111. package/templates/features/claudeResources/files/src/integrations/claude-resources/__tests__/escape-for-mdx.test.ts +0 -42
  112. package/templates/features/claudeResources/files/src/integrations/claude-resources/__tests__/generate.test.ts +0 -752
  113. package/templates/features/claudeResources/files/src/integrations/claude-resources/escape-for-mdx.ts +0 -97
  114. package/templates/features/claudeResources/files/src/integrations/claude-resources/generate.ts +0 -735
  115. package/templates/features/designTokenPanel/files/src/components/design-token-panel-bootstrap.tsx +0 -15
  116. package/templates/features/designTokenPanel/files/src/config/design-token-panel-config.ts +0 -435
  117. package/templates/features/designTokenPanel/files/src/config/design-tokens-manifest.ts +0 -174
  118. package/templates/features/designTokenPanel/files/src/lib/design-token-panel-bootstrap.ts +0 -30
  119. package/templates/features/docHistory/files/src/components/doc-history.tsx +0 -10
  120. package/templates/features/docHistory/files/src/types/doc-history.ts +0 -7
  121. package/templates/features/dynamicPageTransition/files/src/components/client-router-bootstrap.tsx +0 -72
  122. package/templates/features/i18n/files/pages/[locale]/index.tsx +0 -72
  123. package/templates/features/imageEnlarge/files/src/components/image-enlarge.tsx +0 -11
  124. package/templates/features/sidebarToggle/files/src/components/desktop-sidebar-toggle.tsx +0 -6
  125. package/templates/features/tauri/files/src/components/find-bar.tsx +0 -122
  126. package/templates/features/tauri/files/src/components/find-in-page-init.tsx +0 -59
  127. package/templates/features/tauri/files/src/utils/find-in-page.ts +0 -175
@@ -1,9 +1,13 @@
1
1
  /**
2
2
  * Search feature.
3
3
  *
4
- * W7A (#1736): post-cutover, `pages/lib/_header-with-defaults.tsx` includes
5
- * the search widget unconditionallyno header injection is required.
6
- * The search-index plugin is still wired by `zfb-config-gen.ts`.
4
+ * The `@takazudo/zudo-doc/plugins/search-index` plugin runs unconditionally
5
+ * (every project gets a `search-index.json`) `zudoDocPreset()` always
6
+ * wires it. This feature only controls whether the header shows the search
7
+ * trigger (`{ type: "component", component: "search" }` in
8
+ * `headerRightItems`, see `zfb-config-gen.ts`) — the widget itself is
9
+ * package-owned (`chrome/derive.tsx`'s `SearchWidget`), so there is nothing
10
+ * left to inject.
7
11
  */
8
12
  export const searchFeature = () => ({
9
13
  name: "search",
@@ -2,13 +2,9 @@ import type { FeatureModule } from "../compose.js";
2
2
  /**
3
3
  * Sidebar-resizer feature.
4
4
  *
5
- * W7A (#1736): post-cutover, sidebar resizer pre-paint scripts and runtime
6
- * initialization are runtime-gated on `settings.sidebarResizer` inside the
7
- * pages/lib wrappers — no doc-layout injection is required.
8
- *
9
- * NOTE: spec-lock §6.5 flagged a pre-paint FOUC question for the
10
- * `applySidebarWidth` IIFE that previously ran inline in the layout `<head>`.
11
- * The post-cutover model relies on the pages/lib head wrapper emitting the
12
- * inline script (when present); this feature module no longer injects it.
5
+ * Purely a `zudoDoc({ sidebarResizer: true })` field (see `zfb-config-gen.ts`)
6
+ * the pre-paint script and runtime init are package-owned
7
+ * (`sidebar-resizer/sidebar-resizer-init.tsx`), gated on `settings.sidebarResizer`
8
+ * inside the package's own chrome. Nothing to inject.
13
9
  */
14
10
  export declare const sidebarResizerFeature: FeatureModule;
@@ -1,14 +1,10 @@
1
1
  /**
2
2
  * Sidebar-resizer feature.
3
3
  *
4
- * W7A (#1736): post-cutover, sidebar resizer pre-paint scripts and runtime
5
- * initialization are runtime-gated on `settings.sidebarResizer` inside the
6
- * pages/lib wrappers — no doc-layout injection is required.
7
- *
8
- * NOTE: spec-lock §6.5 flagged a pre-paint FOUC question for the
9
- * `applySidebarWidth` IIFE that previously ran inline in the layout `<head>`.
10
- * The post-cutover model relies on the pages/lib head wrapper emitting the
11
- * inline script (when present); this feature module no longer injects it.
4
+ * Purely a `zudoDoc({ sidebarResizer: true })` field (see `zfb-config-gen.ts`)
5
+ * the pre-paint script and runtime init are package-owned
6
+ * (`sidebar-resizer/sidebar-resizer-init.tsx`), gated on `settings.sidebarResizer`
7
+ * inside the package's own chrome. Nothing to inject.
12
8
  */
13
9
  export const sidebarResizerFeature = () => ({
14
10
  name: "sidebarResizer",
@@ -2,12 +2,12 @@ import type { FeatureModule } from "../compose.js";
2
2
  /**
3
3
  * Sidebar-toggle feature.
4
4
  *
5
- * W7A (#1736): post-cutover, the sidebar-toggle is hosted by the pages/lib
6
- * wrappers which runtime-gate on `settings.sidebarToggle`. The supporting
7
- * CSS (toggle button positioning, sidebar transitions, `[data-sidebar-hidden]`
8
- * styles) lives unconditionally in `templates/base/src/styles/global.css`
9
- * — the selectors only match when the runtime attaches the
10
- * `data-sidebar-hidden` attribute or mounts the toggle button, so the cost
11
- * to scaffolds without the feature is one inert rule block.
5
+ * Purely a `zudoDoc({ sidebarToggle: true })` field (see `zfb-config-gen.ts`).
6
+ * `DesktopSidebarToggle` is fully package-owned
7
+ * (`@takazudo/zudo-doc/desktop-sidebar-toggle-island`, wired into
8
+ * Header/Sidebar directly) and its CSS ships unconditionally from
9
+ * `@takazudo/zudo-doc/features.css` — the old host re-export shim
10
+ * (`src/components/desktop-sidebar-toggle.tsx`) is gone; nothing to inject
11
+ * or copy.
12
12
  */
13
13
  export declare const sidebarToggleFeature: FeatureModule;
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Sidebar-toggle feature.
3
3
  *
4
- * W7A (#1736): post-cutover, the sidebar-toggle is hosted by the pages/lib
5
- * wrappers which runtime-gate on `settings.sidebarToggle`. The supporting
6
- * CSS (toggle button positioning, sidebar transitions, `[data-sidebar-hidden]`
7
- * styles) lives unconditionally in `templates/base/src/styles/global.css`
8
- * — the selectors only match when the runtime attaches the
9
- * `data-sidebar-hidden` attribute or mounts the toggle button, so the cost
10
- * to scaffolds without the feature is one inert rule block.
4
+ * Purely a `zudoDoc({ sidebarToggle: true })` field (see `zfb-config-gen.ts`).
5
+ * `DesktopSidebarToggle` is fully package-owned
6
+ * (`@takazudo/zudo-doc/desktop-sidebar-toggle-island`, wired into
7
+ * Header/Sidebar directly) and its CSS ships unconditionally from
8
+ * `@takazudo/zudo-doc/features.css` — the old host re-export shim
9
+ * (`src/components/desktop-sidebar-toggle.tsx`) is gone; nothing to inject
10
+ * or copy.
11
11
  */
12
12
  export const sidebarToggleFeature = () => ({
13
13
  name: "sidebarToggle",
@@ -2,13 +2,20 @@ import type { FeatureModule } from "../compose.js";
2
2
  /**
3
3
  * Tag governance feature.
4
4
  *
5
- * Ships the tag audit and suggest scripts. Settings (`tagVocabulary`,
6
- * `tagGovernance`) are emitted by `settings-gen.ts`; devDeps and
7
- * `tags:audit` / `tags:suggest` package scripts are added in
8
- * `scaffold.ts#generatePackageJson`.
5
+ * Ships `scripts/tags-audit.ts` / `scripts/tags-suggest.ts` (unconditional
6
+ * feature-file copy, `templates/features/tagGovernance/files/`) plus the
7
+ * settings fields (`tagGovernance`, `tagVocabulary`, `tagVocabularyEntries`)
8
+ * `zfb-config-gen.ts` writes straight into `zfb.config.ts`.
9
9
  *
10
- * `src/config/tag-vocabulary.ts` and `tag-vocabulary-types.ts` stay in the
11
- * base template because `src/utils/tags.ts` and `settings-types.ts` import
12
- * from them regardless of whether governance is on.
10
+ * One genuine remaining coupling (minimal-scaffold cutover, epic
11
+ * zudolab/zudo-doc#2651): `@takazudo/zudo-doc`'s `tags-audit` bin
12
+ * (`packages/zudo-doc/bin/tags-audit-runner.ts`) still dynamically
13
+ * `import()`s `src/config/settings.ts` and `src/config/tag-vocabulary.ts`
14
+ * BY PATH — a legacy contract that predates the single-`zfb.config.ts`
15
+ * model and hasn't been updated for it (out of this generator's scope; a
16
+ * package-level follow-up could remove it). So `tagGovernance` is the one
17
+ * feature that still needs a tiny `src/config/` pair — this postProcess
18
+ * writes both, sourced from the SAME `choices` the main `zfb.config.ts`
19
+ * generation reads, so the two can't drift.
13
20
  */
14
21
  export declare const tagGovernanceFeature: FeatureModule;
@@ -1,16 +1,60 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ import { getSecondaryLang } from "../utils.js";
1
4
  /**
2
5
  * Tag governance feature.
3
6
  *
4
- * Ships the tag audit and suggest scripts. Settings (`tagVocabulary`,
5
- * `tagGovernance`) are emitted by `settings-gen.ts`; devDeps and
6
- * `tags:audit` / `tags:suggest` package scripts are added in
7
- * `scaffold.ts#generatePackageJson`.
7
+ * Ships `scripts/tags-audit.ts` / `scripts/tags-suggest.ts` (unconditional
8
+ * feature-file copy, `templates/features/tagGovernance/files/`) plus the
9
+ * settings fields (`tagGovernance`, `tagVocabulary`, `tagVocabularyEntries`)
10
+ * `zfb-config-gen.ts` writes straight into `zfb.config.ts`.
8
11
  *
9
- * `src/config/tag-vocabulary.ts` and `tag-vocabulary-types.ts` stay in the
10
- * base template because `src/utils/tags.ts` and `settings-types.ts` import
11
- * from them regardless of whether governance is on.
12
+ * One genuine remaining coupling (minimal-scaffold cutover, epic
13
+ * zudolab/zudo-doc#2651): `@takazudo/zudo-doc`'s `tags-audit` bin
14
+ * (`packages/zudo-doc/bin/tags-audit-runner.ts`) still dynamically
15
+ * `import()`s `src/config/settings.ts` and `src/config/tag-vocabulary.ts`
16
+ * BY PATH — a legacy contract that predates the single-`zfb.config.ts`
17
+ * model and hasn't been updated for it (out of this generator's scope; a
18
+ * package-level follow-up could remove it). So `tagGovernance` is the one
19
+ * feature that still needs a tiny `src/config/` pair — this postProcess
20
+ * writes both, sourced from the SAME `choices` the main `zfb.config.ts`
21
+ * generation reads, so the two can't drift.
12
22
  */
13
- export const tagGovernanceFeature = () => ({
23
+ export const tagGovernanceFeature = (choices) => ({
14
24
  name: "tagGovernance",
15
25
  injections: [],
26
+ postProcess: async (targetDir) => {
27
+ const vocabPath = path.join(targetDir, "src/config/tag-vocabulary.ts");
28
+ if (!(await fs.pathExists(vocabPath))) {
29
+ await fs.outputFile(vocabPath, `import type { TagVocabularyEntry } from "@takazudo/zudo-doc/settings";
30
+
31
+ // Starter (empty) tag vocabulary — add an entry per tag you use in doc
32
+ // frontmatter so \`pnpm tags:audit\` can validate it. Shared by
33
+ // zfb.config.ts (tagVocabularyEntries) and scripts/tags-audit.ts /
34
+ // scripts/tags-suggest.ts — this file is the single source of truth.
35
+ export const tagVocabulary: TagVocabularyEntry[] = [];
36
+ `);
37
+ }
38
+ const settingsPath = path.join(targetDir, "src/config/settings.ts");
39
+ if (!(await fs.pathExists(settingsPath))) {
40
+ const locales = choices.features.includes("i18n")
41
+ ? `{ ${getSecondaryLang(choices.defaultLang)}: { dir: "src/content/docs-${getSecondaryLang(choices.defaultLang)}" } }`
42
+ : `{}`;
43
+ await fs.outputFile(settingsPath, `// Minimal settings mirror consumed ONLY by @takazudo/zudo-doc's
44
+ // tags-audit bin (packages/zudo-doc/bin/tags-audit-runner.ts), which
45
+ // dynamically imports this exact path — a legacy coupling that predates the
46
+ // single zfb.config.ts model (see the tagGovernance feature module for the
47
+ // full note). Keep these four fields in sync with the matching zudoDoc({...})
48
+ // fields in zfb.config.ts — both are generated from the same choices at
49
+ // scaffold time, so a fresh scaffold never drifts; hand-edit both if you
50
+ // change either one later.
51
+ export const settings = {
52
+ docsDir: "src/content/docs",
53
+ tagGovernance: "warn" as const,
54
+ tagVocabulary: true,
55
+ locales: ${locales},
56
+ };
57
+ `);
58
+ }
59
+ },
16
60
  });
@@ -2,15 +2,18 @@ import type { FeatureModule } from "../compose.js";
2
2
  /**
3
3
  * Tauri feature.
4
4
  *
5
- * #2052: the FindInPageInit island (Cmd/Ctrl+F find bar for the Tauri
6
- * WebView, where the browser-native find UI is unavailable) is wired into
7
- * `pages/lib/_body-end-islands.tsx` via the three injections below — import,
8
- * displayName, and Island mount. zfb's island scanner only registers
9
- * components reachable through static import chains (page wrapper →
10
- * component), so without this injection the feature-copied component files
11
- * are orphaned dead code that never hydrates. The find-match highlight CSS
12
- * is unconditional in `templates/base/src/styles/global.css` (matches host);
13
- * the component runtime-gates itself (renders null unless
14
- * `window.__TAURI_INTERNALS__` exists), so no settings field is needed.
5
+ * Minimal-scaffold cutover (epic zudolab/zudo-doc#2651, Wave 6 #2660): the
6
+ * `src-tauri/**` Rust shell is a genuine, unconditional file copy (no
7
+ * package equivalent kept exactly as before).
8
+ *
9
+ * The FindInPageInit island (Cmd/Ctrl+F find bar, #2052) is now
10
+ * package-owned (`@takazudo/zudo-doc`, #2689) instead of a template file
11
+ * copy `zfb-config-gen.ts`'s `buildDesiredConfig()` sets
12
+ * `findInPage: true` whenever this feature is selected (#2690), which mounts
13
+ * the package's `FindInPageInit` island via `zudoDocPreset()`. There is no
14
+ * separate `findInPage` feature module or CLI flag; it rides this one. The
15
+ * island self-gates on `window.__TAURI_INTERNALS__`, so it's a safe no-op in
16
+ * a plain browser build even though `findInPage: true` is unconditionally
17
+ * emitted for every tauri-feature scaffold.
15
18
  */
16
19
  export declare const tauriFeature: FeatureModule;
@@ -1,60 +1,26 @@
1
1
  import fs from "fs-extra";
2
2
  import path from "path";
3
+ import { pmRunCommand } from "../utils.js";
3
4
  /**
4
5
  * Tauri feature.
5
6
  *
6
- * #2052: the FindInPageInit island (Cmd/Ctrl+F find bar for the Tauri
7
- * WebView, where the browser-native find UI is unavailable) is wired into
8
- * `pages/lib/_body-end-islands.tsx` via the three injections below — import,
9
- * displayName, and Island mount. zfb's island scanner only registers
10
- * components reachable through static import chains (page wrapper →
11
- * component), so without this injection the feature-copied component files
12
- * are orphaned dead code that never hydrates. The find-match highlight CSS
13
- * is unconditional in `templates/base/src/styles/global.css` (matches host);
14
- * the component runtime-gates itself (renders null unless
15
- * `window.__TAURI_INTERNALS__` exists), so no settings field is needed.
7
+ * Minimal-scaffold cutover (epic zudolab/zudo-doc#2651, Wave 6 #2660): the
8
+ * `src-tauri/**` Rust shell is a genuine, unconditional file copy (no
9
+ * package equivalent kept exactly as before).
10
+ *
11
+ * The FindInPageInit island (Cmd/Ctrl+F find bar, #2052) is now
12
+ * package-owned (`@takazudo/zudo-doc`, #2689) instead of a template file
13
+ * copy `zfb-config-gen.ts`'s `buildDesiredConfig()` sets
14
+ * `findInPage: true` whenever this feature is selected (#2690), which mounts
15
+ * the package's `FindInPageInit` island via `zudoDocPreset()`. There is no
16
+ * separate `findInPage` feature module or CLI flag; it rides this one. The
17
+ * island self-gates on `window.__TAURI_INTERNALS__`, so it's a safe no-op in
18
+ * a plain browser build even though `findInPage: true` is unconditionally
19
+ * emitted for every tauri-feature scaffold.
16
20
  */
17
21
  export const tauriFeature = (choices) => ({
18
22
  name: "tauri",
19
- injections: [
20
- // 1. Import the island entry. Inserted AFTER the
21
- // `// @slot:body-end-islands:imports` anchor.
22
- {
23
- file: "pages/lib/_body-end-islands.tsx",
24
- anchor: "// @slot:body-end-islands:imports",
25
- position: "after",
26
- content: `import FindInPageInit from "@/components/find-in-page-init";`,
27
- },
28
- // 2. Stable island marker name (same belt-and-braces guard as the
29
- // sibling islands in the file). Inserted AFTER the
30
- // `// @slot:body-end-islands:display-names` anchor.
31
- {
32
- file: "pages/lib/_body-end-islands.tsx",
33
- anchor: "// @slot:body-end-islands:display-names",
34
- position: "after",
35
- content: `(FindInPageInit as { displayName?: string }).displayName = "FindInPageInit";`,
36
- },
37
- // 3. Island mount. Inserted AFTER the
38
- // `{/* @slot:body-end-islands:extra-islands */}` anchor.
39
- // when="load" (not "idle"): the island's job is to intercept
40
- // Cmd/Ctrl+F via a keydown listener, so it must hydrate as soon as
41
- // the islands runtime mounts — same rationale as the
42
- // clientRouterBootstrap click intercept above it. Deferring to idle
43
- // would leave a post-load window where Cmd+F does nothing, which is
44
- // the very bug this injection fixes.
45
- {
46
- file: "pages/lib/_body-end-islands.tsx",
47
- anchor: "{/* @slot:body-end-islands:extra-islands */}",
48
- position: "after",
49
- content: ` {/* Tauri-only find-in-page (Cmd/Ctrl+F) bar. Renders null outside
50
- a Tauri WebView, so the island is inert in plain browser builds
51
- of the same scaffold. */}
52
- {Island({
53
- when: "load",
54
- children: <FindInPageInit />,
55
- }) as unknown as VNode}`,
56
- },
57
- ],
23
+ injections: [],
58
24
  postProcess: async (targetDir) => {
59
25
  // Patch Cargo.toml package name
60
26
  const cargoPath = path.join(targetDir, "src-tauri/Cargo.toml");
@@ -76,9 +42,7 @@ export const tauriFeature = (choices) => ({
76
42
  content = content.replace(/"productName": "ZudoDoc"/, `"productName": "${productName}"`);
77
43
  content = content.replace(/"identifier": "com.zudolab.zudo-doc"/, `"identifier": "${identifier}"`);
78
44
  // Patch beforeDevCommand for the chosen package manager
79
- const devCmd = choices.packageManager === "npm" || choices.packageManager === "bun"
80
- ? `${choices.packageManager} run dev`
81
- : `${choices.packageManager} dev`;
45
+ const devCmd = pmRunCommand(choices.packageManager, "dev");
82
46
  content = content.replace(/"beforeDevCommand": "pnpm dev"/, `"beforeDevCommand": "${devCmd}"`);
83
47
  await fs.writeFile(confPath, content);
84
48
  }
@@ -2,30 +2,18 @@ import type { FeatureModule } from "../compose.js";
2
2
  /**
3
3
  * Versioning feature.
4
4
  *
5
- * The pages/lib wrappers gate `VersionSwitcher` and `VersionBanner` on
6
- * `settings.versions`. Doc-layout flow is handled by route enumerators +
7
- * `_inline-version-switcher.tsx`. This feature copies versioning page
8
- * templates from `templates/features/versioning/files/` via
9
- * `copyFeatureFiles` (compose.ts), and injects nothing into `global.css`.
5
+ * Purely a `zudoDoc({ versions: [] })` field (see `zfb-config-gen.ts`) — the
6
+ * versioned doc routes (`/docs/versions`, `/v/[version]/docs/[[...slug]]`,
7
+ * and their i18n counterparts) are PACKAGE-INJECTED
8
+ * (`settings.packageOwnedRoutes`, default on) and render through the shared
9
+ * `renderDocPage` chrome. `templates/features/versioning/files/` has been
10
+ * empty since #2390 — there is no host stub left to copy or postProcess.
10
11
  *
11
- * W7C (#1738): the versioning feature ships pages under
12
- * `templates/features/versioning/files/pages/`:
13
- *
14
- * lib/_versions-page.tsx (always versions-listing renderer)
15
- *
16
- * The versioned DOC routes `/docs/versions`, `/v/[version]/docs/[[...slug]]`,
17
- * and `/v/[version]/[locale]/docs/[[...slug]]` — are now PACKAGE-INJECTED
18
- * (packageOwnedRoutes); their host catch-all stubs were deleted from the
19
- * template in #2390 (supersedes #2377) so generated projects render them via
20
- * injection through `@takazudo/zudo-doc`'s `_chrome` chrome (which wires the
21
- * MDX content components). The package route is the functional equivalent of
22
- * the old stub (it enumerates `settings.versions` and renders via the shared
23
- * `renderDocPage`).
24
- *
25
- * `copyFeatureFiles` (compose.ts) auto-copies everything under `files/`.
26
- * postProcess is now a defensive no-op: the i18n-gated stubs it strips
27
- * (`[locale]/docs/versions.tsx`, `v/[version]/[locale]/**`) no longer ship in
28
- * the template, but the cleanup is kept so a re-added stub can never leak an
29
- * orphan locale route into a single-locale project.
12
+ * Known limitation (pre-existing, not introduced by the minimal-scaffold
13
+ * cutover — inherited from the same injected-DYNAMIC-route dev-mode gap the
14
+ * locked manifest's `pages/docs/[[...slug]].tsx` stub exists to fix for the
15
+ * primary doc route, tracked as a #2667 follow-up): the versioned doc
16
+ * routes may still 404 in `zfb dev` since versioning has no stub of its own
17
+ * in the locked manifest. `zfb build` is unaffected.
30
18
  */
31
19
  export declare const versioningFeature: FeatureModule;
@@ -1,47 +1,21 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
1
  /**
4
2
  * Versioning feature.
5
3
  *
6
- * The pages/lib wrappers gate `VersionSwitcher` and `VersionBanner` on
7
- * `settings.versions`. Doc-layout flow is handled by route enumerators +
8
- * `_inline-version-switcher.tsx`. This feature copies versioning page
9
- * templates from `templates/features/versioning/files/` via
10
- * `copyFeatureFiles` (compose.ts), and injects nothing into `global.css`.
4
+ * Purely a `zudoDoc({ versions: [] })` field (see `zfb-config-gen.ts`) — the
5
+ * versioned doc routes (`/docs/versions`, `/v/[version]/docs/[[...slug]]`,
6
+ * and their i18n counterparts) are PACKAGE-INJECTED
7
+ * (`settings.packageOwnedRoutes`, default on) and render through the shared
8
+ * `renderDocPage` chrome. `templates/features/versioning/files/` has been
9
+ * empty since #2390 — there is no host stub left to copy or postProcess.
11
10
  *
12
- * W7C (#1738): the versioning feature ships pages under
13
- * `templates/features/versioning/files/pages/`:
14
- *
15
- * lib/_versions-page.tsx (always versions-listing renderer)
16
- *
17
- * The versioned DOC routes `/docs/versions`, `/v/[version]/docs/[[...slug]]`,
18
- * and `/v/[version]/[locale]/docs/[[...slug]]` — are now PACKAGE-INJECTED
19
- * (packageOwnedRoutes); their host catch-all stubs were deleted from the
20
- * template in #2390 (supersedes #2377) so generated projects render them via
21
- * injection through `@takazudo/zudo-doc`'s `_chrome` chrome (which wires the
22
- * MDX content components). The package route is the functional equivalent of
23
- * the old stub (it enumerates `settings.versions` and renders via the shared
24
- * `renderDocPage`).
25
- *
26
- * `copyFeatureFiles` (compose.ts) auto-copies everything under `files/`.
27
- * postProcess is now a defensive no-op: the i18n-gated stubs it strips
28
- * (`[locale]/docs/versions.tsx`, `v/[version]/[locale]/**`) no longer ship in
29
- * the template, but the cleanup is kept so a re-added stub can never leak an
30
- * orphan locale route into a single-locale project.
11
+ * Known limitation (pre-existing, not introduced by the minimal-scaffold
12
+ * cutover — inherited from the same injected-DYNAMIC-route dev-mode gap the
13
+ * locked manifest's `pages/docs/[[...slug]].tsx` stub exists to fix for the
14
+ * primary doc route, tracked as a #2667 follow-up): the versioned doc
15
+ * routes may still 404 in `zfb dev` since versioning has no stub of its own
16
+ * in the locked manifest. `zfb build` is unaffected.
31
17
  */
32
- export const versioningFeature = (choices) => ({
18
+ export const versioningFeature = () => ({
33
19
  name: "versioning",
34
- postProcess: async (targetDir) => {
35
- if (!choices.features.includes("i18n")) {
36
- const localeVersions = path.join(targetDir, "pages", "[locale]", "docs", "versions.tsx");
37
- if (await fs.pathExists(localeVersions)) {
38
- await fs.remove(localeVersions);
39
- }
40
- const localeVersionedDocs = path.join(targetDir, "pages", "v", "[version]", "[locale]");
41
- if (await fs.pathExists(localeVersionedDocs)) {
42
- await fs.remove(localeVersionedDocs);
43
- }
44
- }
45
- },
46
20
  injections: [],
47
21
  });
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { FEATURES } from "./constants.js";
6
6
  import { loadPreset } from "./preset.js";
7
7
  import { runPrompts } from "./prompts.js";
8
8
  import { scaffold } from "./scaffold.js";
9
- import { installDependencies, initGitRepo } from "./utils.js";
9
+ import { installDependencies, initGitRepo, pmRunCommand } from "./utils.js";
10
10
  async function main() {
11
11
  const args = parseArgs();
12
12
  // Handle --help
@@ -173,8 +173,7 @@ async function main() {
173
173
  console.log();
174
174
  console.log(` ${pc.bold("Next steps:")}`);
175
175
  console.log(` cd ${choices.projectName}`);
176
- const runCmd = choices.packageManager === "npm" ? "npm run" : choices.packageManager;
177
- console.log(` ${runCmd} dev`);
176
+ console.log(` ${pmRunCommand(choices.packageManager, "dev")}`);
178
177
  console.log();
179
178
  }
180
179
  main().catch((err) => {
package/dist/preset.d.ts CHANGED
@@ -38,6 +38,7 @@ export interface PresetJson {
38
38
  features?: string[];
39
39
  githubUrl?: string;
40
40
  cjkFriendly?: boolean;
41
+ minifyHtml?: boolean;
41
42
  packageManager?: "pnpm" | "npm" | "yarn" | "bun";
42
43
  headerRightItems?: PresetHeaderRightItem[];
43
44
  metaTags?: PresetMetaTagsConfig;
package/dist/preset.js CHANGED
@@ -72,6 +72,9 @@ export function validatePreset(json) {
72
72
  if (p.cjkFriendly !== undefined && typeof p.cjkFriendly !== "boolean") {
73
73
  return `"cjkFriendly" must be a boolean in preset`;
74
74
  }
75
+ if (p.minifyHtml !== undefined && typeof p.minifyHtml !== "boolean") {
76
+ return `"minifyHtml" must be a boolean in preset`;
77
+ }
75
78
  if (p.headerRightItems !== undefined) {
76
79
  if (!Array.isArray(p.headerRightItems)) {
77
80
  return `"headerRightItems" must be an array in preset`;
@@ -177,6 +180,8 @@ export function presetToChoices(json) {
177
180
  choices.githubUrl = json.githubUrl;
178
181
  if (json.cjkFriendly !== undefined)
179
182
  choices.cjkFriendly = json.cjkFriendly;
183
+ if (json.minifyHtml !== undefined)
184
+ choices.minifyHtml = json.minifyHtml;
180
185
  if (json.headerRightItems !== undefined) {
181
186
  choices.headerRightItems = json.headerRightItems;
182
187
  }
package/dist/prompts.d.ts CHANGED
@@ -12,6 +12,7 @@ export interface UserChoices {
12
12
  explicitlyDisabledFeatures?: string[];
13
13
  githubUrl?: string;
14
14
  cjkFriendly?: boolean;
15
+ minifyHtml?: boolean;
15
16
  packageManager: "pnpm" | "npm" | "yarn" | "bun";
16
17
  headerRightItems?: PresetHeaderRightItem[];
17
18
  metaTags?: PresetMetaTagsConfig;
@@ -29,6 +30,7 @@ export interface PartialChoices {
29
30
  explicitlyDisabledFeatures?: string[];
30
31
  githubUrl?: string;
31
32
  cjkFriendly?: boolean;
33
+ minifyHtml?: boolean;
32
34
  packageManager?: "pnpm" | "npm" | "yarn" | "bun";
33
35
  headerRightItems?: PresetHeaderRightItem[];
34
36
  metaTags?: PresetMetaTagsConfig;
package/dist/prompts.js CHANGED
@@ -200,6 +200,7 @@ export async function runPrompts(prefilled = {}) {
200
200
  explicitlyDisabledFeatures: prefilled.explicitlyDisabledFeatures,
201
201
  githubUrl,
202
202
  cjkFriendly: prefilled.cjkFriendly,
203
+ minifyHtml: prefilled.minifyHtml,
203
204
  packageManager,
204
205
  headerRightItems: prefilled.headerRightItems,
205
206
  metaTags: prefilled.metaTags,
@@ -2,14 +2,21 @@ import type { UserChoices } from "./prompts.js";
2
2
  import { getSecondaryLang } from "./utils.js";
3
3
  export { getSecondaryLang };
4
4
  /**
5
- * Pinned `@takazudo/zudo-doc` version used in both `generatePackageJson()`
6
- * and the `.zudo-doc.json` seed written by `scaffold()`. Hoisted as a shared
7
- * constant so the dep pin and the provenance seed can never drift.
5
+ * Pinned `@takazudo/zudo-doc` version used by `generatePackageJson()`.
6
+ * Hoisted as a shared constant (kept even though it now has a single
7
+ * call site) because `scripts/check-pin-parity.mjs` resolves this exact
8
+ * declaration below via its constant-reference regex form (see that
9
+ * script's `readScaffoldPin()`) — keep the declaration line's shape
10
+ * parseable (const name, `=`, a quoted literal) and do NOT repeat that
11
+ * exact pattern anywhere earlier in this file (a comment containing the
12
+ * literal text would false-match the same regex, since it isn't anchored
13
+ * to a real `export const` statement).
8
14
  *
9
- * Strip the caret from this string to get the bare version for provenance:
10
- * ZUDO_DOC_PIN.replace(/^\^/, "") → "1.0.0"
15
+ * `.zudo-doc.json` is NO LONGER seeded here (locked decision #2653 #6
16
+ * lazy-create on first `zudo-doc eject`; `packages/zudo-doc/src/eject/index.ts`
17
+ * already tolerates its absence and writes the file on first successful eject).
11
18
  *
12
19
  * Bumped in lockstep by scripts/release-create-zudo-doc.sh.
13
20
  */
14
- export declare const ZUDO_DOC_PIN = "^3.1.0";
21
+ export declare const ZUDO_DOC_PIN = "^3.3.0";
15
22
  export declare function scaffold(choices: UserChoices): Promise<void>;