@takazudo/zudo-doc 2.5.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +1038 -0
  2. package/README.md +4 -0
  3. package/dist/chrome/derive.d.ts +4 -1
  4. package/dist/chrome/derive.js +30 -25
  5. package/dist/color-scheme-utils.d.ts +153 -102
  6. package/dist/color-scheme-utils.js +168 -97
  7. package/dist/content.css +5 -5
  8. package/dist/design-token-panel-bootstrap.d.ts +37 -16
  9. package/dist/design-token-panel-bootstrap.js +47 -19
  10. package/dist/doc-page-renderer/index.d.ts +1 -0
  11. package/dist/doc-page-renderer/index.js +2 -0
  12. package/dist/doc-page-shell/index.d.ts +2 -0
  13. package/dist/doc-page-shell/index.js +2 -0
  14. package/dist/doclayout/doc-layout.d.ts +9 -0
  15. package/dist/doclayout/doc-layout.js +2 -0
  16. package/dist/features.css +19 -0
  17. package/dist/home-page/index.d.ts +8 -0
  18. package/dist/home-page/index.js +3 -1
  19. package/dist/integrations/changelog/emit.d.ts +2 -0
  20. package/dist/integrations/changelog/emit.js +24 -0
  21. package/dist/integrations/changelog/generate.d.ts +2 -0
  22. package/dist/integrations/changelog/generate.js +24 -0
  23. package/dist/integrations/changelog/index.d.ts +5 -0
  24. package/dist/integrations/changelog/index.js +11 -0
  25. package/dist/integrations/changelog/load.d.ts +3 -0
  26. package/dist/integrations/changelog/load.js +79 -0
  27. package/dist/integrations/changelog/sanitize.d.ts +10 -0
  28. package/dist/integrations/changelog/sanitize.js +24 -0
  29. package/dist/integrations/changelog/types.d.ts +31 -0
  30. package/dist/integrations/changelog/types.js +0 -0
  31. package/dist/plugins/changelog.d.ts +3 -0
  32. package/dist/plugins/changelog.js +17 -0
  33. package/dist/preset.d.ts +7 -0
  34. package/dist/preset.js +8 -0
  35. package/dist/safelist.css +1 -1
  36. package/dist/settings.d.ts +11 -0
  37. package/dist/theme/design-token-serde.d.ts +74 -33
  38. package/dist/theme/design-token-serde.js +187 -94
  39. package/dist/theme/design-token-types.d.ts +6 -10
  40. package/dist/theme/index.d.ts +1 -1
  41. package/dist/theme-toggle/color-scheme-sync.d.ts +22 -12
  42. package/eject/theme-toggle/color-scheme-sync.ts +22 -12
  43. package/package.json +18 -9
