create-zudo-doc 0.2.22 → 1.0.1

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 (28) hide show
  1. package/dist/compose.d.ts +6 -3
  2. package/dist/compose.js +6 -4
  3. package/dist/features/image-enlarge.d.ts +15 -13
  4. package/dist/features/image-enlarge.js +16 -192
  5. package/dist/scaffold.d.ts +11 -0
  6. package/dist/scaffold.js +52 -8
  7. package/dist/settings-gen.js +4 -0
  8. package/package.json +1 -1
  9. package/templates/base/pages/_mdx-components.ts +64 -185
  10. package/templates/base/pages/index.tsx +1 -1
  11. package/templates/base/pages/lib/_extract-headings.ts +21 -295
  12. package/templates/base/pages/lib/_math-block.tsx +4 -63
  13. package/templates/base/src/components/content/code-group.tsx +3 -76
  14. package/templates/base/src/components/content/content-admonition.tsx +4 -56
  15. package/templates/base/src/config/settings-types.ts +34 -172
  16. package/templates/base/src/styles/global.css +35 -8
  17. package/templates/features/i18n/files/pages/[locale]/index.tsx +1 -1
  18. package/templates/base/pages/404.tsx +0 -61
  19. package/templates/base/pages/robots.txt.tsx +0 -5
  20. package/templates/base/pages/sitemap.xml.tsx +0 -59
  21. package/templates/base/plugins/copy-public-plugin.mjs +0 -58
  22. package/templates/base/src/components/site-tree-nav.tsx +0 -6
  23. package/templates/features/docTags/files/pages/[locale]/docs/tags/[tag].tsx +0 -59
  24. package/templates/features/docTags/files/pages/[locale]/docs/tags/index.tsx +0 -39
  25. package/templates/features/docTags/files/pages/docs/tags/[tag].tsx +0 -43
  26. package/templates/features/docTags/files/pages/docs/tags/index.tsx +0 -20
  27. package/templates/features/versioning/files/pages/[locale]/docs/versions.tsx +0 -48
  28. package/templates/features/versioning/files/pages/docs/versions.tsx +0 -20
