From 86b58234d3f879ebc76692c4befa0280f70a4551 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:20:25 -0400 Subject: [PATCH 01/11] feat(packages/config): add root property to Section type and schema Co-Authored-By: Claude --- packages/config/src/schema.ts | 1 + packages/config/src/types.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/config/src/schema.ts b/packages/config/src/schema.ts index 84eba2d..10a678c 100644 --- a/packages/config/src/schema.ts +++ b/packages/config/src/schema.ts @@ -116,6 +116,7 @@ const entrySchema: z.ZodType
= z.lazy(() => icon: iconConfigSchema.optional(), card: cardConfigSchema.optional(), standalone: z.boolean().optional(), + root: z.boolean().optional(), }) .strict() ) diff --git a/packages/config/src/types.ts b/packages/config/src/types.ts index cb69954..aef2a4e 100644 --- a/packages/config/src/types.ts +++ b/packages/config/src/types.ts @@ -264,6 +264,7 @@ export interface Section { readonly icon?: IconConfig readonly card?: CardConfig readonly standalone?: boolean + readonly root?: boolean } /** From 088633649d5182f92020cd293234db2f22f1b477 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:20:40 -0400 Subject: [PATCH 02/11] feat(packages/core): propagate root property to ResolvedEntry Co-Authored-By: Claude --- packages/core/src/sync/resolve/index.ts | 1 + packages/core/src/sync/types.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/packages/core/src/sync/resolve/index.ts b/packages/core/src/sync/resolve/index.ts index 9e0f16f..9f33b42 100644 --- a/packages/core/src/sync/resolve/index.ts +++ b/packages/core/src/sync/resolve/index.ts @@ -244,6 +244,7 @@ async function resolveNestedSection( card: section.card, landing: section.landing, standalone: section.standalone, + root: section.root, autoLink, items: sorted, page: sectionPage, diff --git a/packages/core/src/sync/types.ts b/packages/core/src/sync/types.ts index bdc2154..44ff4d9 100644 --- a/packages/core/src/sync/types.ts +++ b/packages/core/src/sync/types.ts @@ -142,6 +142,12 @@ export interface ResolvedEntry { * When true, this section gets its own sidebar namespace keyed by `link`. */ readonly standalone?: boolean + /** + * When true, child sections are promoted to top-level sidebar items + * and the parent title is hidden from the sidebar hierarchy. + * Implies standalone scope isolation. + */ + readonly root?: boolean /** * When true, `link` was auto-derived from `path` or children's common prefix * rather than explicitly set in the config. From e451706d0f02ced7d3199fbfd79b0a9f23627a83 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:22:07 -0400 Subject: [PATCH 03/11] test(packages/core): add failing tests for buildRootMeta root section promotion Co-Authored-By: Claude --- packages/core/src/sync/sidebar/meta.test.ts | 70 +++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/packages/core/src/sync/sidebar/meta.test.ts b/packages/core/src/sync/sidebar/meta.test.ts index 7c0cd0d..18535c0 100644 --- a/packages/core/src/sync/sidebar/meta.test.ts +++ b/packages/core/src/sync/sidebar/meta.test.ts @@ -77,6 +77,36 @@ const packagesRoot: ResolvedEntry = { ], } +const referenceRoot: ResolvedEntry = { + title: 'Reference', + link: '/references', + root: true, + items: [ + { + title: 'API', + link: '/references/api', + items: [ + { + title: 'Auth', + link: '/references/api/auth', + page: { outputPath: 'references/api/auth.md', frontmatter: {} }, + }, + ], + }, + { + title: 'CLI', + link: '/references/cli', + items: [ + { + title: 'Commands', + link: '/references/cli/commands', + page: { outputPath: 'references/cli/commands.md', frontmatter: {} }, + }, + ], + }, + ], +} + // --------------------------------------------------------------------------- // buildRootMeta // --------------------------------------------------------------------------- @@ -111,6 +141,46 @@ describe(buildRootMeta, () => { expect(result).toHaveLength(1) expect(result[0]).toMatchObject({ name: 'visible' }) }) + + it('should promote root section children to top-level meta items', () => { + const entries: readonly ResolvedEntry[] = [ + { title: 'Getting Started', link: '/getting-started', items: [] }, + referenceRoot, + ] + + const result = buildRootMeta(entries) + + expect(result).toEqual([ + { type: 'dir', name: 'getting-started', label: 'Getting Started' }, + { type: 'dir', name: 'api', label: 'API' }, + { type: 'dir', name: 'cli', label: 'CLI' }, + ]) + }) + + it('should not include root section parent as a meta item', () => { + const entries: readonly ResolvedEntry[] = [referenceRoot] + + const result = buildRootMeta(entries) + + const names = result.map((item) => ('name' in item ? item.name : null)) + expect(names).not.toContain('references') + }) + + it('should exclude hidden children from root section promotion', () => { + const rootWithHidden: ResolvedEntry = { + title: 'Reference', + link: '/references', + root: true, + items: [ + { title: 'API', link: '/references/api', items: [] }, + { title: 'Internal', link: '/references/internal', hidden: true, items: [] }, + ], + } + + const result = buildRootMeta([rootWithHidden]) + + expect(result).toEqual([{ type: 'dir', name: 'api', label: 'API' }]) + }) }) // --------------------------------------------------------------------------- From 1979bb953ee59375c5737566e87e07384ad6a6d8 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:22:25 -0400 Subject: [PATCH 04/11] feat(packages/core): promote root section children in buildRootMeta Co-Authored-By: Claude --- packages/core/src/sync/sidebar/meta.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/core/src/sync/sidebar/meta.ts b/packages/core/src/sync/sidebar/meta.ts index 7fa72eb..ddbd97a 100644 --- a/packages/core/src/sync/sidebar/meta.ts +++ b/packages/core/src/sync/sidebar/meta.ts @@ -81,6 +81,24 @@ export function buildRootMeta(entries: readonly ResolvedEntry[]): readonly MetaI return entries .filter((e) => !e.hidden) .flatMap((entry) => { + if (entry.root && entry.items) { + return entry.items + .filter((child) => !child.hidden) + .flatMap((child) => { + const name = resolveDirName(child) + if (name === null) { + return [] + } + return [ + { + type: 'dir' as const, + name, + label: child.title, + }, + ] + }) + } + const name = resolveDirName(entry) if (name === null) { return [] From cf1312f4134ebdcd2e975f3294134ebc39e89fb2 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:23:35 -0400 Subject: [PATCH 05/11] test(packages/core): add failing tests for buildMetaDirectories root section handling Co-Authored-By: Claude --- packages/core/src/sync/sidebar/meta.test.ts | 33 +++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/packages/core/src/sync/sidebar/meta.test.ts b/packages/core/src/sync/sidebar/meta.test.ts index 18535c0..d4a48d5 100644 --- a/packages/core/src/sync/sidebar/meta.test.ts +++ b/packages/core/src/sync/sidebar/meta.test.ts @@ -284,6 +284,39 @@ describe(buildMetaDirectories, () => { } }) + it('should flatten root section children without emitting parent directory group', () => { + const directories = buildMetaDirectories([referenceRoot]) + + const dirPaths = directories.map((d) => d.dirPath) + expect(dirPaths).not.toContain('references') + }) + + it('should emit subdirectories for root section children', () => { + const directories = buildMetaDirectories([referenceRoot]) + + const apiDir = directories.find((d) => d.dirPath === 'references/api') + expect(apiDir).toBeDefined() + if (apiDir) { + expect(apiDir.items).toContainEqual({ type: 'file', name: 'auth', label: 'Auth' }) + } + + const cliDir = directories.find((d) => d.dirPath === 'references/cli') + expect(cliDir).toBeDefined() + if (cliDir) { + expect(cliDir.items).toContainEqual({ type: 'file', name: 'commands', label: 'Commands' }) + } + }) + + it('should handle mix of root and non-root sections', () => { + const directories = buildMetaDirectories([packagesRoot, referenceRoot]) + + const dirPaths = directories.map((d) => d.dirPath) + expect(dirPaths).toContain('packages') + expect(dirPaths).not.toContain('references') + expect(dirPaths).toContain('references/api') + expect(dirPaths).toContain('references/cli') + }) + it('should preserve leaf-before-section order when names do not collide', () => { const mixedSection: ResolvedEntry = { title: 'Mixed', From ec043529ee5d3ed3859db5227746d3d27b88dd6a Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:24:33 -0400 Subject: [PATCH 06/11] feat(packages/core): expand root sections in buildMetaDirectories Root sections are expanded into their visible children before flattening, and the root parent directory is filtered from the output so no parent group _meta.json is emitted. Co-Authored-By: Claude --- packages/core/src/sync/sidebar/meta.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/core/src/sync/sidebar/meta.ts b/packages/core/src/sync/sidebar/meta.ts index ddbd97a..c4ee2af 100644 --- a/packages/core/src/sync/sidebar/meta.ts +++ b/packages/core/src/sync/sidebar/meta.ts @@ -126,8 +126,20 @@ export function buildRootMeta(entries: readonly ResolvedEntry[]): readonly MetaI * @returns Flat array of directories needing `_meta.json` files */ export function buildMetaDirectories(entries: readonly ResolvedEntry[]): readonly MetaDirectory[] { - const { placements } = flattenToPlacements(entries, 0) - return groupPlacementsByDir(placements) + const rootParentDirs = new Set( + entries + .filter((entry) => entry.root && entry.link) + .map((entry) => stripLeadingSlash(entry.link ?? '')) + .filter(Boolean) + ) + const expanded = entries.flatMap((entry) => { + if (entry.root && entry.items) { + return entry.items.filter((child) => !child.hidden) + } + return [entry] + }) + const { placements } = flattenToPlacements(expanded, 0) + return groupPlacementsByDir(placements).filter((dir) => !rootParentDirs.has(dir.dirPath)) } // --------------------------------------------------------------------------- From a2f0ba9d435a812834e49b481d8a8f3a91ecbb36 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:26:03 -0400 Subject: [PATCH 07/11] feat(packages/core): treat root sections as standalone in scopes and nav Co-Authored-By: Claude --- packages/core/src/sync/index.ts | 2 +- packages/core/src/sync/sidebar/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/sync/index.ts b/packages/core/src/sync/index.ts index 59610e7..b07c279 100644 --- a/packages/core/src/sync/index.ts +++ b/packages/core/src/sync/index.ts @@ -389,7 +389,7 @@ function concatPage(pages: readonly PageData[], page: PageData | undefined): Pag * @returns Array of standalone scope path strings */ function collectStandaloneScopePaths(entries: readonly ResolvedEntry[]): readonly string[] { - return entries.filter((e) => e.standalone && e.link).map((e) => e.link as string) + return entries.filter((e) => (e.standalone || e.root) && e.link).map((e) => e.link as string) } /** diff --git a/packages/core/src/sync/sidebar/index.ts b/packages/core/src/sync/sidebar/index.ts index 23ce7fa..4ca8116 100644 --- a/packages/core/src/sync/sidebar/index.ts +++ b/packages/core/src/sync/sidebar/index.ts @@ -23,8 +23,8 @@ export function generateNav( // Auto: first 3 non-standalone sections (matching home page features), // plus all standalone sections (workspace dropdowns). const visible = resolved.filter((e) => !e.hidden) - const nonStandalone = visible.filter((e) => !e.standalone).slice(0, 3) - const standalone = visible.filter((e) => e.standalone) + const nonStandalone = visible.filter((e) => !e.standalone && !e.root).slice(0, 3) + const standalone = visible.filter((e) => e.standalone || e.root) return [...nonStandalone, ...standalone] .map(buildNavEntry) @@ -127,7 +127,7 @@ function resolveLink(entry: ResolvedEntry): string | undefined { * @returns Array of nav items for dropdown, or undefined */ function resolveChildren(entry: ResolvedEntry): readonly RspressNavItem[] | undefined { - if (entry.standalone && entry.items && entry.items.length > 0) { + if ((entry.standalone || entry.root) && entry.items && entry.items.length > 0) { return entry.items .filter((child) => !child.hidden) .map( From 57b28d81b6c2d656050509d52726ba101750cff3 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:26:27 -0400 Subject: [PATCH 08/11] test(packages/core): add nav generation tests for root sections Co-Authored-By: Claude --- packages/core/src/sync/sidebar/nav.test.ts | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 packages/core/src/sync/sidebar/nav.test.ts diff --git a/packages/core/src/sync/sidebar/nav.test.ts b/packages/core/src/sync/sidebar/nav.test.ts new file mode 100644 index 0000000..3da6942 --- /dev/null +++ b/packages/core/src/sync/sidebar/nav.test.ts @@ -0,0 +1,83 @@ +import { describe, expect, it } from 'vitest' + +import type { ZpressConfig } from '../../types.ts' +import type { ResolvedEntry } from '../types.ts' +import { generateNav } from './index.ts' + +// --------------------------------------------------------------------------- +// Fixtures +// --------------------------------------------------------------------------- + +const autoConfig = { nav: 'auto' } as ZpressConfig + +// --------------------------------------------------------------------------- +// generateNav — root sections +// --------------------------------------------------------------------------- + +describe(generateNav, () => { + it('should exclude root sections from non-standalone nav items', () => { + const entries: readonly ResolvedEntry[] = [ + { title: 'Guide', link: '/guide', items: [{ title: 'Intro', link: '/guide/intro' }] }, + { + title: 'Reference', + link: '/references', + root: true, + items: [ + { title: 'API', link: '/references/api', items: [] }, + { title: 'CLI', link: '/references/cli', items: [] }, + ], + }, + ] + + const nav = generateNav(autoConfig, entries) + const texts = nav.map((item) => item.text) + + expect(texts).toContain('Guide') + expect(texts).toContain('Reference') + }) + + it('should produce dropdown children for root sections', () => { + const entries: readonly ResolvedEntry[] = [ + { + title: 'Reference', + link: '/references', + root: true, + items: [ + { title: 'API', link: '/references/api', items: [] }, + { title: 'CLI', link: '/references/cli', items: [] }, + ], + }, + ] + + const nav = generateNav(autoConfig, entries) + const refItem = nav.find((item) => item.text === 'Reference') + + expect(refItem).toBeDefined() + if (refItem && 'items' in refItem) { + const childTexts = (refItem.items as readonly { readonly text: string }[]).map((c) => c.text) + expect(childTexts).toEqual(['API', 'CLI']) + } + }) + + it('should not count root sections toward the 3 non-standalone limit', () => { + const entries: readonly ResolvedEntry[] = [ + { title: 'A', link: '/a', items: [{ title: 'A1', link: '/a/1' }] }, + { title: 'B', link: '/b', items: [{ title: 'B1', link: '/b/1' }] }, + { title: 'C', link: '/c', items: [{ title: 'C1', link: '/c/1' }] }, + { title: 'D', link: '/d', items: [{ title: 'D1', link: '/d/1' }] }, + { + title: 'Ref', + link: '/ref', + root: true, + items: [{ title: 'API', link: '/ref/api', items: [] }], + }, + ] + + const nav = generateNav(autoConfig, entries) + const texts = nav.map((item) => item.text) + + // First 3 non-standalone + root section + expect(texts).toEqual(['A', 'B', 'C', 'Ref']) + expect(texts).not.toContain('D') + }) +}) From 9b59e66558772ee9fab5a1f2f2cb8fefef004f74 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 18:28:41 -0400 Subject: [PATCH 09/11] fix(packages/core): replace ternary with filter+map in root meta test Co-Authored-By: Claude --- packages/core/src/sync/sidebar/meta.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/core/src/sync/sidebar/meta.test.ts b/packages/core/src/sync/sidebar/meta.test.ts index d4a48d5..914d0cc 100644 --- a/packages/core/src/sync/sidebar/meta.test.ts +++ b/packages/core/src/sync/sidebar/meta.test.ts @@ -162,7 +162,12 @@ describe(buildRootMeta, () => { const result = buildRootMeta(entries) - const names = result.map((item) => ('name' in item ? item.name : null)) + const names = result + .filter( + (item): item is { readonly type: string; readonly name: string; readonly label: string } => + 'name' in item + ) + .map((item) => item.name) expect(names).not.toContain('references') }) From 76a6075b5966820736f9bc7e0a71490f37981285 Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 19:11:20 -0400 Subject: [PATCH 10/11] chore(packages/config): update generated schema.json with root property Co-Authored-By: Claude --- packages/config/schemas/schema.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/config/schemas/schema.json b/packages/config/schemas/schema.json index 7995f89..4968b96 100644 --- a/packages/config/schemas/schema.json +++ b/packages/config/schemas/schema.json @@ -392,6 +392,9 @@ }, "standalone": { "type": "boolean" + }, + "root": { + "type": "boolean" } }, "required": [ From 47df7f10ec244e889a4b736b0b94a9b3724b11ea Mon Sep 17 00:00:00 2001 From: Zac Rosenbauer Date: Fri, 10 Apr 2026 19:19:16 -0400 Subject: [PATCH 11/11] feat(examples/kitchen-sink): add root section example with API and CLI references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Demonstrates `root: true` — "Reference" section promotes "API" and "CLI" as top-level sidebar items without a wrapping parent group. Co-Authored-By: Claude --- .../docs/references/api/authentication.md | 21 ++++++++++++++ .../docs/references/api/endpoints.md | 23 +++++++++++++++ .../docs/references/api/errors.md | 16 ++++++++++ .../docs/references/cli/commands.md | 29 +++++++++++++++++++ .../docs/references/cli/configuration.md | 27 +++++++++++++++++ .../docs/references/cli/installation.md | 22 ++++++++++++++ examples/kitchen-sink/zpress.config.ts | 20 +++++++++++++ 7 files changed, 158 insertions(+) create mode 100644 examples/kitchen-sink/docs/references/api/authentication.md create mode 100644 examples/kitchen-sink/docs/references/api/endpoints.md create mode 100644 examples/kitchen-sink/docs/references/api/errors.md create mode 100644 examples/kitchen-sink/docs/references/cli/commands.md create mode 100644 examples/kitchen-sink/docs/references/cli/configuration.md create mode 100644 examples/kitchen-sink/docs/references/cli/installation.md diff --git a/examples/kitchen-sink/docs/references/api/authentication.md b/examples/kitchen-sink/docs/references/api/authentication.md new file mode 100644 index 0000000..41756f7 --- /dev/null +++ b/examples/kitchen-sink/docs/references/api/authentication.md @@ -0,0 +1,21 @@ +--- +title: Authentication +--- + +# Authentication + +All API requests require a Bearer token in the `Authorization` header. + +## Obtaining a Token + +Send a `POST` request to `/auth/token` with your client credentials: + +```bash +curl -X POST https://api.acme.com/auth/token \ + -H "Content-Type: application/json" \ + -d '{"client_id": "...", "client_secret": "..."}' +``` + +## Token Refresh + +Tokens expire after 1 hour. Use the refresh token to obtain a new access token without re-authenticating. diff --git a/examples/kitchen-sink/docs/references/api/endpoints.md b/examples/kitchen-sink/docs/references/api/endpoints.md new file mode 100644 index 0000000..6364efe --- /dev/null +++ b/examples/kitchen-sink/docs/references/api/endpoints.md @@ -0,0 +1,23 @@ +--- +title: Endpoints +--- + +# Endpoints + +## Users + +| Method | Path | Description | +|--------|------|-------------| +| `GET` | `/users` | List all users | +| `GET` | `/users/:id` | Get user by ID | +| `POST` | `/users` | Create a user | +| `PATCH` | `/users/:id` | Update a user | +| `DELETE` | `/users/:id` | Delete a user | + +## Projects + +| Method | Path | Description | +|--------|------|-------------| +| `GET` | `/projects` | List all projects | +| `GET` | `/projects/:id` | Get project by ID | +| `POST` | `/projects` | Create a project | diff --git a/examples/kitchen-sink/docs/references/api/errors.md b/examples/kitchen-sink/docs/references/api/errors.md new file mode 100644 index 0000000..27eedd2 --- /dev/null +++ b/examples/kitchen-sink/docs/references/api/errors.md @@ -0,0 +1,16 @@ +--- +title: Error Codes +--- + +# Error Codes + +All errors return a JSON body with `code`, `message`, and optional `details`. + +| Code | HTTP Status | Description | +|------|-------------|-------------| +| `auth_required` | 401 | Missing or invalid authentication | +| `forbidden` | 403 | Insufficient permissions | +| `not_found` | 404 | Resource does not exist | +| `validation_error` | 422 | Request body failed validation | +| `rate_limited` | 429 | Too many requests | +| `internal_error` | 500 | Unexpected server error | diff --git a/examples/kitchen-sink/docs/references/cli/commands.md b/examples/kitchen-sink/docs/references/cli/commands.md new file mode 100644 index 0000000..82f72a5 --- /dev/null +++ b/examples/kitchen-sink/docs/references/cli/commands.md @@ -0,0 +1,29 @@ +--- +title: Commands +--- + +# Commands + +## `acme init` + +Initialize a new Acme project in the current directory. + +```bash +acme init [--template ] +``` + +## `acme deploy` + +Deploy the current project to production. + +```bash +acme deploy [--env ] [--dry-run] +``` + +## `acme status` + +Show the current deployment status. + +```bash +acme status [--json] +``` diff --git a/examples/kitchen-sink/docs/references/cli/configuration.md b/examples/kitchen-sink/docs/references/cli/configuration.md new file mode 100644 index 0000000..9e8daf9 --- /dev/null +++ b/examples/kitchen-sink/docs/references/cli/configuration.md @@ -0,0 +1,27 @@ +--- +title: Configuration +--- + +# Configuration + +The CLI reads configuration from `acme.config.ts` in the project root. + +```ts +export default { + org: 'acme', + project: 'web', + region: 'us-east-1', + deploy: { + strategy: 'rolling', + timeout: 300, + }, +} +``` + +## Environment Variables + +| Variable | Description | Default | +|----------|-------------|---------| +| `ACME_TOKEN` | API authentication token | — | +| `ACME_ORG` | Organization slug | from config | +| `ACME_LOG_LEVEL` | Log verbosity (`debug`, `info`, `warn`, `error`) | `info` | diff --git a/examples/kitchen-sink/docs/references/cli/installation.md b/examples/kitchen-sink/docs/references/cli/installation.md new file mode 100644 index 0000000..dc4bbb7 --- /dev/null +++ b/examples/kitchen-sink/docs/references/cli/installation.md @@ -0,0 +1,22 @@ +--- +title: Installation +--- + +# Installation + +Install the Acme CLI globally: + +```bash +npm install -g @acme/cli +``` + +Verify the installation: + +```bash +acme --version +``` + +## System Requirements + +- Node.js 18 or later +- macOS, Linux, or Windows (WSL) diff --git a/examples/kitchen-sink/zpress.config.ts b/examples/kitchen-sink/zpress.config.ts index 827703e..10df46b 100644 --- a/examples/kitchen-sink/zpress.config.ts +++ b/examples/kitchen-sink/zpress.config.ts @@ -141,6 +141,26 @@ export default defineConfig({ }, ], }, + { + title: 'Reference', + icon: 'pixelarticons:book-open', + path: '/references', + root: true, + items: [ + { + title: 'API', + path: '/references/api', + include: 'docs/references/api/*.md', + sort: 'alpha', + }, + { + title: 'CLI', + path: '/references/cli', + include: 'docs/references/cli/*.md', + sort: 'alpha', + }, + ], + }, ], sidebar: { above: [