@@ -0,0 +1,24 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { generateChangelogMarkdown } from "./generate.js";
4
+ import { loadChangelogEntries } from "./load.js";
5
+ function emitChangelogs(options) {
6
+ const written = [];
7
+ for (const config of options.changelogs) {
8
+ const sourceDir = resolve(options.projectRoot, config.sourceDir);
9
+ const outputFile = resolve(options.projectRoot, config.outputFile);
10
+ const entries = loadChangelogEntries({ sourceDir });
11
+ const markdown = generateChangelogMarkdown(entries, {
12
+ title: config.title,
13
+ packageName: config.packageName
14
+ });
15
+ mkdirSync(dirname(outputFile), { recursive: true });
16
+ writeFileSync(outputFile, markdown);
17
+ written.push(outputFile);
18
+ options.logger?.info(`Generated ${config.outputFile} (${entries.length} releases)`);
19
+ }
20
+ return { written };
21
+ }
22
+ export {
23
+ emitChangelogs
24
+ };
@@ -0,0 +1,2 @@
1
+ import type { ChangelogEntry, ChangelogGenerateOptions } from "./types.js";
2
+ export declare function generateChangelogMarkdown(entries: readonly ChangelogEntry[], options?: ChangelogGenerateOptions): string;
@@ -0,0 +1,24 @@
1
+ function generateChangelogMarkdown(entries, options = {}) {
2
+ const title = options.title ?? "Changelog";
3
+ const lines = [`# ${title}`, ""];
4
+ if (options.packageName) {
5
+ lines.push(`All notable changes to \`${options.packageName}\` are documented in this file.`);
6
+ } else {
7
+ lines.push("All notable changes to this project are documented in this file.");
8
+ }
9
+ lines.push("");
10
+ lines.push("The format is based on Keep a Changelog, and release notes are generated from the changelog MDX pages.");
11
+ for (const entry of entries) {
12
+ lines.push("");
13
+ lines.push(entry.date ? `## [${entry.version}] - ${entry.date}` : `## [${entry.version}]`);
14
+ if (entry.content) {
15
+ lines.push("");
16
+ lines.push(entry.content);
17
+ }
18
+ }
19
+ lines.push("");
20
+ return lines.join("\n");
21
+ }
22
+ export {
23
+ generateChangelogMarkdown
24
+ };
@@ -0,0 +1,5 @@
1
+ export { emitChangelogs } from "./emit.js";
2
+ export { generateChangelogMarkdown } from "./generate.js";
3
+ export { compareEntriesNewestFirst, loadChangelogEntries } from "./load.js";
4
+ export { sanitizeChangelogMarkdown } from "./sanitize.js";
5
+ export type { ChangelogConfig, ChangelogEmitOptions, ChangelogEmitResult, ChangelogEntry, ChangelogGenerateOptions, ChangelogLoadOptions, ChangelogLogger, } from "./types.js";
@@ -0,0 +1,11 @@
1
+ import { emitChangelogs } from "./emit.js";
2
+ import { generateChangelogMarkdown } from "./generate.js";
3
+ import { compareEntriesNewestFirst, loadChangelogEntries } from "./load.js";
4
+ import { sanitizeChangelogMarkdown } from "./sanitize.js";
5
+ export {
6
+ compareEntriesNewestFirst,
7
+ emitChangelogs,
8
+ generateChangelogMarkdown,
9
+ loadChangelogEntries,
10
+ sanitizeChangelogMarkdown
11
+ };
@@ -0,0 +1,3 @@
1
+ import type { ChangelogEntry, ChangelogLoadOptions } from "./types.js";
2
+ export declare function loadChangelogEntries(options: ChangelogLoadOptions): ChangelogEntry[];
3
+ export declare function compareEntriesNewestFirst(a: ChangelogEntry, b: ChangelogEntry): number;
@@ -0,0 +1,79 @@
1
+ import { readdirSync } from "node:fs";
2
+ import { basename, join, resolve } from "node:path";
3
+ import { parseMarkdownFile } from "../../md-utils/index.js";
4
+ import { sanitizeChangelogMarkdown } from "./sanitize.js";
5
+ const RELEASED_RE = /^Released:\s*(\d{4}-\d{2}-\d{2})\s*$/im;
6
+ function loadChangelogEntries(options) {
7
+ const absDir = resolve(options.sourceDir);
8
+ const names = readdirSync(absDir);
9
+ const entries = [];
10
+ for (const name of names) {
11
+ if (!/\.mdx?$/.test(name) || name === "index.mdx" || name === "index.md" || name.startsWith("_")) {
12
+ continue;
13
+ }
14
+ const sourcePath = join(absDir, name);
15
+ const parsed = parseMarkdownFile(sourcePath);
16
+ if (!parsed) continue;
17
+ const version = String(parsed.data.title ?? basename(name).replace(/\.mdx?$/, ""));
18
+ const rawContent = parsed.content;
19
+ const date = rawContent.match(RELEASED_RE)?.[1];
20
+ const contentWithoutReleased = rawContent.replace(RELEASED_RE, "").trim();
21
+ const content = sanitizeChangelogMarkdown(contentWithoutReleased);
22
+ entries.push({ version, date, content, sourcePath });
23
+ }
24
+ entries.sort(compareEntriesNewestFirst);
25
+ return entries;
26
+ }
27
+ function compareEntriesNewestFirst(a, b) {
28
+ const byVersion = compareSemverLike(b.version, a.version);
29
+ if (byVersion !== 0) return byVersion;
30
+ return b.sourcePath.localeCompare(a.sourcePath);
31
+ }
32
+ function compareSemverLike(a, b) {
33
+ const parsedA = parseSemverLike(a);
34
+ const parsedB = parseSemverLike(b);
35
+ if (!parsedA || !parsedB) return a.localeCompare(b, void 0, { numeric: true });
36
+ for (const key of ["major", "minor", "patch"]) {
37
+ const diff = parsedA[key] - parsedB[key];
38
+ if (diff !== 0) return diff;
39
+ }
40
+ if (!parsedA.pre && !parsedB.pre) return 0;
41
+ if (!parsedA.pre) return 1;
42
+ if (!parsedB.pre) return -1;
43
+ return comparePrerelease(parsedA.pre, parsedB.pre);
44
+ }
45
+ function parseSemverLike(version) {
46
+ const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/);
47
+ if (!match) return null;
48
+ return {
49
+ major: Number(match[1]),
50
+ minor: Number(match[2]),
51
+ patch: Number(match[3]),
52
+ pre: match[4] ? match[4].split(".") : null
53
+ };
54
+ }
55
+ function comparePrerelease(a, b) {
56
+ const len = Math.max(a.length, b.length);
57
+ for (let i = 0; i < len; i += 1) {
58
+ const left = a[i];
59
+ const right = b[i];
60
+ if (left === void 0) return -1;
61
+ if (right === void 0) return 1;
62
+ const leftNum = /^\d+$/.test(left) ? Number(left) : null;
63
+ const rightNum = /^\d+$/.test(right) ? Number(right) : null;
64
+ if (leftNum !== null && rightNum !== null) {
65
+ const diff2 = leftNum - rightNum;
66
+ if (diff2 !== 0) return diff2;
67
+ continue;
68
+ }
69
+ if (leftNum !== null) return -1;
70
+ if (rightNum !== null) return 1;
71
+ const diff = left.localeCompare(right);
72
+ if (diff !== 0) return diff;
73
+ }
74
+ return 0;
75
+ }
76
+ export {
77
+ compareEntriesNewestFirst,
78
+ loadChangelogEntries
79
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Convert authored MDX-ish changelog body content into package-safe
3
+ * CommonMark. This deliberately handles the MDX constructs that should not
4
+ * leak into `node_modules/CHANGELOG.md` while preserving normal markdown.
5
+ *
6
+ * Fenced code blocks are protected from these transforms first - a changelog
7
+ * entry documenting a code change can legitimately contain `import`/`export`/
8
+ * JSX syntax inside an example, and that must survive verbatim.
9
+ */
10
+ export declare function sanitizeChangelogMarkdown(content: string): string;
@@ -0,0 +1,24 @@
1
+ const FENCED_CODE_BLOCK_RE = /^([ \t]*```[^\n]*\n[\s\S]*?\n[ \t]*```[ \t]*)$/gm;
2
+ function sanitizeChangelogMarkdown(content) {
3
+ const codeBlocks = [];
4
+ const withPlaceholders = content.replace(FENCED_CODE_BLOCK_RE, (match) => {
5
+ const token = `CHANGELOG_CODE_BLOCK_PLACEHOLDER_${codeBlocks.length}`;
6
+ codeBlocks.push(match);
7
+ return token;
8
+ });
9
+ const sanitized = withPlaceholders.replace(/^import\s+.*$/gm, "").replace(/^export\s+.*$/gm, "").replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/^:::\s*([A-Za-z][\w-]*).*$/gm, (_m, name) => {
10
+ return `> **${labelize(name)}**`;
11
+ }).replace(/^:::\s*$/gm, "").replace(/^<([A-Z][A-Za-z0-9]*)\b[^>]*>\s*$/gm, (_m, name) => {
12
+ return `> **${labelize(name)}**`;
13
+ }).replace(/^<\/[A-Z][A-Za-z0-9]*>\s*$/gm, "").replace(/<\/?[A-Z][A-Za-z0-9]*\b[^>]*>/g, "").replace(/\n{3,}/g, "\n\n").trim();
14
+ return codeBlocks.reduce(
15
+ (acc, block, i) => acc.replace(`CHANGELOG_CODE_BLOCK_PLACEHOLDER_${i}`, () => block),
16
+ sanitized
17
+ ).trim();
18
+ }
19
+ function labelize(name) {
20
+ return name.replace(/[-_]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/\b\w/g, (ch) => ch.toUpperCase());
21
+ }
22
+ export {
23
+ sanitizeChangelogMarkdown
24
+ };
@@ -0,0 +1,31 @@
1
+ export interface ChangelogConfig {
2
+ sourceDir: string;
3
+ outputFile: string;
4
+ packageName?: string;
5
+ title?: string;
6
+ }
7
+ export interface ChangelogEmitOptions {
8
+ projectRoot: string;
9
+ changelogs: readonly ChangelogConfig[];
10
+ logger?: ChangelogLogger;
11
+ }
12
+ export interface ChangelogEmitResult {
13
+ written: string[];
14
+ }
15
+ export interface ChangelogLogger {
16
+ info(message: string): void;
17
+ warn?(message: string): void;
18
+ }
19
+ export interface ChangelogEntry {
20
+ version: string;
21
+ date?: string;
22
+ content: string;
23
+ sourcePath: string;
24
+ }
25
+ export interface ChangelogLoadOptions {
26
+ sourceDir: string;
27
+ }
28
+ export interface ChangelogGenerateOptions {
29
+ title?: string;
30
+ packageName?: string;
31
+ }
File without changes
@@ -0,0 +1,3 @@
1
+ import type { ZfbPlugin } from "@takazudo/zfb/plugins";
2
+ declare const plugin: ZfbPlugin;
3
+ export default plugin;
@@ -0,0 +1,17 @@
1
+ import { emitChangelogs } from "../integrations/changelog/index.js";
2
+ const plugin = {
3
+ name: "changelog",
4
+ async postBuild(ctx) {
5
+ const changelogs = ctx.options["changelogs"];
6
+ if (!Array.isArray(changelogs) || changelogs.length === 0) return;
7
+ emitChangelogs({
8
+ projectRoot: ctx.projectRoot,
9
+ changelogs,
10
+ logger: ctx.logger
11
+ });
12
+ }
13
+ };
14
+ var changelog_default = plugin;
15
+ export {
16
+ changelog_default as default
17
+ };
package/dist/preset.d.ts CHANGED
@@ -56,6 +56,12 @@ export interface PresetClaudeResourcesConfig {
56
56
  */
57
57
  scanRoot?: string;
58
58
  }
59
+ export interface PresetChangelogConfig {
60
+ sourceDir: string;
61
+ outputFile: string;
62
+ packageName?: string;
63
+ title?: string;
64
+ }
59
65
  /**
60
66
  * The subset of `settings` the preset reads. Any concrete `typeof settings`
61
67
  * (this repo's or a generated project's) is assignable to this — the preset
@@ -74,6 +80,7 @@ export interface PresetSettings {
74
80
  onBrokenMarkdownLinks: "warn" | "error" | "ignore";
75
81
  headingIdStrategy: "flat" | "hierarchical";
76
82
  llmsTxt?: boolean;
83
+ changelogs?: PresetChangelogConfig[] | false;
77
84
  docHistory?: boolean;
78
85
  claudeResources?: PresetClaudeResourcesConfig | false;
79
86
  /** "owner/repo" — when set, enables `#123` / SHA autolinks in markdown. Omit to disable entirely. */
package/dist/preset.js CHANGED
@@ -206,6 +206,14 @@ function buildPlugins(settings, routeContext) {
206
206
  locales: localeArray
207
207
  }
208
208
  }