package/dist/compose.d.ts CHANGED
@@ -75,9 +75,6 @@ export declare function validateDependencies(features: FeatureDefinition[], allS
75
75
  * `@import "@takazudo/zdtp/styles.css";` at `@slot:global-css:feature-styles`.
76
76
  * The sibling `@slot:global-css:theme-tokens` anchor is consumed by the
77
77
  * color-scheme palette generator and must remain.
78
- * - `pages/_mdx-components.ts` — image-enlarge.ts injects the
79
- * EnlargeableParagraph p-override (ENLARGE_SVG, EnlargeableParagraph def,
80
- * `p:` map entry) when imageEnlarge is enabled.
81
78
  * - `pages/lib/_body-end-islands.tsx` — tauri.ts injects the FindInPageInit
82
79
  * island (import, displayName, Island mount) when tauri is enabled.
83
80
  * design-token-panel.ts injects the DesignTokenPanelBootstrap island
@@ -86,6 +83,12 @@ export declare function validateDependencies(features: FeatureDefinition[], allS
86
83
  * - `src/config/settings-types.ts` — design-token-panel.ts injects the
87
84
  * `"design-token-panel"` member into `HeaderRightTriggerName` when the
88
85
  * feature is enabled (replace-range between the :start/:end anchors).
86
+ *
87
+ * NOTE: `pages/_mdx-components.ts` was removed (#2360 / E2). The imageEnlarge
88
+ * p-override injections (ENLARGE_SVG, EnlargeableParagraph, p: entry) are now
89
+ * handled inside the @takazudo/zudo-doc/mdx-components factory — the template
90
+ * no longer carries @slot anchors for this file and the feature module's
91
+ * injections are a no-op (the factory reads settings.imageEnlarge at render time).
89
92
  */
90
93
  export declare const ANCHOR_FILES: string[];
91
94
  /**
package/dist/compose.js CHANGED
@@ -161,9 +161,6 @@ export function validateDependencies(features, allSelectedNames) {
161
161
  * `@import "@takazudo/zdtp/styles.css";` at `@slot:global-css:feature-styles`.
162
162
  * The sibling `@slot:global-css:theme-tokens` anchor is consumed by the
163
163
  * color-scheme palette generator and must remain.
164
- * - `pages/_mdx-components.ts` — image-enlarge.ts injects the
165
- * EnlargeableParagraph p-override (ENLARGE_SVG, EnlargeableParagraph def,
166
- * `p:` map entry) when imageEnlarge is enabled.
167
164
  * - `pages/lib/_body-end-islands.tsx` — tauri.ts injects the FindInPageInit
168
165
  * island (import, displayName, Island mount) when tauri is enabled.
169
166
  * design-token-panel.ts injects the DesignTokenPanelBootstrap island
@@ -172,10 +169,15 @@ export function validateDependencies(features, allSelectedNames) {
172
169
  * - `src/config/settings-types.ts` — design-token-panel.ts injects the
173
170
  * `"design-token-panel"` member into `HeaderRightTriggerName` when the
174
171
  * feature is enabled (replace-range between the :start/:end anchors).
172
+ *
173
+ * NOTE: `pages/_mdx-components.ts` was removed (#2360 / E2). The imageEnlarge
174
+ * p-override injections (ENLARGE_SVG, EnlargeableParagraph, p: entry) are now
175
+ * handled inside the @takazudo/zudo-doc/mdx-components factory — the template
176
+ * no longer carries @slot anchors for this file and the feature module's
177
+ * injections are a no-op (the factory reads settings.imageEnlarge at render time).
175
178
  */
176
179
  export const ANCHOR_FILES = [
177
180
  "src/styles/global.css",
178
- "pages/_mdx-components.ts",
179
181
  "pages/lib/_body-end-islands.tsx",
180
182
  "src/config/settings-types.ts",
181
183
  ];
@@ -9,22 +9,24 @@ import type { FeatureModule } from "../compose.js";
9
9
  * `global.css` in S3 #2348) — the selectors only activate when the runtime
10
10
  * mounts the .zd-enlarge-btn.
11
11
  *
12
- * S2 (#1825): after zfb next.18 removed the built-in imageEnlarge Rust
13
- * feature, the server-side figure/button emission is re-implemented via an
14
- * MDX paragraph (p) component override in pages/_mdx-components.ts. When
15
- * imageEnlarge is enabled, three injections into the template file install:
16
- * 1. Additional imports: toChildArray + VNode from preact.
17
- * 2. ENLARGE_SVG const + EnlargeableParagraph function definition.
18
- * 3. `p: EnlargeableParagraph` entry in the createMdxComponents return map.
19
- * When imageEnlarge is OFF, none of these are injected, so the override is
20
- * absent and paragraphs render plain (the Rust built-in is gone "off" must
21
- * mean no wrapping at all).
12
+ * S2 (#1825): the server-side figure/button emission was re-implemented via an
13
+ * MDX paragraph (p) component override in pages/_mdx-components.ts. Three
14
+ * injections installed the ENLARGE_SVG + EnlargeableParagraph code when
15
+ * imageEnlarge was enabled.
16
+ *
17
+ * S8 / #2360 (E2): the full MDX component assembly moved into the
18
+ * @takazudo/zudo-doc/mdx-components factory (createMdxComponentsBase). The
19
+ * factory reads settings.imageEnlarge at render time and conditionally wraps
20
+ * block-level images in <figure class="zd-enlargeable"> the same logic the
21
+ * old injections installed, now handled once inside the package. The three
22
+ * _mdx-components.ts injections (enlarge-imports, enlarge-defs,
23
+ * enlarge-p-entry) are therefore removed; the feature is a no-op from the
24
+ * compose engine's perspective (the runtime gate in the factory is always
25
+ * present in the scaffolded template).
22
26
  *
23
27
  * S3 (#2348): the ImageEnlarge island and its SSR fallback moved from
24
28
  * src/components/image-enlarge.tsx into @takazudo/zudo-doc/image-enlarge.
25
29
  * The pages/lib/_body-end-islands.tsx template now imports them from the
26
- * package, so the local component file overlay was removed from
27
- * templates/features/imageEnlarge/files/. No file-copy injections remain
28
- * in this feature module — only _mdx-components.ts injections.
30
+ * package, so no file-copy injections exist in this feature module either.
29
31
  */
30
32
  export declare const imageEnlargeFeature: FeatureModule;
@@ -8,203 +8,27 @@
8
8
  * `global.css` in S3 #2348) — the selectors only activate when the runtime
9
9
  * mounts the .zd-enlarge-btn.
10
10
  *
11
- * S2 (#1825): after zfb next.18 removed the built-in imageEnlarge Rust
12
- * feature, the server-side figure/button emission is re-implemented via an
13
- * MDX paragraph (p) component override in pages/_mdx-components.ts. When
14
- * imageEnlarge is enabled, three injections into the template file install:
15
- * 1. Additional imports: toChildArray + VNode from preact.
16
- * 2. ENLARGE_SVG const + EnlargeableParagraph function definition.
17
- * 3. `p: EnlargeableParagraph` entry in the createMdxComponents return map.
18
- * When imageEnlarge is OFF, none of these are injected, so the override is
19
- * absent and paragraphs render plain (the Rust built-in is gone "off" must
20
- * mean no wrapping at all).
11
+ * S2 (#1825): the server-side figure/button emission was re-implemented via an
12
+ * MDX paragraph (p) component override in pages/_mdx-components.ts. Three
13
+ * injections installed the ENLARGE_SVG + EnlargeableParagraph code when
14
+ * imageEnlarge was enabled.
15
+ *
16
+ * S8 / #2360 (E2): the full MDX component assembly moved into the
17
+ * @takazudo/zudo-doc/mdx-components factory (createMdxComponentsBase). The
18
+ * factory reads settings.imageEnlarge at render time and conditionally wraps
19
+ * block-level images in <figure class="zd-enlargeable"> the same logic the
20
+ * old injections installed, now handled once inside the package. The three
21
+ * _mdx-components.ts injections (enlarge-imports, enlarge-defs,
22
+ * enlarge-p-entry) are therefore removed; the feature is a no-op from the
23
+ * compose engine's perspective (the runtime gate in the factory is always
24
+ * present in the scaffolded template).
21
25
  *
22
26
  * S3 (#2348): the ImageEnlarge island and its SSR fallback moved from
23
27
  * src/components/image-enlarge.tsx into @takazudo/zudo-doc/image-enlarge.
24
28
  * The pages/lib/_body-end-islands.tsx template now imports them from the
25
- * package, so the local component file overlay was removed from
26
- * templates/features/imageEnlarge/files/. No file-copy injections remain
27
- * in this feature module — only _mdx-components.ts injections.
29
+ * package, so no file-copy injections exist in this feature module either.
28
30
  */
29
31
  export const imageEnlargeFeature = () => ({
30
32
  name: "imageEnlarge",
31
- injections: [
32
- // 1. Import additions: toChildArray + VNode from preact.
33
- // Inserted AFTER the `// @slot:mdx-components:enlarge-imports` anchor.
34
- // NOTE: `settings` is NOT injected here — the base template already
35
- // imports it (#2172); injecting it again caused a duplicate ES-module
36
- // lexical binding.
37
- {
38
- file: "pages/_mdx-components.ts",
39
- anchor: "// @slot:mdx-components:enlarge-imports",
40
- position: "after",
41
- content: `import { toChildArray } from "preact";
42
- import type { VNode } from "preact";`,
43
- },
44
- // 2. ENLARGE_SVG const + EnlargeableParagraph function.
45
- // Inserted AFTER the `// @slot:mdx-components:enlarge-defs` anchor
46
- // (which sits just before the `createMdxComponents` JSDoc comment).
47
- // Markup is ported verbatim from rehype-image-enlarge.ts makeEnlargeButton()
48
- // so the island's eligibility/[hidden] logic and CSS keep working identically.
49
- {
50
- file: "pages/_mdx-components.ts",
51
- anchor: "// @slot:mdx-components:enlarge-defs",
52
- position: "after",
53
- content: `/**
54
- * SVG icon for the image-enlarge button (4-corner-arrows).
55
- *
56
- * Ported verbatim from
57
- * packages/create-zudo-doc/templates/base/src/plugins/rehype-image-enlarge.ts
58
- * makeEnlargeButton() — this is the same icon the old Rust plugin emitted.
59
- * Must match exactly so the existing .zd-enlarge-btn CSS and the
60
- * image-enlarge island (src/components/image-enlarge.tsx) keep working.
61
- *
62
- * Attribute spellings: HTML/Preact conventions — \`focusable\` stays a string
63
- * ("false") because Preact's preact-render-to-string drops boolean false;
64
- * \`aria-hidden\` is the HTML attribute name (not ariaHidden).
65
- */
66
- const ENLARGE_SVG = {
67
- type: "svg",
68
- props: {
69
- viewBox: "0 0 38.99 38.99",
70
- fill: "currentColor",
71
- focusable: "false",
72
- "aria-hidden": "true",
73
- children: [
74
- {
75
- type: "polygon",
76
- props: {
77
- points:
78
- "16.2 13.74 5.92 3.47 11.2 3.47 11.2 0 3.47 0 0 0 0 3.47 0 11.2 3.47 11.2 3.47 5.92 13.74 16.2 16.2 13.74",
79
- },
80
- key: null,
81
- constructor: undefined,
82
- },
83
- {
84
- type: "polygon",
85
- props: {
86
- points:
87
- "25.24 16.2 35.52 5.92 35.52 11.2 38.99 11.2 38.99 3.47 38.99 0 35.52 0 27.79 0 27.79 3.47 33.07 3.47 22.79 13.74 25.24 16.2",
88
- },
89
- key: null,
90
- constructor: undefined,
91
- },
92
- {
93
- type: "polygon",
94
- props: {
95
- points:
96
- "22.79 25.24 33.07 35.52 27.79 35.52 27.79 38.99 35.52 38.99 38.99 38.99 38.99 35.52 38.99 27.79 35.52 27.79 35.52 33.07 25.24 22.79 22.79 25.24",
97
- },
98
- key: null,
99
- constructor: undefined,
100
- },
101
- {
102
- type: "polygon",
103
- props: {
104
- points:
105
- "13.74 22.79 3.47 33.07 3.47 27.79 0 27.79 0 35.52 0 38.99 3.47 38.99 11.2 38.99 11.2 35.52 5.92 35.52 16.2 25.24 13.74 22.79",
106
- },
107
- key: null,
108
- constructor: undefined,
109
- },
110
- ],
111
- },
112
- key: null,
113
- constructor: undefined,
114
- };
115
-
116
- /**
117
- * Enlarge-aware MDX paragraph override.
118
- *
119
- * When \`settings.imageEnlarge\` is enabled and a paragraph contains exactly
120
- * one non-whitespace child that is a block-level image VNode (type ===
121
- * ContentImg or "img"), this wraps the image in:
122
- * <figure class="zd-enlargeable">
123
- * <img ...>
124
- * <button type="button" class="zd-enlarge-btn" hidden aria-label="Enlarge image">
125
- * <svg ...>…</svg>
126
- * </button>
127
- * </figure>
128
- *
129
- * The \`title="no-enlarge"\` opt-out is read from the un-rendered VNode
130
- * (Preact's h() is lazy — child.type is still the ContentImg function, not
131
- * yet called). ContentImg strips the sentinel from the rendered img DOM.
132
- *
133
- * All other paragraphs delegate to htmlOverrides.p (ContentParagraph passthrough).
134
- */
135
- function EnlargeableParagraph(props: {
136
- children?: ComponentChildren;
137
- [key: string]: unknown;
138
- }): unknown {
139
- const { children, ...rest } = props;
140
- // Collect children and drop whitespace-only text nodes.
141
- const kids = toChildArray(children).filter((child) => {
142
- if (typeof child === "string" || typeof child === "number") {
143
- return String(child).trim() !== "";
144
- }
145
- return true;
146
- });
147
-
148
- // Check for a single-image block paragraph eligible for enlarge wrapping.
149
- if (settings.imageEnlarge && kids.length === 1) {
150
- const kid = kids[0];
151
- // VNode type guard: must be an object with a \`type\` property.
152
- if (
153
- kid !== null &&
154
- typeof kid === "object" &&
155
- "type" in kid &&
156
- "props" in kid
157
- ) {
158
- const vnode = kid as VNode<Record<string, unknown>>;
159
- if (vnode.type === ContentImg || vnode.type === "img") {
160
- const imgProps = (vnode.props ?? {}) as Record<string, unknown>;
161
- // Opt-out: title="no-enlarge" — render plain paragraph (ContentImg
162
- // will strip the sentinel title from the actual img DOM).
163
- if (imgProps.title !== "no-enlarge") {
164
- // Wrap in figure.zd-enlargeable with the enlarge button.
165
- const enlargeBtn = {
166
- type: "button",
167
- props: {
168
- type: "button",
169
- class: "zd-enlarge-btn",
170
- hidden: true,
171
- "aria-label": "Enlarge image",
172
- children: ENLARGE_SVG,
173
- },
174
- key: null,
175
- constructor: undefined,
176
- };
177
- return {
178
- type: "figure",
179
- props: {
180
- class: "zd-enlargeable",
181
- children: [vnode, enlargeBtn],
182
- },
183
- key: null,
184
- constructor: undefined,
185
- };
186
- }
187
- }
188
- }
189
- }
190
-
191
- // Fallback: delegate to the standard ContentParagraph passthrough.
192
- return (htmlOverrides.p as (props: unknown) => unknown)(props);
193
- }
194
- `,
195
- },
196
- // 3. p: EnlargeableParagraph entry in createMdxComponents return map.
197
- // Inserted AFTER the `// @slot:mdx-components:enlarge-p-entry` anchor
198
- // (which sits between `img: ContentImg,` and `HtmlPreview:`).
199
- // Must come AFTER the ...htmlOverrides spread to override ContentParagraph.
200
- {
201
- file: "pages/_mdx-components.ts",
202
- anchor: "// @slot:mdx-components:enlarge-p-entry",
203
- position: "after",
204
- content: ` // p override: wraps block-level images in <figure class="zd-enlargeable">
205
- // with an enlarge button when settings.imageEnlarge is enabled.
206
- // Must come AFTER the ...htmlOverrides spread to override ContentParagraph.
207
- p: EnlargeableParagraph,`,
208
- },
209
- ],
33
+ injections: [],
210
34
  });
@@ -1,4 +1,15 @@
1
1
  import type { UserChoices } from "./prompts.js";
2
2
  import { getSecondaryLang } from "./utils.js";
3
3
  export { getSecondaryLang };
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.
8
+ *
9
+ * Strip the caret from this string to get the bare version for provenance:
10
+ * ZUDO_DOC_PIN.replace(/^\^/, "") → "1.0.0"
11
+ *
12
+ * Bumped in lockstep by scripts/release-create-zudo-doc.sh.
13
+ */
14
+ export declare const ZUDO_DOC_PIN = "^1.0.1";
4
15
  export declare function scaffold(choices: UserChoices): Promise<void>;
package/dist/scaffold.js CHANGED
@@ -8,6 +8,17 @@ import { composeFeatures } from "./compose.js";
8
8
  import { featureModules } from "./features/index.js";
9
9
  import { capitalize, getSecondaryLang } from "./utils.js";
10
10
  export { getSecondaryLang };
11
+ /**
12
+ * Pinned `@takazudo/zudo-doc` version used in both `generatePackageJson()`
13
+ * and the `.zudo-doc.json` seed written by `scaffold()`. Hoisted as a shared
14
+ * constant so the dep pin and the provenance seed can never drift.
15
+ *
16
+ * Strip the caret from this string to get the bare version for provenance:
17
+ * ZUDO_DOC_PIN.replace(/^\^/, "") → "1.0.0"
18
+ *
19
+ * Bumped in lockstep by scripts/release-create-zudo-doc.sh.
20
+ */
21
+ export const ZUDO_DOC_PIN = "^1.0.1";
11
22
  /**
12
23
  * Files in `templates/base/**` that must never be copied into a generated
13
24
  * project. Each entry is matched against the path relative to `templates/base/`
@@ -280,6 +291,14 @@ export async function scaffold(choices) {
280
291
  await fs.outputFile(path.join(targetDir, "zfb.config.ts"), zfbConfigContent);
281
292
  const pkg = generatePackageJson(choices);
282
293
  await fs.outputFile(path.join(targetDir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
294
+ // Seed .zudo-doc.json — provenance marker for `zudo-doc eject <component>`.
295
+ // packageVersion is the bare version string (caret stripped from ZUDO_DOC_PIN)
296
+ // so it records the concrete version the scaffold targets; the eject CLI
297
+ // records the actually-installed version on first eject.
298
+ await fs.outputFile(path.join(targetDir, ".zudo-doc.json"), JSON.stringify({
299
+ packageVersion: ZUDO_DOC_PIN.replace(/^\^/, ""),
300
+ ejected: {},
301
+ }, null, 2) + "\n");
283
302
  const gitignoreLines = [
284
303
  "# Build output",
285
304
  "node_modules",
@@ -303,6 +322,9 @@ export async function scaffold(choices) {
303
322
  "# Cloudflare Wrangler",
304
323
  ".wrangler/",
305
324
  "",
325
+ "# zudo-doc build artifact (routes-src/ staged here at build time)",
326
+ ".zudo-doc/",
327
+ "",
306
328
  ];
307
329
  // The doc-lookup skill is only generated when skillSymlinker is selected
308
330
  // (the setup-doc-skill.sh script and `setup:doc-skill` npm script are gated
@@ -444,15 +466,20 @@ function generatePackageJson(choices) {
444
466
  // zfb-content GFM-autolink fix — terminate the autolink path at CJK
445
467
  // boundaries (zfb#1105). Content-rendering bug fix, additive; relevant for
446
468
  // CJK (e.g. Japanese) docs. No consumer-facing / CLI breaking change.
447
- // next.54 (current pin): bug-fix + perf release — cross-OS CSS hash
448
- // stability, multi-valued response headers (e.g. multiple Set-Cookie),
469
+ // next.54: bug-fix + perf release — cross-OS CSS hash stability,
470
+ // multi-valued response headers (e.g. multiple Set-Cookie),
449
471
  // supplementary-plane CJK reading-time, plus CLI/server/runtime hardening
450
472
  // and render perf passes. No consumer-facing / CLI breaking change.
451
- "@takazudo/zfb": "0.1.0-next.62",
452
- "@takazudo/zfb-runtime": "0.1.0-next.62",
473
+ // next.65 (current pin): dev-render of package-injected routes (zfb#1227,
474
+ // landed next.63) + islands bundler now seeds the host tsconfig `paths`
475
+ // (e.g. `@/*`) into its synthetic tsconfig (zfb#1238) — fixes silent island
476
+ // hydration failure under route injection. Unblocks packageOwnedRoutes.
477
+ // No consumer-facing / CLI breaking change.
478
+ "@takazudo/zfb": "0.1.0-next.65",
479
+ "@takazudo/zfb-runtime": "0.1.0-next.65",
453
480
  // zfb-adapter-cloudflare — required for any route with `prerender = false`.
454
481
  // Pinned in lockstep with @takazudo/zfb.
455
- "@takazudo/zfb-adapter-cloudflare": "0.1.0-next.62",
482
+ "@takazudo/zfb-adapter-cloudflare": "0.1.0-next.65",
456
483
  // @takazudo/zudo-doc — published from this monorepo via
457
484
  // .github/workflows/publish-zudo-doc.yml. The pin here is bumped in
458
485
  // lockstep by scripts/release-create-zudo-doc.sh whenever zudo-doc's
@@ -464,7 +491,9 @@ function generatePackageJson(choices) {
464
491
  // ties this pin to packages/zudo-doc's version, so the lockstep release
465
492
  // bumps both together; do not cut a create-zudo-doc release until the
466
493
  // matching @takazudo/zudo-doc version (with content.css) is on npm.
467
- "@takazudo/zudo-doc": "^0.2.22",
494
+ // ZUDO_DOC_PIN is the shared constant — scaffold() uses the same value
495
+ // to seed .zudo-doc.json so the provenance and the dep can never drift.
496
+ "@takazudo/zudo-doc": ZUDO_DOC_PIN,
468
497
  // zod — used by the generated zfb.config.ts. zfb-config-gen emits
469
498
  // `import { z } from "zod"` for the content-collection schema +
470
499
  // `z.toJSONSchema(...)` conversion. Without this dep, the consumer
@@ -497,6 +526,19 @@ function generatePackageJson(choices) {
497
526
  // consumer-build verification — the import lives in the mirrored
498
527
  // pages, not behind any feature gate. Same pin as host.
499
528
  katex: "^0.16.38",
529
+ // diff — required at build time by EVERY generated project, not just
530
+ // docHistory ones. The always-copied host base template
531
+ // `pages/lib/_doc-history-area.tsx` statically imports the real
532
+ // `DocHistory` from `@takazudo/zudo-doc/doc-history` (to keep zfb's island
533
+ // scanner chain page→stub→DocHistory walkable), which pulls
534
+ // `@takazudo/zudo-doc/dist/doc-history/index.js`'s `await import("diff")`
535
+ // into the bundle. With packageOwnedRoutes default ON (1.0), a
536
+ // docHistory-off project still bundles that path, so without `diff` here
537
+ // `zfb build` fails at esbuild with "Could not resolve 'diff'" (#2342).
538
+ // `diff` is an *optional* peerDependency of @takazudo/zudo-doc, so a
539
+ // missing copy produces no `pnpm install` warning — which is why this gap
540
+ // shipped silently and only surfaced at build time.
541
+ diff: "^8.0.3",
500
542
  };
501
543
  const devDeps = {
502
544
  "@tailwindcss/vite": "^4.2.0",
@@ -511,14 +553,16 @@ function generatePackageJson(choices) {
511
553
  devDeps["pagefind"] = "^1.4.0";
512
554
  }
513
555
  if (choices.features.includes("docHistory")) {
514
- deps["diff"] = "^8.0.3";
556
+ // (diff is now an unconditional base dep — see the `deps` block above:
557
+ // packageOwnedRoutes always bundles the doc-history-area path, so diff is
558
+ // required regardless of this feature flag.)
515
559
  // @takazudo/zudo-doc has @takazudo/zudo-doc-history-server as an optional
516
560
  // peer dep. When docHistory is selected the zfb plugin
517
561
  // (@takazudo/zudo-doc/plugins/doc-history) eagerly imports
518
562
  // @takazudo/zudo-doc/integrations/doc-history which in turn imports
519
563
  // @takazudo/zudo-doc-history-server/git-history. Without this dep the
520
564
  // plugin host fails at init with ERR_MODULE_NOT_FOUND — W8A (#1739).
521
- deps["@takazudo/zudo-doc-history-server"] = "^0.2.22";
565
+ deps["@takazudo/zudo-doc-history-server"] = "^1.0.1";
522
566
  // tsx is no longer needed here: the relocated package plugin imports the
523
567
  // runner directly (no `tsx -e` spawn) since the package ships compiled
524
568
  // dist/ — package-first migration #2321 (#2337).
@@ -150,6 +150,10 @@ export function generateSettingsFile(choices) {
150
150
  else {
151
151
  lines.push(` docHistory: false,`);
152
152
  }
153
+ // Package-owned route injection is on by default since the fast-follow (#2372).
154
+ // Generated projects include the field explicitly so settings.ts stays in sync
155
+ // with src/config/settings.ts (checked by check-fixture-settings-drift.mjs).
156
+ lines.push(` packageOwnedRoutes: true,`);
153
157
  if (choices.features.includes("bodyFootUtil")) {
154
158
  lines.push(` bodyFootUtilArea: {`);
155
159
  lines.push(` docHistory: ${choices.features.includes("docHistory")},`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-zudo-doc",
3
- "version": "0.2.22",
3
+ "version": "1.0.1",
4
4
  "description": "Create a new zudo-doc documentation site",
5
5
  "license": "MIT",
6
6
  "author": "Takeshi Takatsudo",