[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6D2FKPC58JF67RTG8SD49SK":3,"skill-same:01M6D2FKPC58JF67RTG8SD49SK":60},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":35,"linkOnly":36,"markdownContent":37,"markdownBody":38,"frontMatter":39,"refName":32,"commitSha":40,"skillDirectory":41,"forksCount":42,"repositoryHtmlUrl":43,"repositoryHomepageUrl":6,"ownerHtmlUrl":44,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":45,"install":46,"resources":59},"01M6D2FKPC58JF67RTG8SD49SK","l-update-generator",null,"Detect and fix drift between the main zudo-doc project and the create-zudo-doc generator CLI. Use when adding\u002Fremoving features, or to verify the generator stays in sync. Also triggered by \"update generator\", \"sync generator\", \"l-update-generator\", \"l-sync-create-zudo-doc\".","zudolab\u002Fzudo-doc","zudolab","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F266356510?v=4","01M6D2E9N9X9851YB24CEQF04H","01M6D2E9SFKZ0FWBMPB2625H28",1,"MIT","https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fl-update-generator\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"update","l update generator","generator","features","detect","doc generator","when","doc","sync","verify","cli","create","drift","use","main","fix","project","2026-11-10 10:12:30",false,"---\nname: l-update-generator\ndescription: \"Detect and fix drift between the main zudo-doc project and the create-zudo-doc generator CLI. Use when adding\u002Fremoving features, or to verify the generator stays in sync. Also triggered by \\\"update generator\\\", \\\"sync generator\\\", \\\"l-update-generator\\\", \\\"l-sync-create-zudo-doc\\\".\"\n---\n\n# Update create-zudo-doc Generator\n\nDetect and fix drift between the main zudo-doc project and the `create-zudo-doc` CLI generator.\n\n## Architecture Overview (minimal-scaffold, epic zudolab\u002Fzudo-doc#2651)\n\nThe generator emits the **locked ~12-file minimal manifest** — one config\nfile (`zfb.config.ts`, `zudoDoc({ ...only fields the user chose })`) plus\nmarkdown content plus a handful of unavoidable root files. Everything else\n(layout, chrome, islands, default `:root` tokens, even the doc ROUTES\nthemselves via `packageOwnedRoutes`) ships from `@takazudo\u002Fzudo-doc` in\n`node_modules`. There is no more copy-then-strip and no more `@slot:`\ninjection anchors:\n\n1. Copy the minimal **base template** (`templates\u002Fbase\u002F`) — 10 files, no\n   injection anchors: `pages\u002Findex.tsx`, `pages\u002Fdocs\u002F[[...slug]].tsx`,\n   `src\u002Fstyles\u002Fglobal.css`, `tsconfig.json`, `scripts\u002Fsetup-doc-skill.sh`,\n   `scripts\u002Fcheck-links.js`, and four `public\u002F` favicon files\n   (the last is excluded from the unconditional mirror and copied only when\n   `skillSymlinker` is selected — see `scaffold.ts`'s `EXCLUDE_FROM_MIRROR`).\n2. **Generate** the ONE `zfb.config.ts` programmatically (`zfb-config-gen.ts`)\n   — diff-from-defaults: only fields whose value differs from the matching\n   `ZudoDocConfig` `@default` are emitted (`siteName` is always emitted).\n   There is no more `settings-gen.ts` and no more `src\u002Fconfig\u002Fsettings.ts`\n   in a fresh scaffold.\n3. **Compose** selected features (`compose.ts` + `src\u002Ffeatures\u002F*.ts`) — most\n   feature modules are now **pure settings-field emission** (`injections: []`,\n   no `postProcess`) because the corresponding UI\u002Fbehavior is entirely\n   package-owned (package-first migration, epics #2321\u002F#2344\u002F#2356). Only a\n   handful still do real work:\n   - **Genuine file copies**: `i18n` (locale doc-route stub), `tagGovernance`\n     (one explicit `src\u002Fconfig\u002Ftag-vocabulary.ts` CLI\u002Fconfig module), `skillSymlinker`\n     (`scripts\u002Fsetup-doc-skill.sh`, copied in `scaffold.ts` directly, not a\n     `templates\u002Ffeatures\u002F` dir), `claudeSkills` (copies curated\n     `zudo-doc-*` Claude Code skills from the monorepo, also in\n     `scaffold.ts` directly), `claudeSkillsWriting` (copies the\n     `zudo-doc-writing` writing\u002Fnavigation-guide skill, also in\n     `scaffold.ts` directly).\n   - **`postProcess` patches** (small, targeted string patches to an\n     already-generated file — never new files): `docHistory` (patches the\n     doc-route stub(s) to statically import the real `DocHistory` and thread\n     it through `createChrome`), `designTokenPanel` (inserts the one\n     conditional `@import \"@takazudo\u002Fzdtp\u002Fstyles.css\";` line into\n     `global.css` — the one thing that can't ship unconditionally from\n     `@takazudo\u002Fzudo-doc\u002Ftheme.css`, since it pulls in zdtp's own bytes),\n     `tagGovernance` (writes the explicit `tag-vocabulary.ts` module).\n   - **Retired features**: `tauri` \u002F `tauriDev` were removed (#4758). Do not\n     treat their absence as drift; positive flags and preset\u002FAPI feature names\n     must keep failing before any write, and `--no-tauri` \u002F `--no-tauri-dev` \u002F\n     `--tauri=false` \u002F `--tauri-dev=false` stay accepted as unadvertised\n     no-ops.\n\n`tagGovernance` passes its module explicitly to the package-owned\n`tags-audit`\u002F`tags-suggest` bins with `--config`; there are no project-side CLI\nshims and no duplicate settings module.\n\n## When to Use\n\n- After adding or removing a feature from zudo-doc\n- When the drift-detection test fails\n- Periodically to verify generator health\n- User says \"update generator\", \"sync generator\", \"check generator drift\", \"l-update-generator\", or the old name \"l-sync-create-zudo-doc\"\n\n**Quick pre-check**: Run `pnpm check:template-drift` first to get an automated summary of base template drift. Then proceed with the full workflow below for the config census, dependency, and feature composition drift.\n\n## Step 1: Analyze Drift\n\nCompare the main project's source files with what the generator produces.\n\n### 1a. Settings\u002Fconfig-field drift\n\nThe field census now lives in ONE place — the package, not this repo's own\n`src\u002Fconfig\u002Fsettings.ts`:\n\n- **Census (source of truth)**: `packages\u002Fzudo-doc\u002Fsrc\u002Fconfig.ts` —\n  `ZudoDocConfig` (the documented field surface, every field carries a\n  `@default` JSDoc) and browser-safe `settings-defaults.ts` (the actual `DEFAULT_SETTINGS`, re-exported by `config.ts`).\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fzfb-config-gen.ts` —\n  `DEFAULT_MIRROR` (a hand-kept local copy of `DEFAULT_SETTINGS`, only for\n  fields the generator can ever set — it can't `import` the package, see the\n  file's header comment for why) + `buildDesiredConfig()` (user-choice →\n  field mapping) + `FIELD_ORDER` (cosmetic emission order).\n\nCompare field names between `ZudoDocConfig` and `zfb-config-gen.ts`'s\n`DEFAULT_MIRROR`\u002F`FIELD_ORDER`\u002F`buildDesiredConfig()`. A field the generator\ncan plausibly set (has a CLI flag or prompt) but is missing from\n`DEFAULT_MIRROR`\u002F`FIELD_ORDER` is drift. A field `DEFAULT_MIRROR` carries\nwhose default value no longer matches `DEFAULT_SETTINGS` is also drift\n(stale mirror).\n\nThis repo's OWN `src\u002Fconfig\u002Fsettings.ts` (the showcase's real settings\nobject, spread into `zfb.config.ts`'s `zudoDoc({ ...settings, ... })`) is a\nsecondary, informal cross-check — useful for spotting a field the showcase\ndemonstrates but the generator never learned to emit — but it is NOT the\ncensus. Don't chase drift against it that isn't also drift against\n`ZudoDocConfig`.\n\n### 1b. Dependency drift\n\nCompare dependencies:\n\n- **Main**: `package.json` — root dependencies\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fscaffold.ts` `generatePackageJson()` — generated deps\n\nCheck for packages used in base template files and feature files that are not included in the generated package.json. Read `generatePackageJson()` for the actual dependency branches: zfb family pins stay aligned; zod is required; zdtp is feature-selected, and 0.9.0 has no Preact dependency, so no generated project declares Preact. `diff` and `katex` remain optional runtime peers. No `preact-render-to-string` or React compatibility dependency is needed for owned JSX.\n\n### 1c. zfb config \u002F preset drift\n\nCompare the main project's `zfb.config.ts` (`zudoDoc({ ...settings, chromeBindingsModule: \".\u002Fsrc\u002Fchrome-bindings\" })`) with what the generator produces:\n\n- **Main**: `zfb.config.ts` — spreads `settings` from `src\u002Fconfig\u002Fsettings.ts` into `zudoDoc({...})`\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fzfb-config-gen.ts` — programmatic diff-from-defaults generation, same `zudoDoc()` entry point\n\nBoth sides go through the SAME `zudoDoc()` function\n(`packages\u002Fzudo-doc\u002Fsrc\u002Fconfig.ts`), so there is no separate \"integration\nwiring\" to check field-by-field anymore — `zudoDocPreset()` (the internal\nfragment builder `zudoDoc()` calls) is the one place collections\u002Fplugins\u002F\nmarkdown logic lives. Only check `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts` when a\nNEW plugin or collection needs wiring from a settings field (see 1d).\n\n### 1d. Feature composition drift\n\nCheck that features in the main project have corresponding feature modules:\n\n- **Main**: does the showcase demonstrate a behavior with no `ZudoDocConfig` field and no generator feature module backing it?\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Ffeatures\u002F*.ts` — feature modules (mostly settings-field emission now; injections\u002FpostProcess only for the handful of genuine gaps listed in \"Architecture Overview\" above)\n- **Templates**: `packages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002F*\u002Ffiles\u002F` — feature-specific files (only `i18n` has one; `claudeSkills`\u002F`claudeSkillsWriting` directories are copied from `scaffold.ts`)\n\nFor each feature-gated behavior in the main project, verify:\n\n1. A feature module exists in `src\u002Ffeatures\u002F` and is registered in `src\u002Ffeatures\u002Findex.ts`\n2. If the feature ships genuine files, they exist in `templates\u002Ffeatures\u002F\u003Cname>\u002Ffiles\u002F`\n3. If the feature introduces a new plugin\u002Fcollection, `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts`'s `zudoDocPreset()` wires it from the matching settings field — NOT the generator (the generator only ever emits the field value)\n4. If the feature has a `postProcess` hook, verify the string patch it applies still matches the current shape of the file it patches (e.g. `docHistory`'s patch targets the exact `createChrome(routeCtx);` \u002F `import { createChrome } from \"@takazudo\u002Fzudo-doc\u002Fchrome\";` lines in the doc-route stub — a stub rewrite elsewhere breaks this silently since the patch is a literal string match, not an AST edit)\n\n### 1e. Base template drift\n\nCompare the 6 source-code base template files against their showcase \u002F package counterparts (the four favicon files are byte-identical assets; most showcase behavior is package-owned, not template-mirrored):\n\n- `templates\u002Fbase\u002Fpages\u002Findex.tsx` — 1-line re-export\n- `templates\u002Fbase\u002Fpages\u002Fdocs\u002F[[...slug]].tsx` — self-contained doc-route stub (compare against the showcase's `pages\u002Fdocs\u002F[[...slug]].tsx`, which the `.template-drift-allowlist` allows to diverge — the showcase adds `chromeBindingsModule` wiring the minimal stub doesn't need)\n- `templates\u002Fbase\u002Fsrc\u002Fstyles\u002Fglobal.css` — fixed ~20-line `@import` chain (compare against the showcase's `src\u002Fstyles\u002Fglobal.css`, also allowlisted — the showcase's is a superset)\n- `templates\u002Fbase\u002Ftsconfig.json` — 5-line extends form (compare against the showcase's `tsconfig.json`, allowlisted — the showcase adds `noUncheckedIndexedAccess`, `types`, and extra `include` paths, while both stay `baseUrl`-free with relative alias targets — see \"Owned JSX and project-local aliases\" in `packages\u002Fzudo-doc\u002FCLAUDE.md`)\n- `templates\u002Fbase\u002Fscripts\u002Fsetup-doc-skill.sh` — should be byte-identical to the root `scripts\u002Fsetup-doc-skill.sh` (the root copy IS the source template; not allowlisted, must match exactly)\n- `templates\u002Fbase\u002Fscripts\u002Fcheck-links.js` — source-first counterpart to the showcase checker; allowlisted because generated projects read literal settings from `zfb.config.ts` instead of the showcase's `src\u002Fconfig\u002Fsettings.ts`, so validation-core changes require manual parity review\n\n**Automated first check**: Run `pnpm check:template-drift` before doing manual analysis. This runs `scripts\u002Fcheck-template-drift.sh` and quickly identifies files that differ between the main project and the base template.\n\n**Allowlist note**: The base-template pairs in `.template-drift-allowlist` (`global.css`, `tsconfig.json`, `pages\u002Findex.tsx`, the two doc-route stubs, and `scripts\u002Fcheck-links.js`) are skipped by the automated script's whole-file content check because they intentionally differ (the showcase carries wiring the minimal template doesn't need). These files **still require manual review** — check that validation-core or other relevant changes in the main project are reflected in the template counterpart. `global.css` also has a dedicated automated guard (`check_global_css_legacy_tokens` in `scripts\u002Fcheck-template-drift.sh`) that fails if the template regresses to a pre-ramp-restructure token or drops the `@import \"@takazudo\u002Fzudo-doc\u002Ftheme.css\"` line — that one drift class stays automated even though the rest of the file needs manual review.\n\n## Step 2: Report Findings\n\nPresent a clear drift report:\n\n```\n## Config-Field Drift\n- Missing in generator: fieldA, fieldB (present in ZudoDocConfig, absent from DEFAULT_MIRROR\u002FFIELD_ORDER)\n- Stale default in DEFAULT_MIRROR: fieldC (generator default no longer matches DEFAULT_SETTINGS)\n\n## Dependency Drift\n- Missing from generated package.json: packageX (used unconditionally, or by featureY)\n- Unnecessary in generated package.json: packageZ (feature disabled \u002F no longer needed)\n\n## Preset Drift\n- Missing plugin wiring: pluginX in packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts for settings.fieldY\n\n## Feature Composition Drift\n- Missing feature module: feature \"X\" has a ZudoDocConfig field but no src\u002Ffeatures\u002F\u003Cname>.ts\n- Missing template files: feature \"X\" module exists but templates\u002Ffeatures\u002FX\u002Ffiles\u002F is missing a file it should copy\n- Stale postProcess patch: feature \"X\"'s string-replace target no longer exists in the file it patches\n\n## Base Template Drift\n- Stale file: templates\u002Fbase\u002F\u003Cpath> differs from its showcase\u002Fpackage counterpart\n\n## No Drift Detected\n(if everything is in sync)\n```\n\n## Step 3: Apply Fixes\n\nFor each drift item found:\n\n1. **Config-field drift** → Update `zfb-config-gen.ts`'s `DEFAULT_MIRROR` + `buildDesiredConfig()` + `FIELD_ORDER`. If the field doesn't exist yet on `ZudoDocConfig`, add it there first (with a `@default` JSDoc — enforced by `config-jsdoc.test.ts`) and to `settings-defaults.ts`'s `DEFAULT_SETTINGS`.\n2. **Dependency drift** → Update `scaffold.ts` `generatePackageJson()` to add\u002Fremove deps\n3. **Preset drift** → Update `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts`'s `zudoDocPreset()` to wire the plugin\u002Fcollection from the settings field\n4. **Feature composition drift** → Create\u002Fupdate feature module in `src\u002Ffeatures\u002F`, register it in `src\u002Ffeatures\u002Findex.ts`, add template files only if there's a genuine gap (check whether `@takazudo\u002Fzudo-doc` already ships the behavior first)\n5. **Base template drift** → Update the stale file in `templates\u002Fbase\u002F`\n\nAfter fixes:\n\n1. Run `cd packages\u002Fcreate-zudo-doc && pnpm build` to verify TypeScript compiles\n2. Run `cd packages\u002Fcreate-zudo-doc && pnpm test` to verify tests pass (including the settings-drift guard, which asserts `ZudoDocConfig` is a subset of `FIELD_ORDER` ∪ a reasoned allowlist)\n3. Commit with message: `fix(create-zudo-doc): sync generator with main project`\n\n## Key Files\n\n| File | Role |\n|------|------|\n| `packages\u002Fzudo-doc\u002Fsrc\u002Fconfig.ts` | Canonical field census — `ZudoDocConfig` (documented, `@default`-tagged); browser-safe `settings-defaults.ts` owns `DEFAULT_SETTINGS`. Source of truth for every generated project's field surface. |\n| `src\u002Fconfig\u002Fsettings.ts` | This repo's own showcase settings (informal cross-check only — see Step 1a) |\n| `zfb.config.ts` | Main project zfb config — `zudoDoc({ ...settings, chromeBindingsModule: \".\u002Fsrc\u002Fchrome-bindings\" })` |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fzfb-config-gen.ts` | The SINGLE config generator — emits `defineConfig(zudoDoc({...}))`, diff-from-defaults against `DEFAULT_MIRROR` (a local, hand-kept copy of `DEFAULT_SETTINGS`) |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fcompose.ts` | Composition engine (injection system mostly unused — `ANCHOR_FILES` is `[]`; kept as infra), feature resolution |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Ffeatures\u002F*.ts` | Feature modules — settings-field emission via `zfb-config-gen.ts`, plus a handful of genuine file copies \u002F `postProcess` patches |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Ffeatures\u002Findex.ts` | Registers every feature module |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fscaffold.ts` | Orchestrates generation pipeline, generates `package.json`, `.gitignore`, `.npmrc`, seeds starter content |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fclaude-md-gen.ts` | Generates the per-project `CLAUDE.md` |\n| `packages\u002Fcreate-zudo-doc\u002Ftemplates\u002Fbase\u002F` | The locked ~21-file (barebone) minimal manifest's static half — 10 files, no `@slot:` anchors |\n| `packages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002F` | Feature-specific files copied when a feature is enabled — only `i18n` has one (`claudeSkills`\u002F`claudeSkillsWriting` directories are copied from `scaffold.ts`) |\n| `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts` | `zudoDocPreset()` — wires plugins\u002Fcollections\u002Fmarkdown from settings fields; the generator never wires plugins directly |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002F__tests__\u002Fscaffold.test.ts` | Manifest-shape assertions (exact 12-file barebone list, exact all-on list, settings-drift guard) |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002F__tests__\u002Fzfb-config-gen.test.ts` | Field-mapping \u002F diff-from-defaults unit tests |\n","# Update create-zudo-doc Generator\n\nDetect and fix drift between the main zudo-doc project and the `create-zudo-doc` CLI generator.\n\n## Architecture Overview (minimal-scaffold, epic zudolab\u002Fzudo-doc#2651)\n\nThe generator emits the **locked ~12-file minimal manifest** — one config\nfile (`zfb.config.ts`, `zudoDoc({ ...only fields the user chose })`) plus\nmarkdown content plus a handful of unavoidable root files. Everything else\n(layout, chrome, islands, default `:root` tokens, even the doc ROUTES\nthemselves via `packageOwnedRoutes`) ships from `@takazudo\u002Fzudo-doc` in\n`node_modules`. There is no more copy-then-strip and no more `@slot:`\ninjection anchors:\n\n1. Copy the minimal **base template** (`templates\u002Fbase\u002F`) — 10 files, no\n   injection anchors: `pages\u002Findex.tsx`, `pages\u002Fdocs\u002F[[...slug]].tsx`,\n   `src\u002Fstyles\u002Fglobal.css`, `tsconfig.json`, `scripts\u002Fsetup-doc-skill.sh`,\n   `scripts\u002Fcheck-links.js`, and four `public\u002F` favicon files\n   (the last is excluded from the unconditional mirror and copied only when\n   `skillSymlinker` is selected — see `scaffold.ts`'s `EXCLUDE_FROM_MIRROR`).\n2. **Generate** the ONE `zfb.config.ts` programmatically (`zfb-config-gen.ts`)\n   — diff-from-defaults: only fields whose value differs from the matching\n   `ZudoDocConfig` `@default` are emitted (`siteName` is always emitted).\n   There is no more `settings-gen.ts` and no more `src\u002Fconfig\u002Fsettings.ts`\n   in a fresh scaffold.\n3. **Compose** selected features (`compose.ts` + `src\u002Ffeatures\u002F*.ts`) — most\n   feature modules are now **pure settings-field emission** (`injections: []`,\n   no `postProcess`) because the corresponding UI\u002Fbehavior is entirely\n   package-owned (package-first migration, epics #2321\u002F#2344\u002F#2356). Only a\n   handful still do real work:\n   - **Genuine file copies**: `i18n` (locale doc-route stub), `tagGovernance`\n     (one explicit `src\u002Fconfig\u002Ftag-vocabulary.ts` CLI\u002Fconfig module), `skillSymlinker`\n     (`scripts\u002Fsetup-doc-skill.sh`, copied in `scaffold.ts` directly, not a\n     `templates\u002Ffeatures\u002F` dir), `claudeSkills` (copies curated\n     `zudo-doc-*` Claude Code skills from the monorepo, also in\n     `scaffold.ts` directly), `claudeSkillsWriting` (copies the\n     `zudo-doc-writing` writing\u002Fnavigation-guide skill, also in\n     `scaffold.ts` directly).\n   - **`postProcess` patches** (small, targeted string patches to an\n     already-generated file — never new files): `docHistory` (patches the\n     doc-route stub(s) to statically import the real `DocHistory` and thread\n     it through `createChrome`), `designTokenPanel` (inserts the one\n     conditional `@import \"@takazudo\u002Fzdtp\u002Fstyles.css\";` line into\n     `global.css` — the one thing that can't ship unconditionally from\n     `@takazudo\u002Fzudo-doc\u002Ftheme.css`, since it pulls in zdtp's own bytes),\n     `tagGovernance` (writes the explicit `tag-vocabulary.ts` module).\n   - **Retired features**: `tauri` \u002F `tauriDev` were removed (#4758). Do not\n     treat their absence as drift; positive flags and preset\u002FAPI feature names\n     must keep failing before any write, and `--no-tauri` \u002F `--no-tauri-dev` \u002F\n     `--tauri=false` \u002F `--tauri-dev=false` stay accepted as unadvertised\n     no-ops.\n\n`tagGovernance` passes its module explicitly to the package-owned\n`tags-audit`\u002F`tags-suggest` bins with `--config`; there are no project-side CLI\nshims and no duplicate settings module.\n\n## When to Use\n\n- After adding or removing a feature from zudo-doc\n- When the drift-detection test fails\n- Periodically to verify generator health\n- User says \"update generator\", \"sync generator\", \"check generator drift\", \"l-update-generator\", or the old name \"l-sync-create-zudo-doc\"\n\n**Quick pre-check**: Run `pnpm check:template-drift` first to get an automated summary of base template drift. Then proceed with the full workflow below for the config census, dependency, and feature composition drift.\n\n## Step 1: Analyze Drift\n\nCompare the main project's source files with what the generator produces.\n\n### 1a. Settings\u002Fconfig-field drift\n\nThe field census now lives in ONE place — the package, not this repo's own\n`src\u002Fconfig\u002Fsettings.ts`:\n\n- **Census (source of truth)**: `packages\u002Fzudo-doc\u002Fsrc\u002Fconfig.ts` —\n  `ZudoDocConfig` (the documented field surface, every field carries a\n  `@default` JSDoc) and browser-safe `settings-defaults.ts` (the actual `DEFAULT_SETTINGS`, re-exported by `config.ts`).\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fzfb-config-gen.ts` —\n  `DEFAULT_MIRROR` (a hand-kept local copy of `DEFAULT_SETTINGS`, only for\n  fields the generator can ever set — it can't `import` the package, see the\n  file's header comment for why) + `buildDesiredConfig()` (user-choice →\n  field mapping) + `FIELD_ORDER` (cosmetic emission order).\n\nCompare field names between `ZudoDocConfig` and `zfb-config-gen.ts`'s\n`DEFAULT_MIRROR`\u002F`FIELD_ORDER`\u002F`buildDesiredConfig()`. A field the generator\ncan plausibly set (has a CLI flag or prompt) but is missing from\n`DEFAULT_MIRROR`\u002F`FIELD_ORDER` is drift. A field `DEFAULT_MIRROR` carries\nwhose default value no longer matches `DEFAULT_SETTINGS` is also drift\n(stale mirror).\n\nThis repo's OWN `src\u002Fconfig\u002Fsettings.ts` (the showcase's real settings\nobject, spread into `zfb.config.ts`'s `zudoDoc({ ...settings, ... })`) is a\nsecondary, informal cross-check — useful for spotting a field the showcase\ndemonstrates but the generator never learned to emit — but it is NOT the\ncensus. Don't chase drift against it that isn't also drift against\n`ZudoDocConfig`.\n\n### 1b. Dependency drift\n\nCompare dependencies:\n\n- **Main**: `package.json` — root dependencies\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fscaffold.ts` `generatePackageJson()` — generated deps\n\nCheck for packages used in base template files and feature files that are not included in the generated package.json. Read `generatePackageJson()` for the actual dependency branches: zfb family pins stay aligned; zod is required; zdtp is feature-selected, and 0.9.0 has no Preact dependency, so no generated project declares Preact. `diff` and `katex` remain optional runtime peers. No `preact-render-to-string` or React compatibility dependency is needed for owned JSX.\n\n### 1c. zfb config \u002F preset drift\n\nCompare the main project's `zfb.config.ts` (`zudoDoc({ ...settings, chromeBindingsModule: \".\u002Fsrc\u002Fchrome-bindings\" })`) with what the generator produces:\n\n- **Main**: `zfb.config.ts` — spreads `settings` from `src\u002Fconfig\u002Fsettings.ts` into `zudoDoc({...})`\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fzfb-config-gen.ts` — programmatic diff-from-defaults generation, same `zudoDoc()` entry point\n\nBoth sides go through the SAME `zudoDoc()` function\n(`packages\u002Fzudo-doc\u002Fsrc\u002Fconfig.ts`), so there is no separate \"integration\nwiring\" to check field-by-field anymore — `zudoDocPreset()` (the internal\nfragment builder `zudoDoc()` calls) is the one place collections\u002Fplugins\u002F\nmarkdown logic lives. Only check `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts` when a\nNEW plugin or collection needs wiring from a settings field (see 1d).\n\n### 1d. Feature composition drift\n\nCheck that features in the main project have corresponding feature modules:\n\n- **Main**: does the showcase demonstrate a behavior with no `ZudoDocConfig` field and no generator feature module backing it?\n- **Generator**: `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Ffeatures\u002F*.ts` — feature modules (mostly settings-field emission now; injections\u002FpostProcess only for the handful of genuine gaps listed in \"Architecture Overview\" above)\n- **Templates**: `packages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002F*\u002Ffiles\u002F` — feature-specific files (only `i18n` has one; `claudeSkills`\u002F`claudeSkillsWriting` directories are copied from `scaffold.ts`)\n\nFor each feature-gated behavior in the main project, verify:\n\n1. A feature module exists in `src\u002Ffeatures\u002F` and is registered in `src\u002Ffeatures\u002Findex.ts`\n2. If the feature ships genuine files, they exist in `templates\u002Ffeatures\u002F\u003Cname>\u002Ffiles\u002F`\n3. If the feature introduces a new plugin\u002Fcollection, `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts`'s `zudoDocPreset()` wires it from the matching settings field — NOT the generator (the generator only ever emits the field value)\n4. If the feature has a `postProcess` hook, verify the string patch it applies still matches the current shape of the file it patches (e.g. `docHistory`'s patch targets the exact `createChrome(routeCtx);` \u002F `import { createChrome } from \"@takazudo\u002Fzudo-doc\u002Fchrome\";` lines in the doc-route stub — a stub rewrite elsewhere breaks this silently since the patch is a literal string match, not an AST edit)\n\n### 1e. Base template drift\n\nCompare the 6 source-code base template files against their showcase \u002F package counterparts (the four favicon files are byte-identical assets; most showcase behavior is package-owned, not template-mirrored):\n\n- `templates\u002Fbase\u002Fpages\u002Findex.tsx` — 1-line re-export\n- `templates\u002Fbase\u002Fpages\u002Fdocs\u002F[[...slug]].tsx` — self-contained doc-route stub (compare against the showcase's `pages\u002Fdocs\u002F[[...slug]].tsx`, which the `.template-drift-allowlist` allows to diverge — the showcase adds `chromeBindingsModule` wiring the minimal stub doesn't need)\n- `templates\u002Fbase\u002Fsrc\u002Fstyles\u002Fglobal.css` — fixed ~20-line `@import` chain (compare against the showcase's `src\u002Fstyles\u002Fglobal.css`, also allowlisted — the showcase's is a superset)\n- `templates\u002Fbase\u002Ftsconfig.json` — 5-line extends form (compare against the showcase's `tsconfig.json`, allowlisted — the showcase adds `noUncheckedIndexedAccess`, `types`, and extra `include` paths, while both stay `baseUrl`-free with relative alias targets — see \"Owned JSX and project-local aliases\" in `packages\u002Fzudo-doc\u002FCLAUDE.md`)\n- `templates\u002Fbase\u002Fscripts\u002Fsetup-doc-skill.sh` — should be byte-identical to the root `scripts\u002Fsetup-doc-skill.sh` (the root copy IS the source template; not allowlisted, must match exactly)\n- `templates\u002Fbase\u002Fscripts\u002Fcheck-links.js` — source-first counterpart to the showcase checker; allowlisted because generated projects read literal settings from `zfb.config.ts` instead of the showcase's `src\u002Fconfig\u002Fsettings.ts`, so validation-core changes require manual parity review\n\n**Automated first check**: Run `pnpm check:template-drift` before doing manual analysis. This runs `scripts\u002Fcheck-template-drift.sh` and quickly identifies files that differ between the main project and the base template.\n\n**Allowlist note**: The base-template pairs in `.template-drift-allowlist` (`global.css`, `tsconfig.json`, `pages\u002Findex.tsx`, the two doc-route stubs, and `scripts\u002Fcheck-links.js`) are skipped by the automated script's whole-file content check because they intentionally differ (the showcase carries wiring the minimal template doesn't need). These files **still require manual review** — check that validation-core or other relevant changes in the main project are reflected in the template counterpart. `global.css` also has a dedicated automated guard (`check_global_css_legacy_tokens` in `scripts\u002Fcheck-template-drift.sh`) that fails if the template regresses to a pre-ramp-restructure token or drops the `@import \"@takazudo\u002Fzudo-doc\u002Ftheme.css\"` line — that one drift class stays automated even though the rest of the file needs manual review.\n\n## Step 2: Report Findings\n\nPresent a clear drift report:\n\n```\n## Config-Field Drift\n- Missing in generator: fieldA, fieldB (present in ZudoDocConfig, absent from DEFAULT_MIRROR\u002FFIELD_ORDER)\n- Stale default in DEFAULT_MIRROR: fieldC (generator default no longer matches DEFAULT_SETTINGS)\n\n## Dependency Drift\n- Missing from generated package.json: packageX (used unconditionally, or by featureY)\n- Unnecessary in generated package.json: packageZ (feature disabled \u002F no longer needed)\n\n## Preset Drift\n- Missing plugin wiring: pluginX in packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts for settings.fieldY\n\n## Feature Composition Drift\n- Missing feature module: feature \"X\" has a ZudoDocConfig field but no src\u002Ffeatures\u002F\u003Cname>.ts\n- Missing template files: feature \"X\" module exists but templates\u002Ffeatures\u002FX\u002Ffiles\u002F is missing a file it should copy\n- Stale postProcess patch: feature \"X\"'s string-replace target no longer exists in the file it patches\n\n## Base Template Drift\n- Stale file: templates\u002Fbase\u002F\u003Cpath> differs from its showcase\u002Fpackage counterpart\n\n## No Drift Detected\n(if everything is in sync)\n```\n\n## Step 3: Apply Fixes\n\nFor each drift item found:\n\n1. **Config-field drift** → Update `zfb-config-gen.ts`'s `DEFAULT_MIRROR` + `buildDesiredConfig()` + `FIELD_ORDER`. If the field doesn't exist yet on `ZudoDocConfig`, add it there first (with a `@default` JSDoc — enforced by `config-jsdoc.test.ts`) and to `settings-defaults.ts`'s `DEFAULT_SETTINGS`.\n2. **Dependency drift** → Update `scaffold.ts` `generatePackageJson()` to add\u002Fremove deps\n3. **Preset drift** → Update `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts`'s `zudoDocPreset()` to wire the plugin\u002Fcollection from the settings field\n4. **Feature composition drift** → Create\u002Fupdate feature module in `src\u002Ffeatures\u002F`, register it in `src\u002Ffeatures\u002Findex.ts`, add template files only if there's a genuine gap (check whether `@takazudo\u002Fzudo-doc` already ships the behavior first)\n5. **Base template drift** → Update the stale file in `templates\u002Fbase\u002F`\n\nAfter fixes:\n\n1. Run `cd packages\u002Fcreate-zudo-doc && pnpm build` to verify TypeScript compiles\n2. Run `cd packages\u002Fcreate-zudo-doc && pnpm test` to verify tests pass (including the settings-drift guard, which asserts `ZudoDocConfig` is a subset of `FIELD_ORDER` ∪ a reasoned allowlist)\n3. Commit with message: `fix(create-zudo-doc): sync generator with main project`\n\n## Key Files\n\n| File | Role |\n|------|------|\n| `packages\u002Fzudo-doc\u002Fsrc\u002Fconfig.ts` | Canonical field census — `ZudoDocConfig` (documented, `@default`-tagged); browser-safe `settings-defaults.ts` owns `DEFAULT_SETTINGS`. Source of truth for every generated project's field surface. |\n| `src\u002Fconfig\u002Fsettings.ts` | This repo's own showcase settings (informal cross-check only — see Step 1a) |\n| `zfb.config.ts` | Main project zfb config — `zudoDoc({ ...settings, chromeBindingsModule: \".\u002Fsrc\u002Fchrome-bindings\" })` |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fzfb-config-gen.ts` | The SINGLE config generator — emits `defineConfig(zudoDoc({...}))`, diff-from-defaults against `DEFAULT_MIRROR` (a local, hand-kept copy of `DEFAULT_SETTINGS`) |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fcompose.ts` | Composition engine (injection system mostly unused — `ANCHOR_FILES` is `[]`; kept as infra), feature resolution |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Ffeatures\u002F*.ts` | Feature modules — settings-field emission via `zfb-config-gen.ts`, plus a handful of genuine file copies \u002F `postProcess` patches |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Ffeatures\u002Findex.ts` | Registers every feature module |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fscaffold.ts` | Orchestrates generation pipeline, generates `package.json`, `.gitignore`, `.npmrc`, seeds starter content |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002Fclaude-md-gen.ts` | Generates the per-project `CLAUDE.md` |\n| `packages\u002Fcreate-zudo-doc\u002Ftemplates\u002Fbase\u002F` | The locked ~21-file (barebone) minimal manifest's static half — 10 files, no `@slot:` anchors |\n| `packages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002F` | Feature-specific files copied when a feature is enabled — only `i18n` has one (`claudeSkills`\u002F`claudeSkillsWriting` directories are copied from `scaffold.ts`) |\n| `packages\u002Fzudo-doc\u002Fsrc\u002Fpreset.ts` | `zudoDocPreset()` — wires plugins\u002Fcollections\u002Fmarkdown from settings fields; the generator never wires plugins directly |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002F__tests__\u002Fscaffold.test.ts` | Manifest-shape assertions (exact 12-file barebone list, exact all-on list, settings-drift guard) |\n| `packages\u002Fcreate-zudo-doc\u002Fsrc\u002F__tests__\u002Fzfb-config-gen.test.ts` | Field-mapping \u002F diff-from-defaults unit tests |\n",{"name":5,"description":7},"2b67af76ba78c1da6117a21efb72878fedcdc151",".claude\u002Fskills\u002Fl-update-generator",0,"https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc","https:\u002F\u002Fgithub.com\u002Fzudolab","2026-11-14 11:23:40",{"source":8,"skillName":5,"commands":47,"prompt":57,"zipAvailable":58},[48,51,54],{"tool":49,"command":50},"npx","npx skills add zudolab\u002Fzudo-doc --skill l-update-generator",{"tool":52,"command":53},"bunx","bunx skills add zudolab\u002Fzudo-doc --skill l-update-generator",{"tool":55,"command":56},"pnpm","pnpm dlx skills add zudolab\u002Fzudo-doc --skill l-update-generator","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fl-update-generator\u002FSKILL.md",true,[],[61,94,119,135,173,185],{"skillNo":62,"name":63,"nameZh":6,"description":64,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":65,"categories":66,"keywords":77,"publishedAt":35},"01M6D2GZKKY2E651Q297NEZEGV","zudo-doc-writing","Doc-writing and navigation-structure guide for this zudo-doc project. Consult BEFORE creating pages, adding categories, designing header navigation, or writing\u002Fediting mdx content under src\u002Fcontent\u002F. Covers: reading the AUTHORING.md editorial policy and its four placement questions, when to run a structure review, plan-the-nav-tree-first workflow, tree vs note-tray categories, the recommended 3-level hierarchy (header → sidebar → nested), filesystem navigation as the default, linked versus heading-only category rows, category index pages, sidebar_position discipline, frontmatter schema, no-h1 rule, relative .mdx links, and admonition syntax. Triggered by 'write docs', 'add a page', 'create a page', 'add category', 'structure navigation', 'nav design', 'zudo-doc-writing'.","https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002Fpackages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002FclaudeSkillsWriting\u002Ffiles\u002F.claude\u002Fskills\u002Fzudo-doc-writing\u002FSKILL.md",[67,72],{"categoryNo":68,"categoryName":69,"taxonomyType":70,"taxonomyTypeDesc":71},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":73,"categoryName":74,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[78,79,25,34,80,81,82,83,84,29,85,86,87,88,24,89,90,91,92,93],"writing","zudo doc writing","default","design","only","workflow","consult","structure","plan","discipline","categories","review","hierarchy","filesystem navigation","run","src",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":35},"01M6D2GWFZ81SCB168Z4P4NYYN","zudo-doc-version-bump","Bump package version, update changelog and versioned docs snapshot (if those features are enabled), commit, tag, and create a GitHub release. Use when: (1) User says 'version bump', 'bump version', 'release', or 'zudo-doc-version-bump', (2) User wants to create a new release of this project.","https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002Fpackages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002FclaudeSkills\u002Ffiles\u002F.claude\u002Fskills\u002Fzudo-doc-version-bump\u002FSKILL.md",[],[101,102,103,104,25,34,105,106,31,107,108,29,109,110,18,111,112,113,114,115,116,117,24,21,118],"bump","zudo doc version bump","version","version bump","update changelog","package","patch","commit","changelog","github","release","snapshot","bump version","docs","user","proposal","new","github release",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":35},"01M6D2GRJ1MKMMEACKDFSAKF20","zudo-doc-translate","Translate zudo-doc documentation between the locales configured in this project, with Japanese conventions applied only to the `ja` locale.","https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002Fpackages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002FclaudeSkills\u002Ffiles\u002F.claude\u002Fskills\u002Fzudo-doc-translate\u002FSKILL.md",[],[126,127,25,128,129,130,34,82,131,114,132,133,134],"translate","zudo doc translate","documentation","i18n","japanese","conventions","translate docs","with","locale",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":150,"publishedAt":35},"01M6D2GMXQGVKJZTA35Q9AZN7V","zudo-doc-design-system","Project-specific CSS and component rules for zudo-doc. Must be consulted before writing or editing CSS, zudo-wind utilities, color tokens, or component markup in this project. Covers: component-first strategy, design token system, three-tier color architecture, and palette index convention. Triggered by 'design system', 'zudo-doc-design-system', 'zudo-doc-css-wisdom' (old name).","https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002Fpackages\u002Fcreate-zudo-doc\u002Ftemplates\u002Ffeatures\u002FclaudeSkills\u002Ffiles\u002F.claude\u002Fskills\u002Fzudo-doc-design-system\u002FSKILL.md",[141,144,147],{"categoryNo":142,"categoryName":143,"taxonomyType":70,"taxonomyTypeDesc":71},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":145,"categoryName":146,"taxonomyType":70,"taxonomyTypeDesc":71},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":148,"categoryName":149,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000032","设计师",[151,152,81,25,153,154,155,34,156,157,158,78,159,160,161,162,163,164,165,166,167,168,169,170,171,172],"zudo doc design system","system","design system","css","three","editing","tokens","strategy","wisdom","Rules","architecture","component","first","token","design-system","index","design token","wind","palette","Utilities","color","for",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":179,"publishedAt":35},"01M6D2GJYJQRZTHVY1CN884E96","localized-shell","Fixture skill for localized generated resource routes.","https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002Fe2e\u002Ffixtures\u002Fi18n\u002Fsrc\u002Fcontent\u002Fresources\u002F.claude\u002Fskills\u002Flocalized-shell\u002FSKILL.md",[],[180,181,182,183,184,172],"localized shell","shell","fixture","generated","fixture skill",{"skillNo":186,"name":187,"nameZh":6,"description":188,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":189,"categories":190,"keywords":193,"publishedAt":35},"01M6D2GF8BK70Y7TE3B7NCX87H","zudo-doc-writing-rules","Doc-writing rules for zudo-doc content (mdx files under src\u002Fcontent\u002Fdocs\u002F and src\u002Fcontent\u002Fdocs-ja\u002F). Consult before writing or editing doc content. Covers: no h1 in content, sidebar_position is mandatory, kebab-case file names, bilingual rule, linking conventions, and admonition syntax. Triggered by 'writing rules', 'zudo-doc-writing-rules', 'doc rule', 'mdx rule', 'write a doc', 'create a page'.","https:\u002F\u002Fgithub.com\u002Fzudolab\u002Fzudo-doc\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fzudo-doc-writing-rules\u002FSKILL.md",[191,192],{"categoryNo":68,"categoryName":69,"taxonomyType":70,"taxonomyTypeDesc":71},{"categoryNo":73,"categoryName":74,"taxonomyType":75,"taxonomyTypeDesc":76},[194,25,78,160,79,195,29,196,156,93,197,198,131,199,200,84,172,201,202,203],"zudo doc writing rules","writing rules","page","write","syntax","files","file","true","case","linking"]