209
+ ] : [],
210
+ ...Array.isArray(settings.changelogs) && settings.changelogs.length > 0 ? [
211
+ {
212
+ name: "@takazudo/zudo-doc/plugins/changelog",
213
+ options: {
214
+ changelogs: settings.changelogs.map((changelog) => ({ ...changelog }))
215
+ }
216
+ }
209
217
  ] : []
210
218
  ];
211
219
  }
package/dist/safelist.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /* generated by gen-safelist.mjs — do not edit by hand */
2
- @source inline("-link -mb-px -ml-hsp-sm -noscript -translate-x-full 2xl:w-[24px] [&::-webkit-details-marker]:hidden [&_a]:text-accent [&_a]:underline [&_nav]:mb-0 [data-admonition] [data-kbd-shortcut] [doc-history-meta] [doc-history] [doc-layout] [llms-txt] a a2 abbr about above absent absolute accent across activated active actual added admonition admonition- admonition-body admonition-title admonition/callout after after-breadcrumb after-content after-navigate after-sidebar after-title against agent agents ai-chat ai-chat-md ai-chat-trigger alert align-top all allow-same-origin allow-scripts alone already already-executed already-picked an anchor anchored and and/or animate-spin announce antialiased any application/json application/xml applies apply-css-vars approach are area arg aria-atomic aria-busy aria-controls aria-current aria-disabled aria-expanded aria-haspopup aria-hidden aria-label aria-live aria-orientation aria-pressed aria-selected aria-valuemax aria-valuemin aria-valuenow arm arms arrows article as asc aside aspect-[1200/630] aspect-square asset- assets assistant async at attach attribute attributes auto autogenerated available avoid await away b back backdrop:bg-bg/30 backdrop:bg-bg/80 backdrop:bg-overlay/60 backdrop:z-modal-backdrop background background-color backtick backticks baked banner bare base base64 based batch be because before below best between bg bg-[#fff] bg-accent bg-bg bg-chat-assistant-bg bg-chat-user-bg bg-code-bg bg-fg bg-info/10 bg-info/5 bg-muted bg-overlay/30 bg-surface bg-transparent bg-warning/10 bg-warning/5 bi bigint bin blank blanks blob block blockquote blocks blur body body-end-components body-end-scripts bold boolean bootstrap border border-accent border-b border-b-2 border-b-[5px] border-bg/30 border-collapse border-danger border-dashed border-fg border-info/30 border-l border-l-0 border-l-[3px] border-left-width border-muted border-none border-r border-radius border-solid border-t border-t-[2px] border-t-[3px] border-transparent border-warning/30 border-width border-y both bottom-vsp-xl box-border br brand breadcrumb:end breadcrumb:start break-words browser browsers btn bug build bundler but button buttons by bypassed byte-identical bytes cached call caller calls can cancellation cannot canonical canvas caption card card-grid carry cases cat-nav- catch category catppuccin-latte caught caution center center/contain ch chains change changed changes checkbox child chrome ci circle cite class class-less claude claude-agents claude-commands claude-md claude-skills cleaned clear clear-css-vars clearing click client client-router client-side clip clobbering close closed closing code code-block-sr-announce code-group code-group-panel col col-resize colgroup collision color color-scheme color-scheme-changed color-scheme-provider color-tweak colorization colors column comma command commands comment commit compare component component:github-link component:language-switcher component:search component:theme-toggle component:version-switcher compute computed concrete configuration configure configured confuse connect const construction consumer consumes container containers containing content content-admonition content-link content-type content-wrapper:end content-wrapper:start contents context controller controls converts copy corners correct correctly corrupt count covered covers cp crashes created cross-component crumb- cs css ctx cur current cursor cursor-not-allowed cursor-pointer custom danger dark data data-active data-admonition data-base data-close-search data-current-locale data-default-locale data-group-id data-header data-header-logo data-header-nav data-header-right data-kbd-shortcut data-language-switcher data-loading-index data-mermaid-enlarge-ready data-mermaid-rendered data-mermaid-src data-nav-active data-nav-item data-nav-item-dropdown data-nav-more data-nav-more-menu data-nav-more-toggle data-no-results data-open-search data-pan-active data-processed data-result-count-template data-search-count data-search-count-narrow data-search-dialog data-search-input data-search-placeholder data-search-results data-search-unavailable data-sidebar-hidden data-sidebar-resizer data-site-nav data-tab-btn data-tab-default data-tab-label data-tab-value data-tabs data-taglist-group data-testid data-theme data-theme/style data-trailing-slash data-variant data-version-banner data-version-latest data-version-menu data-version-rewire data-version-slug data-version-switcher data-version-toggle data-version-trigger-label data-zd-nosidebar data-zd-toc data-zfb-transition-persist dd decimal declare decoration decoration-muted default defaults del delegated dependency depth desc description design design-token-panel design-token-trigger desktop desktop-sidebar desktop-sidebar-toggle desktop-sidebar-toggle-island destructive detach detached details deterministic develop dfn diagram diagrams dialog dieser diff diff-line-added diff-line-content diff-line-empty diff-line-num diff-line-removed diff-row dir directly directories directory disabled disabled:opacity-50 disc display:none dist distinct div dl do doc doc-card- doc-content-band doc-history doc-history-generate doc-history-panel doc-history-trigger doc-page doc-pager doc-prose doc-title docs docs- docs-v- document document-level documented does double-registration drag draggable drop dropdown dropdown-child dropdown-parent dropdowns dt duration-150 duration-200 during dynamically e2e each ease-in-out edge eject ejected el element elements els else em embedded emit emitting empty empty/undefined en enable end enlarged entire entities entries entry error escape escaped even eventually every exactly excerpt excludes existing exists exit expected export extends factories failed fall fallback fallbacks falls false family fast feature feed fg fields fieldset figcaption figure file fill fills finally find fire fires first fixed fixed-width fixtures flag flash flat flex flex-1 flex-col flex-wrap flip flipping flips flush-left focus focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-2 focus-visible:underline focus:border-accent focus:outline-none focus:underline font font-bold font-family font-medium font-mono font-semibold font-weight footer footer- for form found free fresh from frontmatter frontmatter-preview frozen fs-extra full fully function further g gap-[0.3em] gap-[clamp(1.5rem,3vw,4rem)] gap-hsp-2xs gap-hsp-md gap-hsp-sm gap-hsp-xl gap-hsp-xs gap-vsp-2xs gap-vsp-lg gap-vsp-md gap-vsp-xs gap-x-hsp-2xs gap-x-hsp-lg gap-x-hsp-md gap-x-hsp-sm gap-x-hsp-xs gap-y-vsp-2xs gap-y-vsp-lg gap-y-vsp-md gap-y-vsp-xs gaps gate generate generation genuine geometry get github github-link go got graph gray-matter grid grid-cols-1 grid-cols-2 group group-focus-visible:text-accent group-focus-visible:underline group-focus-within:block group-hover:bg-fg group-hover:block group-hover:text-accent group-hover:text-bg group-hover:underline group-open:rotate-90 guard h-[0.5rem] h-[0.625rem] h-[0.875rem] h-[1.125rem] h-[1.25rem] h-[1.575rem] h-[14px] h-[1em] h-[1lh] h-[2rem] h-[3.5rem] h-[3rem] h-[90vh] h-[calc(100%-3rem)] h-[calc(100vh-3.5rem)] h-dvh h-full h-icon-lg h-icon-md h-icon-sm h-icon-xs h1 h1s h2 h2s h3 h4 h5 h6 half hand hand-copied handle handled handler handlers has hash-link have head head-links head-scripts header header- header-call:end header-call:start heading heading-h2 heading-h3 heading-h4 headings height here hex hidden highlight highlighter history hit horizontal host hover:bg-[color-mix(in_srgb,var(--color-surface)_80%,var(--color-fg)_20%)] hover:bg-accent-hover hover:bg-accent/10 hover:bg-surface hover:border-accent hover:border-accent-hover hover:border-fg hover:text-accent hover:text-accent-hover hover:text-fg hover:underline hr href hrefs html i i18n/theme. i2 i3 i4 icon identical idle idx if iframe image image-enlarge image/png img implementation import important imports in inactive inbox includes index info inherit inherited initial initialised injected inline inline-block inline-flex inner input input-clear ins inset-0 inside install instance instanceof instead instructions intended intent into invalid inverse inversion invoke is issues it italic item item- items items-baseline items-center items-start its itself javascript justify-between justify-center justify-end justify-start katex kbd keep keeps kept keyboard keyboard-shortcut keydown keystroke keywords khroma label landing language-switcher last:border-b-0 later launch layout leading-relaxed leading-snug leading-tight leaf- leak leaves leaving left left-0 left:calc legend legitimate letter-spacing lg lg:block lg:border lg:border-fg lg:border-solid lg:flex lg:flex-col lg:flex-row lg:gap-hsp-xl lg:grid-cols-[repeat(auto-fit,minmax(12rem,1fr))] lg:h-[90vh] lg:hidden lg:justify-start lg:m-auto lg:max-h-[90vh] lg:max-w-[52.5rem] lg:ml-[var(--zd-sidebar-w)] lg:pt-vsp-2xl lg:px-hsp-2xl lg:py-vsp-2xl lg:text-left lg:w-[90vw] lg:w-[clamp(16rem,25%,22rem)] li li2 library light like likely line linger link link- links list-disc list-none listener literal literals lives llms llms-txt load local locale locales log longest-match look lostpointercapture lower luminance m m-0 m21 m6 main make malformed malicious maps mark marks matches matching math math-display math-inline max max-h-[80vh] max-h-[85vh] max-h-[90vh] max-h-full max-h-none max-w-[46rem] max-w-[85%] max-w-[85vw] max-w-[90vw] max-w-[clamp(50rem,75vw,90rem)] max-w-full max-w-none max-width may mb-0 mb-vsp-2xs mb-vsp-lg mb-vsp-md mb-vsp-sm mb-vsp-xl mb-vsp-xs measures measuring mechanism menu merged mermaid message messages meta meta-knob metadata migration min-h-[60vh] min-h-[calc(100vh-3.5rem)] min-h-screen min-w-0 min-w-[10rem] min-w-[8rem] mirror mirrors missing ml-auto ml-hsp-2xl ml-hsp-lg ml-hsp-sm ml-hsp-xl mod mode module mounted mouseenter mouseleave mr-hsp-sm mt-0 mt-vsp-2xl mt-vsp-2xs mt-vsp-3xs mt-vsp-lg mt-vsp-md mt-vsp-sm mt-vsp-xl must mutates mutation mutations mx-auto my-vsp-lg my-vsp-md name named native nav nav-active nav-card- nav/doc navigating navigation navigations near needs nested new newly-swapped next no no-enlarge no-op no-repeat no-underline node node:buffer node:fs node:fs/promises node:module node:path nodes nofollow noindex non-empty non-light-dark non-persisted non-string none noopener noreferrer normal noscript not not-object note now null number numeric object object-contain observe observer occurred of off og:description og:image og:image:alt og:image:height og:image:width og:title og:type og:url ol old older on once one only onto opacity-60 open open/close option or original other others out outline-none over overflow overflow-auto overflow-hidden overflow-x-auto overflow-y-auto overflow-y:auto overwrite own p p-0 p-hsp-lg p-hsp-md p-hsp-sm p-hsp-xl package package-owned packages padding page page-loading page-loading-overlay page-loading-spinner page-navigate-end page-title pages pages/. paint paint-and-read pan panel panels paren-balance-aware parent parse parsed pass passed passes path paths pattern pb-[50vh] pb-vsp-md pb-vsp-xl pb-vsp-xs per per-link permanently persisted pi pick picked picks picocolors pins pipelines pl-[1.25rem] pl-hsp-lg pl-hsp-sm pl-hsp-xl place placeholder placeholder:text-muted plain plural plus pnpm pointer-events-none pointercancel pointerdown pointermove pointerup polite polygon polyline populates port position position:fixed pr-[4px] pr-hsp-lg pr-hsp-md pr-hsp-sm pr-hsp-xl pre pre-lowercased preact preact/compat preact/hooks preact/jsx-runtime preconnect prefix preload pres preserving print produce produced produces production project project-root-relative properties property props prose provided proxy pt-[0.15rem] pt-[2px] pt-vsp-3xs pt-vsp-md pt-vsp-sm pt-vsp-xl pt-vsp-xs ptag- public purely px px-hsp-2xl px-hsp-2xs px-hsp-lg px-hsp-md px-hsp-sm px-hsp-xl px-hsp-xs py-0 py-[2px] py-[calc(var(--spacing-vsp-xs)+0.15rem)] py-hsp-2xs py-hsp-sm py-hsp-xs py-vsp-2xs py-vsp-3xs py-vsp-lg py-vsp-md py-vsp-sm py-vsp-xl py-vsp-xs q query question r radius raw re-encode/decode re-querying re-render re-renders re-run re-running re-selects reach reached reaches read reading ready real real-value received receives recorded recovers redefine ref- references refetch refreshes regenerate regenerates regex reinit reinits relative reload relying remove removed render rendered renders reorder repaint repeated repeating replaced replaces repopulate requires reserved resize resize-x resolve resolved resolves response restore restores result result-click results results-area retry return returns revision revisions rewrite right right- right-0 ro robots role root rotate-180 rotate-90 round round-trip rounded rounded-[0.75rem] rounded-bl-[0.25rem] rounded-bl-[1rem] rounded-br-[0.25rem] rounded-br-[1rem] rounded-full rounded-lg rounded-t-[1rem] rounds route router routes routes-src running runs runtime s safe safer same same-locale samp scale scanned schema-mismatch schema-missing scheme scored script script- script-eval script-evaluation script-injection scripts scroll scrollbar scrolled scrollend search search-index section section- see sel-bg sel-fg select select-none self self-start semibold sentinel separator serialised serialize server server-rendered set sets setting setup shadow-[0_1px_3px_color-mix(in_srgb,var(--color-fg)_8%,transparent)] shadow-lg shape share shared sharing shiki ship shipped ships short shortcut should show shown shrink-0 sidebar sidebar- sidebar-toggle-island sidebar-tree-island signal similarity single singular site-search site-tree-nav-island sitemap- sites size skill skills skipping skips slash slug sm:border sm:border-muted sm:flex-row sm:grid-cols-2 sm:h-auto sm:items-center sm:justify-between sm:max-h-[80vh] sm:max-w-[52rem] sm:mx-auto sm:my-[10vh] sm:rounded-lg small smooth snapshot snapshots so soft soft-nav solid some somehow source sources space-y-vsp-2xs spacing span spans spec specifier specifiers splitter square sr-only src stale start state status stay staying sticky still stop stored stray string strings strip stripe stroke-linecap stroke-linejoin stroke-width strong stronger style style-attribute styled styles stylesheet sub subagents subsequent success successful summary sup surfaces survives svg swap swapped swaps synchronous synchronously syntactically syntect t tab tab-item tab-panel tabindex table tablist tabpanel tabs tabs-container tabs-content tabs-nav tag tag- tag-item- tags tags:audit take tbody td temp-element template temporary temporary-element terminal terms test-results tested text text-accent text-bg text-body text-caption text-center text-chat-assistant-text text-chat-user-text text-code-fg text-danger text-decoration text-display text-fg text-heading text-info text-left text-micro text-muted text-muted/50 text-right text-small text-title text-warning text/plain textarea tfoot th that the thead their them theme theme-color theme-toggle theme/token then there these they this through throw tighten time tip title to toc toggle toggle-ai-chat toggle-design-token-panel toggles token tokens tolerates too toolbar top-0 top-[3.5rem] top-full top-level total touches tp tr tracked tracking-wider trade-off transition transition-[background,color,border-color] transition-[left,color] transition-colors transition-transform translate-x-0 translations transparent treats tree tree-child- tree-item- tree-top- trigger trigger:ai-chat trigger:design-token-panel triggers true truncate truncated try turn twitter:card twitter:creator twitter:description twitter:image twitter:site twitter:title two type typography u ul unavailable unchanged undefined under underline underlines understand unit-tested unknown unmaintained unobserve unreadable unrelated unreleased unset unsupported up uppercase usage use used user uses utf-8 utf8 utilities utility v v2 val value value-reader values var variable variant verbatim version version- version-menu version-switcher vertical via video viewport virtual:zudo-doc-chrome-bindings virtual:zudo-doc-route-context visible vitesse-dark vocabulary w w-1/2 w-[0.5rem] w-[0.625rem] w-[0.875rem] w-[1.125rem] w-[1.575rem] w-[1.5rem] w-[1.75rem] w-[14px] w-[16px] w-[16rem] w-[18px] w-[1em] w-[280px] w-[2rem] w-[320px] w-[90vw] w-[var(--zd-sidebar-w)] w-dvw w-full w-icon-lg w-icon-md w-icon-sm w-icon-xs want warning was watching wbr wbr- we website weight went were what when where whereas whether which while whitespace-nowrap whitespace-pre whole wide-gamut width will with without word working worktrees would wrap wrapper wrappers written wrong wrote xl:flex xl:hidden y-scrollbar yet you your z-dropdown z-local-1 z-modal z-modal-backdrop z-sidebar z-toolbar zd-content zd-desktop-sidebar-toggle zd-doc-content-band zd-enlarge-btn zd-enlarge-dialog zd-enlarge-dialog-close zd-enlargeable zd-html-preview-code zd-mermaid-dialog zd-mermaid-enlargeable zd-mermaid-tool-btn zd-mermaid-toolbar zd-mermaid-transform zd-mermaid-viewport zd-sidebar-content-wrapper zd-sidebar-open zfb zfb:after-swap zfb:before-preparation zod zoom zudo-doc-design-tokens/v1 zudo-doc-sidebar-visible zudo-doc-sidebar-width zudo-doc-theme zudo-doc-theme-bridge");
2
+ @source inline("-link -mb-px -ml-hsp-sm -noscript -open -translate-x-full 2xl:w-[24px] [&::-webkit-details-marker]:hidden [&_a]:text-accent [&_a]:underline [&_nav]:mb-0 [data-admonition] [data-kbd-shortcut] [doc-history-meta] [doc-history] [doc-layout] [llms-txt] [zudo-doc] a a2 abbr about above absent absolute accent accent:accent- across activated active actual added admonition admonition- admonition-body admonition-title admonition/callout after after-breadcrumb after-content after-navigate after-sidebar after-title against agent agents ai-chat ai-chat-md ai-chat-trigger alert align-top all allow-same-origin allow-scripts alone already already-executed already-picked an anchor anchored and and/or animate-spin announce antialiased any application/json application/xml applies apply-css-vars approach are area arg aria-atomic aria-busy aria-controls aria-current aria-disabled aria-expanded aria-haspopup aria-hidden aria-label aria-live aria-orientation aria-pressed aria-selected aria-valuemax aria-valuemin aria-valuenow arm arms array arrows article as asc aside aspect-[1200/630] aspect-square asset- assets assistant async at attach attribute attributes auto autogenerated available avoid await away b back backdrop:bg-bg/30 backdrop:bg-bg/80 backdrop:bg-overlay/60 backdrop:z-modal-backdrop background background-color backtick backticks baked banner bare base base64 base:base- based baseline batch be because before below best between bg bg-[#fff] bg-accent bg-bg bg-chat-assistant-bg bg-chat-user-bg bg-code-bg bg-fg bg-info/10 bg-info/5 bg-muted bg-overlay/30 bg-surface bg-transparent bg-warning/10 bg-warning/5 bi bigint bin blank blanks blob block blockquote blocks blur body body-end-components body-end-scripts bold boolean bootstrap border border-accent border-b border-b-2 border-b-[5px] border-bg/30 border-collapse border-danger border-dashed border-fg border-info/30 border-l border-l-0 border-l-[3px] border-left-width border-muted border-none border-r border-radius border-solid border-t border-t-[2px] border-t-[3px] border-transparent border-warning/30 border-width border-y both bottom-vsp-xl box-border br brand breadcrumb:end breadcrumb:start break-words browser browsers btn bug build bundler but button buttons by bypassed byte-identical bytes cached call caller calls can cancellation cannot canonical canvas caption card card-grid carry cases cat-nav- catch category catppuccin-latte caught caution center center/contain ch chains change changed changelog changelogs changes checkbox child chrome ci circle cite class class-less claude claude-agents claude-commands claude-md claude-skills cleaned clear clear-css-vars clearing click client client-router client-side clip clobbering close closed closing code code-block-sr-announce code-group code-group-panel col col-resize colgroup collision color color-scheme color-scheme-changed color-scheme-provider color-tweak colorization colors column comma command commands comment commit compare component component:github-link component:language-switcher component:search component:theme-toggle component:version-switcher compute computed concrete configuration configure configured confuse connect const construction consumer consumes container containers containing content content-admonition content-link content-type content-wrapper:end content-wrapper:start contents context controller controls converts copy corners correct correctly corrupt count covered covers cp crashes created cross-component crumb- cs css ctx cur current cursor-not-allowed cursor-pointer custom danger dark data data-active data-admonition data-base data-close-search data-current-locale data-default-locale data-group-id data-header data-header-logo data-header-nav data-header-right data-kbd-shortcut data-language-switcher data-loading-index data-mermaid-enlarge-ready data-mermaid-rendered data-mermaid-src data-nav-active data-nav-item data-nav-item-dropdown data-nav-more data-nav-more-menu data-nav-more-toggle data-no-results data-open-search data-pan-active data-processed data-result-count-template data-search-count data-search-count-narrow data-search-dialog data-search-input data-search-placeholder data-search-results data-search-unavailable data-sidebar-hidden data-sidebar-resizer data-site-nav data-tab-btn data-tab-default data-tab-label data-tab-value data-tabs data-taglist-group data-testid data-theme data-theme/style data-trailing-slash data-variant data-version-banner data-version-latest data-version-menu data-version-rewire data-version-slug data-version-switcher data-version-toggle data-version-trigger-label data-zd-nosidebar data-zd-toc data-zd-wide data-zfb-transition-persist dd decimal declare decoration decoration-muted default defaults del delegated dependency depth desc description design design-token design-token-panel design-token-trigger desktop desktop-sidebar desktop-sidebar-toggle desktop-sidebar-toggle-island destructive detach detached details detected deterministic develop dfn diagram diagrams dialog dieser diff diff-line-added diff-line-content diff-line-empty diff-line-num diff-line-removed diff-row dir directly directories directory disabled disabled:opacity-50 disc display:none dist distinct div dl do doc doc-card- doc-content-band doc-history doc-history-generate doc-history-panel doc-history-trigger doc-page doc-pager doc-prose doc-title docs docs- docs-v- document document-level documented does double-registration drag draggable drop dropdown dropdown-child dropdown-parent dropdowns dt duration-150 duration-200 during dynamically e2e each ease-in-out edge eject ejected el element elements els else em embedded emit emitting empty empty/undefined en enable end enlarged entire entities entries entry error escape escaped even eventually every exactly excerpt excludes existing exists exit expected export extends factories failed faithful fall fallback fallbacks falls false family fast feature feed fg fields fieldset figcaption figure file fill fills finally find fire fires first fixed fixed-width fixtures flag flash flat flex flex-1 flex-col flex-wrap flip flipping flips flush-left focus focus-visible:outline-2 focus-visible:outline-accent focus-visible:outline-offset-2 focus-visible:underline focus:border-accent focus:outline-none focus:underline font font-bold font-family font-medium font-mono font-semibold font-weight footer footer- for form format found free fresh from frontmatter frontmatter-preview frozen fs-extra full fully function further g gap-[0.3em] gap-[clamp(1.5rem,3vw,4rem)] gap-hsp-2xs gap-hsp-md gap-hsp-sm gap-hsp-xl gap-hsp-xs gap-vsp-2xs gap-vsp-lg gap-vsp-md gap-vsp-xs gap-x-hsp-2xs gap-x-hsp-lg gap-x-hsp-md gap-x-hsp-sm gap-x-hsp-xs gap-y-vsp-2xs gap-y-vsp-lg gap-y-vsp-md gap-y-vsp-xs gaps gate generate generated generation genuine geometry get github github-link go got graph gray-matter grid grid-cols-1 grid-cols-2 group group-focus-visible:text-accent group-focus-visible:underline group-focus-within:block group-hover:bg-fg group-hover:block group-hover:text-accent group-hover:text-bg group-hover:underline group-open:rotate-90 guard h-[0.5rem] h-[0.625rem] h-[0.875rem] h-[1.125rem] h-[1.25rem] h-[1.575rem] h-[14px] h-[1em] h-[1lh] h-[2rem] h-[3.5rem] h-[3rem] h-[90vh] h-[calc(100%-3rem)] h-[calc(100vh-3.5rem)] h-dvh h-full h-icon-lg h-icon-md h-icon-sm h-icon-xs h1 h1s h2 h2s h3 h4 h5 h6 half hand hand-copied handle handled handler handlers has hash-link have head head-links head-scripts header header- header-call:end header-call:start heading heading-h2 heading-h3 heading-h4 headings height here hex hidden highlight highlighter history hit horizontal host hover:bg-[color-mix(in_srgb,var(--color-surface)_80%,var(--color-fg)_20%)] hover:bg-accent-hover hover:bg-accent/10 hover:bg-surface hover:border-accent hover:border-accent-hover hover:border-fg hover:text-accent hover:text-accent-hover hover:text-fg hover:underline hr href hrefs html i i18n/theme. i2 i3 i4 icon identical idle idx if iframe image image-enlarge image/png img implementation import important imports in inactive inbox includes index info inherit inherited initial initialised injected inline inline-block inline-flex inner input input-clear ins inset-0 inside install instance instanceof instead instructions intended intent into invalid inverse inversion invoke is issues it italic item item- items items-baseline items-center items-start its itself javascript justify-between justify-center justify-end justify-start katex kbd keep keeps kept keyboard keyboard-shortcut keydown keystroke keywords khroma label landing language-switcher last:border-b-0 later launch layout leading-relaxed leading-snug leading-tight leaf- leak leaves left left-0 left:calc legend legitimate letter-spacing lg lg:block lg:border lg:border-fg lg:border-solid lg:flex lg:flex-col lg:flex-row lg:gap-hsp-xl lg:grid-cols-[repeat(auto-fit,minmax(12rem,1fr))] lg:h-[90vh] lg:hidden lg:justify-start lg:m-auto lg:max-h-[90vh] lg:max-w-[52.5rem] lg:ml-[var(--zd-sidebar-w)] lg:pt-vsp-2xl lg:px-hsp-2xl lg:py-vsp-2xl lg:text-left lg:w-[90vw] lg:w-[clamp(16rem,25%,22rem)] li li2 library light like likely line linger link link- links list-disc list-none listener literal literals lives llms llms-txt load local locale locales log longest-match look lostpointercapture lower luminance m m-0 m21 m6 main major make malformed malicious maps mark marks matches matching math math-display math-inline max max-h-[80vh] max-h-[85vh] max-h-[90vh] max-h-full max-h-none max-w-[46rem] max-w-[85%] max-w-[85vw] max-w-[90vw] max-w-[clamp(50rem,75vw,90rem)] max-w-full max-w-none max-width may mb-0 mb-vsp-2xs mb-vsp-lg mb-vsp-md mb-vsp-sm mb-vsp-xl mb-vsp-xs measures measuring mechanism menu merged mermaid message messages meta meta-knob metadata migration min-h-[60vh] min-h-[calc(100vh-3.5rem)] min-h-screen min-w-0 min-w-[10rem] min-w-[8rem] minor mirror mirrors missing ml-auto ml-hsp-2xl ml-hsp-lg ml-hsp-sm ml-hsp-xl mod mode module mounted mouseenter mouseleave mr-hsp-sm mt-0 mt-vsp-2xl mt-vsp-2xs mt-vsp-3xs mt-vsp-lg mt-vsp-md mt-vsp-sm mt-vsp-xl must mutates mutation mutations muted mx-auto my-vsp-lg my-vsp-md name named native nav nav-active nav-card- nav/doc navigating navigation navigations near needs nested new newly-swapped next no no-enlarge no-op no-repeat no-underline node node:buffer node:fs node:fs/promises node:module node:path nodes nofollow noindex non-empty non-light-dark non-persisted none noopener noreferrer normal noscript not not-object notable note notes now null number numeric object object-contain observe observer occurred of off og:description og:image og:image:alt og:image:height og:image:width og:title og:type og:url oklch ol old older on once one only onto opacity-60 open open/close option or original other others out outline-none over overflow overflow-auto overflow-hidden overflow-x-auto overflow-y-auto overflow-y:auto overwrite own p p-0 p-hsp-lg p-hsp-md p-hsp-sm p-hsp-xl package package-owned packages padding page page-loading page-loading-overlay page-loading-spinner page-navigate-end page-title pages pages/. paint paint-and-read palette pan panel panels paren-balance-aware parent parse parsed pass passed passes patch path paths pattern pb-[50vh] pb-vsp-md pb-vsp-xl pb-vsp-xs per per-link permanently persisted pi pick picked picks picocolors pins pipelines pl-[1.25rem] pl-hsp-lg pl-hsp-sm pl-hsp-xl place placeholder placeholder:text-muted plain plural plus pnpm pointer-events-none pointercancel pointerdown pointermove pointerup polite polygon polyline populates port position position:fixed pr-[4px] pr-hsp-lg pr-hsp-md pr-hsp-sm pr-hsp-xl pre pre-lowercased preact preact/compat preact/hooks preact/jsx-runtime preconnect prefix preload pres preserving print produce produced produces production project project-root-relative properties property props prose provided proxy pt-[0.15rem] pt-[2px] pt-vsp-3xs pt-vsp-md pt-vsp-sm pt-vsp-xl pt-vsp-xs ptag- public purely px px-hsp-2xl px-hsp-2xs px-hsp-lg px-hsp-md px-hsp-sm px-hsp-xl px-hsp-xs py-0 py-[2px] py-[calc(var(--spacing-vsp-xs)+0.15rem)] py-hsp-2xs py-hsp-sm py-hsp-xs py-vsp-2xs py-vsp-3xs py-vsp-lg py-vsp-md py-vsp-sm py-vsp-xl py-vsp-xs q query question r radius ramp range raw re-encode/decode re-querying re-render re-renders re-run re-running re-selects reach reached reaches read reading ready real real-value received receives recorded recovers redefine ref- references refetch refreshes regenerate regenerates regex reinit reinits relative release reload relying remove removed render rendered renders reorder repaint repeated repeating replaced replaces repopulate requires reserved reset resize resize-x resolve resolved resolves response restore restores result result-click results results-area retry return returns revision revisions rewrite right right- right-0 ro robots role roles root rotate-180 rotate-90 round round-trip rounded rounded-[0.75rem] rounded-bl-[0.25rem] rounded-bl-[1rem] rounded-br-[0.25rem] rounded-br-[1rem] rounded-full rounded-lg rounded-t-[1rem] rounds route router routes routes-src running runs runtime s safe safer same same-locale samp scale scanned schema-mismatch schema-missing scheme scored script script- script-eval script-evaluation script-injection scripts scroll scrollbar scrolled scrollend search search-index section section- see select select-none selection-bg selection-fg self self-start semibold sentinel separator serialised serialize server server-rendered set sets setting setup shadow-[0_1px_3px_color-mix(in_srgb,var(--color-fg)_8%,transparent)] shadow-lg shape share shared sharing shiki ship shipped ships short shortcut should show shown shrink-0 sidebar sidebar- sidebar-toggle-island sidebar-tree-island signal similarity single singular site-search site-tree-nav-island sitemap- sites size skill skills skipping skips slash slug sm:border sm:border-muted sm:flex-row sm:grid-cols-2 sm:h-auto sm:items-center sm:justify-between sm:max-h-[80vh] sm:max-w-[52rem] sm:mx-auto sm:my-[10vh] sm:rounded-lg small smooth snapshot snapshots so soft soft-nav solid some somehow source sources space-y-vsp-2xs spacing span spans spec specifier specifiers splitter square sr-only src stale start state state:state- status stay staying sticky still stop stored stray string strings strip stripe stroke-linecap stroke-linejoin stroke-width strong stronger style style-attribute styled styles stylesheet sub subagents subsequent success successful summary sup surface surfaces survives svg swap swapped swaps synchronous synchronously syntactically syntect t tab tab-item tab-panel tabindex table tablist tabpanel tabs tabs-container tabs-content tabs-nav tag tag- tag-item- tags tags:audit take tbody td temp-element template temporary temporary-element terminal terms test-results tested text text-accent text-bg text-body text-caption text-center text-chat-assistant-text text-chat-user-text text-code-fg text-danger text-decoration text-display text-fg text-heading text-info text-left text-micro text-muted text-muted/50 text-right text-small text-title text-warning text/plain textarea tfoot th that the thead their them theme theme-color theme-toggle theme/token then there these they this through throw tighten time tip title to toc toggle toggle-ai-chat toggle-design-token-panel toggles token tokens tolerates too toolbar top-0 top-[3.5rem] top-full top-level total touches tp tr tracked tracking-wider trade-off transition transition-[background,color,border-color] transition-[left,color] transition-colors transition-transform translate-x-0 translations transparent treats tree tree-child- tree-item- tree-top- trigger trigger:ai-chat trigger:design-token-panel triggers true truncate truncated try turn twitter:card twitter:creator twitter:description twitter:image twitter:site twitter:title two type typography u ul unavailable unchanged undefined under underline underlines understand unit-tested unknown unmaintained unobserve unreadable unrelated unreleased unset up uppercase usage use used user uses utf-8 utf8 utilities utility v v1 v2 val valid value value-reader values var variable variant verbatim version version- version-menu version-switcher vertical via video viewport virtual:zudo-doc-chrome-bindings virtual:zudo-doc-route-context visible vitesse-dark vocabulary w w-1/2 w-[0.5rem] w-[0.625rem] w-[0.875rem] w-[1.125rem] w-[1.575rem] w-[1.5rem] w-[1.75rem] w-[14px] w-[16px] w-[16rem] w-[18px] w-[1em] w-[280px] w-[2rem] w-[320px] w-[90vw] w-[var(--zd-sidebar-w)] w-dvw w-full w-icon-lg w-icon-md w-icon-sm w-icon-xs want warning was watching wbr wbr- we website weight went were what when where whereas whether which while whitespace-nowrap whitespace-pre whole wide-gamut width will with without word working worktrees would wrap wrapper wrappers written wrong wrote xl:flex xl:hidden y-scrollbar yet you your z-dropdown z-local-1 z-modal z-modal-backdrop z-sidebar z-toolbar zd-content zd-desktop-sidebar-toggle zd-doc-content-band zd-enlarge-btn zd-enlarge-dialog zd-enlarge-dialog-close zd-enlargeable zd-html-preview-code zd-mermaid-dialog zd-mermaid-enlargeable zd-mermaid-tool-btn zd-mermaid-toolbar zd-mermaid-transform zd-mermaid-viewport zd-sidebar-content-wrapper zd-sidebar-open zfb zfb:after-swap zfb:before-preparation zod zoom zudo-doc-design-tokens/v1 zudo-doc-design-tokens/v2 zudo-doc-design-tokens/v3 zudo-doc-sidebar-visible zudo-doc-sidebar-width zudo-doc-theme zudo-doc-theme-bridge");
@@ -172,6 +172,16 @@ export interface VersionConfig {
172
172
  /** Banner text shown on versioned pages (e.g., "unmaintained", "unreleased") */
173
173
  banner?: "unmaintained" | "unreleased" | false;
174
174
  }
175
+ export interface ChangelogConfig {
176
+ /** Directory containing one MDX/MD changelog page per released version. */
177
+ sourceDir: string;
178
+ /** File to overwrite with the generated CommonMark changelog. */
179
+ outputFile: string;
180
+ /** Optional package/project label used in the generated preamble. */
181
+ packageName?: string;
182
+ /** Document heading. Defaults to "Changelog". */
183
+ title?: string;
184
+ }
175
185
  export interface MetaTagsConfig {
176
186
  /** Emit <meta name="description">. Default true. */
177
187
  description: boolean;
@@ -278,6 +288,7 @@ export interface Settings {
278
288
  tagGovernance: TagGovernanceMode;
279
289
  tagVocabulary: boolean;
280
290
  llmsTxt: boolean;
291
+ changelogs?: ChangelogConfig[] | false;
281
292
  math: boolean;
282
293
  cjkFriendly: boolean;
283
294
  onBrokenMarkdownLinks: "warn" | "error" | "ignore";
@@ -6,7 +6,50 @@
6
6
  * spacing, font, size) so an AI assistant can consume or emit a whole
7
7
  * design-token tweak in one round-trip.
8
8
  *
9
- * Format: `$schema = "zudo-doc-design-tokens/v1"`.
9
+ * Format: `$schema = "zudo-doc-design-tokens/v3"`.
10
+ *
11
+ * v3 color slice — ramp-native, minimized (Color Ramp Restructure,
12
+ * zudolab/zudo-doc#2584 / #2591; minimized to 5/3 in #2602)
13
+ * -----------------------------------------------------------------------------------
14
+ * The color block is the ramp-native `ColorScheme` from `color-scheme-utils.ts`:
15
+ * - `ramps` — the shared Tier-1 source of truth (`base[5]`, `accent[3]`,
16
+ * `state{danger,success,warning,info}`), emitted verbatim as OKLCH strings.
17
+ * - `map` — the per-mode Tier-2 wiring (`bg`/`fg`/`selectionBg`/`selectionFg`
18
+ * + 23 `semantic` roles), each a `RampRef` (`{base:n}` / `{accent:n}` /
19
+ * `{state:role}` / a literal OKLCH string).
20
+ *
21
+ * The legacy v1 color slice (`palette: string[16]`, numeric `base`, `cursor`,
22
+ * `semanticMappings`) is gone. Both `ramps` and `map` are plain JSON data, so
23
+ * the color block is essentially a serialized `ColorScheme`.
24
+ *
25
+ * v1 → v3 migration (RESET, not remap)
26
+ * ------------------------------------
27
+ * A persisted v1 payload (detected by `$schema === "…/v1"`, a `palette` array,
28
+ * or a numeric `base` block) has NO faithful mapping to the new model: the old
29
+ * 16-slot ghostty palette + numeric semantic indices do not correspond to the
30
+ * 5-base / 3-accent / 4-state ramps + `RampRef` wiring. Any remap would invent
31
+ * colors and mislead the user, so `deserialize` RESETS the color slice to the
32
+ * caller-supplied baseline (the current default scheme) and emits a
33
+ * `console.warn` + a `warnings[]` entry — no throw, no blank screen. The
34
+ * spacing/font/size slices are format-compatible across v1/v3 and are preserved.
35
+ *
36
+ * v2 → v3 migration (RESET, schema-label-only — zudolab/zudo-doc#2599)
37
+ * ---------------------------------------------------------------------
38
+ * `v2` was the ramp-native label BEFORE the base-12/accent-7 → base-5/accent-3
39
+ * minimize (#2602); the shape (`ramps` + `map` of `RampRef`s) never changed, only
40
+ * the ramp lengths did. That means a `v2`-labeled payload is ambiguous in a way
41
+ * `v1` never was: `parseRamps` catches a wrong-length `ramps.base`/`ramps.accent`
42
+ * array and falls back to baseline, but `parseMap`'s `RampRef` parser only
43
+ * shape-checks a numeric index (`{base:11}`) — it does NOT range-check it against
44
+ * the ramp length, because that tolerance is also relied on by legitimate
45
+ * already-5/3 round-trip exports (see the `{accent:5}`-style fixtures in the test
46
+ * file). So an out-of-range ref alone can't tell a genuinely-stale pre-5/3 export
47
+ * apart from an intentionally-tolerated current-shape ref — both look identical
48
+ * once parsed. Rather than guess from ref values, `v2` is retired as a whole:
49
+ * ANY payload still carrying the `v2` label (regardless of whether its arrays
50
+ * happen to already be 5/3-shaped) is treated as legacy and RESET to baseline,
51
+ * exactly like v1. Only payloads relabeled `v3` are trusted to resolve cleanly
52
+ * against the current ramp lengths.
10
53
  *
11
54
  * Diff-only by default
12
55
  * --------------------
@@ -14,7 +57,11 @@
14
57
  * the provided `colorDefaults` (for the color block) and the manifest defaults
15
58
  * (for spacing / font / size). Pass `includeDefaults: true` to dump the full
16
59
  * state instead. The whole-category keys (`color`, `spacing`, `font`, `size`)
17
- * are omitted entirely when nothing in them differs.
60
+ * are omitted entirely when nothing in them differs. For the color block the
61
+ * `ramps` and `map` sub-blocks are each emitted whole (not per-stop / per-role
62
+ * diffed) when they differ from the baseline — the ramp-native shape has no
63
+ * stable per-slot index to diff against, and a whole-block emit round-trips
64
+ * cleanly against the same baseline.
18
65
  *
19
66
  * Spacing / font / size keys use CSS variable names (`"--spacing-hsp-md"`) —
20
67
  * the external schema — rather than the internal token id (`"hsp-md"`). This
@@ -42,23 +89,15 @@ interface TokenDef {
42
89
  /** Read-only tokens are displayed but not editable. */
43
90
  readonly?: true;
44
91
  }
45
- import { type ColorTweakState, type TweakState } from "./design-token-types.js";
46
- export declare const DESIGN_TOKEN_SCHEMA: "zudo-doc-design-tokens/v1";
47
- /** External JSON value for a base-color / semantic-color entry. */
48
- type ColorSlotValue = number | "bg" | "fg";
49
- export interface DesignTokenJsonColorBase {
50
- bg?: number;
51
- fg?: number;
52
- cursor?: number;
53
- /** Dashed keys mirror the external docs; they are quoted in source. */
54
- "sel-bg"?: number;
55
- "sel-fg"?: number;
56
- }
92
+ import { type TweakState } from "./design-token-types.js";
93
+ import { type ColorScheme, type ModeMap, type Ramps } from "../color-scheme-utils.js";
94
+ export declare const DESIGN_TOKEN_SCHEMA: "zudo-doc-design-tokens/v3";
95
+ /** External JSON color block a (possibly diff-only) serialized `ColorScheme`.
96
+ * Both sub-blocks are optional: in diff-only output an unchanged `ramps` or
97
+ * `map` is omitted and filled from the baseline on deserialize. */
57
98
  export interface DesignTokenJsonColor {
58
- palette?: string[];
59
- base?: DesignTokenJsonColorBase;
60
- /** Palette-index (or "bg"/"fg") mappings, same keys as `SEMANTIC_DEFAULTS`. */
61
- semantic?: Record<string, ColorSlotValue>;
99
+ ramps?: Ramps;
100
+ map?: ModeMap;
62
101
  }
63
102
  /** External token map keyed by CSS var name. */
64
103
  export type DesignTokenJsonOverrides = Record<string, string>;
@@ -85,14 +124,14 @@ export interface SerializeOptions {
85
124
  /** Token manifest (spacing / font / size arrays) used to compute
86
125
  * diff-only output and resolve CSS-var names. Required. */
87
126
  manifest: DesignTokenManifest;
88
- /** When true, dump full state (all palette entries, all token manifest
127
+ /** When true, dump full state (whole `ramps` + `map`, all token manifest
89
128
  * defaults merged in). Default: diff-only. */
90
129
  includeDefaults?: boolean;
91
- /** Color baseline to diff against — typically the current scheme's initial
92
- * state. Required for meaningful color-diff output; callers that don't have
93
- * it available (e.g. tests without DOM) can omit it and we'll treat the
94
- * whole color block as changed. */
95
- colorDefaults?: ColorTweakState;
130
+ /** Color baseline to diff against — typically the active scheme's initial
131
+ * `ColorScheme`. Required for meaningful color-diff output; callers that
132
+ * don't have it available (e.g. tests without DOM) can omit it and we'll
133
+ * treat the whole color block as changed. */
134
+ colorDefaults?: ColorScheme;
96
135
  /** Override the `exportedAt` stamp (test-only). */
97
136
  now?: () => Date;
98
137
  }
@@ -102,7 +141,7 @@ export interface DeserializeResult {
102
141
  /** CSS var names present in the payload that don't match any known token. */
103
142
  unknownTokens: string[];
104
143
  /** Human-readable errors that did not prevent a state from being produced
105
- * (e.g. "semantic mapping dropped because value isn't a number"). */
144
+ * (e.g. "v1 payload detected; color reset to default"). */
106
145
  warnings: string[];
107
146
  }
108
147
  export interface DeserializeOptions {
@@ -110,12 +149,13 @@ export interface DeserializeOptions {
110
149
  * names back to internal token ids. Required. */
111
150
  manifest: DesignTokenManifest;
112
151
  /** Color baseline used to fill in fields absent from the payload (diff-only
113
- * exports are missing most fields by design). Typically the current
114
- * scheme's initial state. */
115
- colorDefaults?: ColorTweakState;
152
+ * exports are missing most fields by design) and as the reset target for a
153
+ * v1 migration. Typically the active scheme's initial `ColorScheme`. */
154
+ colorDefaults?: ColorScheme;
116
155
  }
117
- /** Thrown when the payload is not a v1 schema object. The error `.reason`
118
- * helps the UI render a precise inline message. */
156
+ /** Thrown when the payload is not a recognized schema object. The error
157
+ * `.reason` helps the UI render a precise inline message. A v1 payload is NOT
158
+ * thrown for — it is migrated (see `deserialize`). */
119
159
  export declare class DesignTokenSchemaError extends Error {
120
160
  readonly reason: "not-object" | "schema-missing" | "schema-mismatch";
121
161
  readonly actualSchema?: unknown;
@@ -131,9 +171,10 @@ export declare function serialize(state: TweakState, opts: SerializeOptions): De
131
171
  /**
132
172
  * Parse a design-token JSON document and lift it back into a tweak state.
133
173
  *
134
- * Throws `DesignTokenSchemaError` on schema mismatch / non-object input. Any
135
- * CSS var name that doesn't match a known manifest entry is collected into
136
- * `unknownTokens` (the caller can surface these as a warning).
174
+ * Throws `DesignTokenSchemaError` on schema mismatch / non-object input. A v1
175
+ * (palette-based) payload is NOT thrown for its color slice is reset to the
176
+ * baseline default (see the v1→v2 migration note at the top). Any CSS var name
177
+ * that doesn't match a known manifest entry is collected into `unknownTokens`.
137
178
  *
138
179
  * Missing fields fall back to `opts.colorDefaults` (or, absent that, a
139
180
  * minimal neutral default) so the result is always a valid `TweakState`.