Skip to content

feat(packages/core,ui): auto-generate section landing pages and fix sidebar#38

Merged
zrosenbauer merged 7 commits intomainfrom
feat/docs-v1
Mar 16, 2026
Merged

feat(packages/core,ui): auto-generate section landing pages and fix sidebar#38
zrosenbauer merged 7 commits intomainfrom
feat/docs-v1

Conversation

@zrosenbauer
Copy link
Member

@zrosenbauer zrosenbauer commented Mar 15, 2026

Summary

  • Auto-generate navigable landing pages with SectionCard grids for all section groups with children
  • Fix sidebar issues: duplicate entries, groups named "Section", missing pages for auto-derived links
  • Redesign SectionCard component with compact icon+title row and optional description row
  • Remove all && chains from package.json scripts — replaced with turbo task dependencies and pnpm lifecycle hooks
  • Add per-package turbo.json for @zpress/config schema generation dependency

Changes

Core (packages/core)

  • Add autoLink flag to ResolvedEntry to distinguish explicit vs auto-derived links
  • Add deriveCommonPrefix() to auto-derive section links from children's common path prefix
  • Add resolveSectionTitle() shared helper to derive group names from prefix segments
  • Fix promoteOverviewChild to skip entries with auto-derived links (preserves explicitly configured pages)
  • Fix duplicate sidebar landing entries when first child link matches parent

UI (packages/ui)

  • Redesign SectionCard: icon + title inline on one row, optional description on a second row
  • Update CSS: smaller icon (28px), no left padding on description

Config (packages/config)

  • Split build script: schema generation is now a separate turbo task (generate:schema)
  • Add per-package turbo.json with build depending on generate:schema

Root

  • Replace all && script chains with turbo tasks and pnpm lifecycle hooks (predev, postversion, prerelease)
  • Add turbo tasks: //#lint, //#format, //#docs:generate, generate:schema

Test plan

  • Verify pnpm dev starts correctly (predev runs build, then turbo dev)
  • Verify pnpm check runs typecheck, lint, and format via turbo
  • Verify sidebar shows proper group names (not "Section")
  • Verify no duplicate sidebar entries for contributing section
  • Verify /documentation-framework/overview page renders
  • Verify section landing pages show SectionCard grids
  • Verify pnpm build works with config schema generation via turbo

Summary by CodeRabbit

  • New Features

    • Templates package with built-in templates and a new CLI "draft" command to scaffold docs; top-level sidebar (above/below) and hero actions surfaced in the UI.
  • Documentation

    • Added Documentation Framework (overview, types, recommended, templates, scaling), Getting Started Quick Start, many internal link updates, and new landing/section guides.
  • Configuration

    • Schema bumped to v0.2.2: adds sidebar/actions, renames nav/title fields, and removes OpenAPI config; public config/type shapes updated.
  • Tests

    • Unit tests for templates registry and rendering added.
  • Chores

    • package scripts and dev workflow simplified/updated.

zrosenbauer and others added 2 commits March 15, 2026 16:39
- Split Getting Started into Introduction (with feature cards) and Quick Start
- Rename Guides section to Concepts, update all cross-references
- Add top-level `actions` config for home page hero buttons
- Add `sidebar` config with `above`/`below` link slots (SidebarConfig, SidebarLink types)
- Remove stubbed OpenAPI config from types, schema, and sidebar plumbing
- Promote HeroConfig.actions to flat `actions` field on ZpressConfig
- Scope feature-grid padding to home page only (no horizontal padding in doc pages)
- Move Contributing from nav to sidebar.below, use explicit nav
- Add documentation-framework section, templates package, and draft command

Co-Authored-By: Claude <noreply@anthropic.com>
…bar, remove && from scripts

- Add auto-derived links from prefix/children common prefix for section groups
- Generate landing pages with SectionCard grids for all sections with children
- Fix section group names falling through to "Section" by deriving from prefix
- Fix duplicate sidebar entries when first child link matches parent
- Preserve explicitly configured pages when parent link is auto-derived
- Redesign SectionCard with compact icon+title row and optional description
- Remove all && chains from package.json scripts, use turbo tasks and pnpm lifecycle hooks
- Add per-package turbo.json for config schema generation dependency

Co-Authored-By: Claude <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Mar 15, 2026

🦋 Changeset detected

Latest commit: 375f769

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@zpress/core Minor
@zpress/ui Minor
@zpress/config Patch
@zpress/cli Patch
@zpress/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Mar 15, 2026

Warning

Rate limit exceeded

@zrosenbauer has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 10 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cead1bc9-74ed-42b7-9b9f-b6effce32ae6

📥 Commits

Reviewing files that changed from the base of the PR and between 91e7e96 and 375f769.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • examples/kitchen-sink/zpress.config.ts
  • packages/cli/src/commands/draft.ts
  • packages/config/schemas/schema.json
  • packages/config/src/index.ts
  • packages/config/src/schema.ts
  • packages/config/src/types.ts
  • packages/core/src/define-config.ts
  • packages/core/src/sync/sidebar/multi.ts
  • packages/core/src/sync/workspace.ts
  • packages/core/src/types.ts
  • packages/templates/test/built-in.test.ts
📝 Walkthrough

Walkthrough

Adds a documentation framework and templates package, a CLI draft command, config/schema v0.2.2 changes (sidebar/actions added, OpenAPI removed, nav item texttitle), centralized section title/auto-linking, sidebar UI integration, docs link migrations, and assorted UI/style tweaks.

Changes

Cohort / File(s) Summary
Docs content & link updates
docs/concepts/..., docs/getting-started/*, docs/references/*, docs/documentation-framework/*
Added Documentation Framework pages, new getting-started content, many internal links updated from /guides/*/concepts/*, plus markup/formatting tweaks.
Templates package (new)
packages/templates/*, packages/templates/src/*, packages/templates/test/*, packages/templates/package.json, packages/templates/tsconfig.json, packages/templates/rslib.config.ts, packages/templates/vitest.config.ts
New @zpress/templates package: types, built-in templates, registry API (immutable), render/toSlug utilities, defineTemplate helper, tests and build configs.
CLI: draft command
packages/cli/src/commands/draft.ts, packages/cli/src/index.ts, packages/cli/package.json
Adds draft CLI command to scaffold docs from templates; depends on @zpress/templates.
Config schema & runtime types
packages/config/schemas/schema.json, packages/config/src/schema.ts, packages/config/src/types.ts, packages/config/src/index.ts, packages/config/package.json, packages/config/turbo.json
Schema bumped to v0.2.2: added actions and sidebar, removed openapi, renamed nav item texttitle, added sidebar/hero/card schemas, stronger zod function schemas, and turbo/schema-gen config; build script simplified.
Core exports & resolver logic
packages/core/src/index.ts, packages/core/src/*, packages/core/src/sync/*, packages/core/src/sync/resolve/text.ts, packages/core/src/sync/sidebar/*, packages/core/src/sync/types.ts, packages/core/src/types.ts
Public type surface reworked (Entry/OpenAPI/WorkspaceItem/Group removed; HeroAction/SidebarConfig/SidebarLink and Section/Workspace types added); centralized resolveSectionTitle(), deriveCommonPrefix for auto-link derivation, autoLink flag added, OpenAPI sidebar removed, and buildMultiSidebar signature adjusted.
UI: sidebar integration & components
packages/ui/src/config.ts, packages/ui/src/theme/hooks/use-zpress.ts, packages/ui/src/theme/components/sidebar/*, packages/ui/src/theme/components/nav/layout.tsx
Theme now exposes sidebarAbove/sidebarBelow; new SidebarLinks component and CSS; Layout injects before/after sidebar slots to render above/below links.
UI styles & component tweaks
packages/ui/src/theme/components/*, packages/ui/src/theme/styles/overrides/*
SectionCard DOM/layout reflow, feature-grid padding changes, new sidebar links CSS, and other visual/layout adjustments.
Example & site config
examples/kitchen-sink/zpress.config.ts, zpress.config.ts
Added sidebar and actions; reorganized sections (Guides→Concepts), added Documentation Framework section; updated prefixes/links and top-level navigation.
Monorepo scripts & tooling
package.json, turbo.json, packages/config/turbo.json
New npm scripts (postversion/prerelease/release/docs:generate/predev/etc.), dev switched to turbo, check script adjusted to skip lint/format directives, and turbo tasks added for docs/schema generation.
Formatting adjustments (icons/tables)
docs/references/icons/*, docs/references/icons/technology/*
Reflowed icon tables and TechIconTable entries to more compact/inline formatting; no semantic data changes.

Sequence Diagram(s)

sequenceDiagram
    participant User as Developer
    participant CLI as zpress CLI
    participant Registry as Template Registry
    participant Render as Renderer
    participant FS as File System
    participant Logger as Console

    User->>CLI: run `zpress draft [type] [title] [out]`
    CLI->>Registry: get(templateType)
    Registry-->>CLI: Template
    CLI->>Render: render(template, { title })
    Render-->>CLI: markdown
    CLI->>FS: ensure out dir & write file
    FS-->>CLI: file written
    CLI->>Logger: log success
    Logger-->>User: success message
Loading
sequenceDiagram
    participant Browser as User Agent
    participant App as Zpress App
    participant Config as Config Parser
    participant Core as Core resolver
    participant UI as Theme builder
    participant Layout as Layout component
    participant Sidebar as SidebarLinks component

    Browser->>App: request page
    App->>Config: load zpress.config.ts
    Config-->>Core: parsed sections, sidebar, actions
    Core->>UI: build themeConfig (sidebarAbove/below)
    UI-->>Layout: themeConfig
    Layout->>Sidebar: render(sidebarAbove)
    Sidebar-->>Layout: above links markup
    Layout->>Sidebar: render(sidebarBelow)
    Sidebar-->>Layout: below links markup
    Layout-->>Browser: final page
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 I stitched templates from carroted code and thread,
Links hopped from guides to concepts instead,
Sidebars peek above and shyly sit below,
Titles now resolve where wild prefixes grow,
A hopping config — v0.2.2 — let's go! 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title directly and accurately summarizes the primary changes: auto-generation of section landing pages and sidebar fixes. It is specific, concise, and clearly communicates the main focus.
Docstring Coverage ✅ Passed Docstring coverage is 81.08% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/docs-v1
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/config/schemas/schema.json (1)

616-634: ⚠️ Potential issue | 🟠 Major

Update configuration files to use title instead of text for nav items.

The nav item field was renamed from text to title in the schema. The root zpress.config.ts (lines 9, 12–13) and examples/kitchen-sink/zpress.config.ts (lines 133–134) still use the old field name and will not match the schema. Update all text: properties to title: in these files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/config/schemas/schema.json` around lines 616 - 634, The schema
renamed nav item field from text to title; update the config objects that define
nav entries to use title instead of text — locate the nav arrays in the root
zpress.config.ts (the exported config object) and in the examples/kitchen-sink
zpress.config.ts (the kitchen-sink exported config) and replace each occurrence
of the property name "text:" with "title:" for all nav item objects (preserve
values and other fields like link/items/activeMatch).
🧹 Nitpick comments (12)
packages/config/turbo.json (1)

9-13: Consider adding tsconfig.json to build inputs.

TypeScript compilation depends on tsconfig.json. If it changes (e.g., compiler options), the build should re-run. Currently only src/**, rslib.config.ts, and package.json are tracked.

♻️ Suggested change
     "build": {
       "dependsOn": ["generate:schema", "^build"],
-      "inputs": ["src/**", "rslib.config.ts", "package.json"],
+      "inputs": ["src/**", "rslib.config.ts", "package.json", "tsconfig.json"],
       "outputs": ["dist/**"]
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/config/turbo.json` around lines 9 - 13, The "build" target's inputs
array currently lists ["src/**", "rslib.config.ts", "package.json"] but omits
the TypeScript configuration; update the "build" target (the "build" object and
its "inputs" property) to include "tsconfig.json" so changes to compiler
settings trigger a rebuild.
packages/ui/src/config.ts (1)

100-111: Consider adding readonly to nested icon object properties for type consistency.

The return type's icon object { id: string; color: string } lacks readonly modifiers, while ZpressSidebarLink in use-zpress.ts defines it as { readonly id: string; readonly color: string }. This inconsistency could cause type widening issues.

♻️ Proposed fix
 function resolveSidebarLinks(
   config: ZpressConfig,
   position: 'above' | 'below'
-): readonly { text: string; link: string; icon?: string | { id: string; color: string } }[] {
+): readonly { text: string; link: string; icon?: string | { readonly id: string; readonly color: string } }[] {
   if (config.sidebar && config.sidebar[position]) {
     return config.sidebar[position]
   }
   return []
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/config.ts` around lines 100 - 111, The return type of
resolveSidebarLinks is inconsistent with ZpressSidebarLink because the nested
icon object lacks readonly modifiers; change the function's return signature
(for the icon shape in the union) from { id: string; color: string } to {
readonly id: string; readonly color: string } so the resolved type matches
ZpressSidebarLink and avoids type widening (update the signature on
resolveSidebarLinks accordingly).
packages/templates/test/built-in.test.ts (1)

6-6: Replace .map() with .forEach() and fix describe title case.

Lines 6 and 14–35 have lint violations:

  • describe title should use lowercase (ESLint: prefer-describe-function-title)
  • .map() is used for side-effects; use .forEach() instead (ESLint: arrow-body-style)
Proposed fix
-describe('BUILT_IN_TEMPLATES', () => {
+describe('built-in templates', () => {
   it('should have an entry for every template type', () => {
     const keys = Object.keys(BUILT_IN_TEMPLATES)
     expect(keys).toEqual(expect.arrayContaining([...TEMPLATE_TYPES]))
     expect(keys.length).toBe(TEMPLATE_TYPES.length)
   })
 
   it('should have matching type field on every template', () => {
-    Object.entries(BUILT_IN_TEMPLATES).map(([key, template]) => {
-      return expect(template.type).toBe(key)
-    })
+    Object.entries(BUILT_IN_TEMPLATES).forEach(([key, template]) => expect(template.type).toBe(key))
   })
 
   it('should have non-empty label and hint on every template', () => {
-    Object.values(BUILT_IN_TEMPLATES).map((template) => {
+    Object.values(BUILT_IN_TEMPLATES).forEach((template) => {
       expect(template.label.length).toBeGreaterThan(0)
-      return expect(template.hint.length).toBeGreaterThan(0)
+      expect(template.hint.length).toBeGreaterThan(0)
     })
   })
 
   it('should include {{title}} placeholder in every template body', () => {
-    Object.values(BUILT_IN_TEMPLATES).map((template) => {
-      return expect(template.body).toContain('{{title}}')
-    })
+    Object.values(BUILT_IN_TEMPLATES).forEach((template) => expect(template.body).toContain('{{title}}'))
   })
 
   it('should have a markdown heading in every template body', () => {
-    Object.values(BUILT_IN_TEMPLATES).map((template) => {
-      return expect(template.body).toMatch(/^# /m)
-    })
+    Object.values(BUILT_IN_TEMPLATES).forEach((template) => expect(template.body).toMatch(/^# /m))
   })
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/templates/test/built-in.test.ts` at line 6, Update the test to use a
lowercase describe title and replace map calls used for side-effects with
forEach: change describe('BUILT_IN_TEMPLATES', ...) to a lowercase string (e.g.,
'built_in_templates') to satisfy prefer-describe-function-title, and in the test
body where BUILT_IN_TEMPLATES.map(...) is iterating only for side effects,
replace that .map(...) with .forEach(...) (referencing the BUILT_IN_TEMPLATES
usage and the anonymous callback currently passed to .map).
packages/ui/src/theme/components/sidebar/sidebar-links.css (1)

36-39: Add a :focus-visible state for keyboard navigation parity.

Only hover is styled right now; adding explicit focus styling improves sidebar usability.

♿ Suggested CSS addition
 .zp-sidebar-link:hover {
   color: var(--rp-c-text-1);
   background-color: var(--rp-c-bg-soft);
 }
+
+.zp-sidebar-link:focus-visible {
+  color: var(--rp-c-text-1);
+  background-color: var(--rp-c-bg-soft);
+  outline: 2px solid var(--rp-c-text-1);
+  outline-offset: 2px;
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/theme/components/sidebar/sidebar-links.css` around lines 36 -
39, Add a keyboard focus style matching the hover state for the sidebar links:
update the stylesheet to add a .zp-sidebar-link:focus-visible rule that sets the
same color and background-color as .zp-sidebar-link:hover and provides an
accessible focus indicator (e.g., outline or focus ring using a contrast-safe
variable) while removing default browser outline if you provide a visible
replacement; target the .zp-sidebar-link selector and use :focus-visible for
keyboard-only focus.
packages/ui/src/theme/components/nav/layout.tsx (1)

81-90: Prefer declarative slot composition over mutating slots.

The local object mutation at lines 82–88 violates the immutable/declarative TypeScript guideline. Use conditional spreads instead for clearer intent:

♻️ Suggested refactor
-  const sidebarSlots = (() => {
-    const slots: { beforeSidebar?: React.ReactNode; afterSidebar?: React.ReactNode } = {}
-    if (aboveItems.length > 0) {
-      slots.beforeSidebar = <SidebarLinks items={aboveItems} position="above" />
-    }
-    if (belowItems.length > 0) {
-      slots.afterSidebar = <SidebarLinks items={belowItems} position="below" />
-    }
-    return slots
-  })()
+  const sidebarSlots: { beforeSidebar?: React.ReactNode; afterSidebar?: React.ReactNode } = {
+    ...(aboveItems.length > 0
+      ? { beforeSidebar: <SidebarLinks items={aboveItems} position="above" /> }
+      : {}),
+    ...(belowItems.length > 0
+      ? { afterSidebar: <SidebarLinks items={belowItems} position="below" /> }
+      : {}),
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/theme/components/nav/layout.tsx` around lines 81 - 90, The
sidebarSlots object is built by mutating a local slots variable; replace that
imperative mutation with a declarative object expression that conditionally
includes properties using spreads or conditional property syntax: construct
sidebarSlots directly (e.g., const sidebarSlots = { ...(aboveItems.length > 0 &&
{ beforeSidebar: <SidebarLinks items={aboveItems} position="above" /> }),
...(belowItems.length > 0 && { afterSidebar: <SidebarLinks items={belowItems}
position="below" /> }) } ) so you no longer mutate slots and keep the same
behavior for SidebarLinks, aboveItems, and belowItems.
docs/documentation-framework/recommended.md (1)

159-182: Add language specifier to fenced code block.

The file structure code block is missing a language specifier. Use text or plaintext for directory trees.

Proposed fix
-```
+```text
 docs/
 ├── getting-started/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/documentation-framework/recommended.md` around lines 159 - 182, The
fenced code block showing the docs directory tree is missing a language
specifier; edit the block in recommended.md to start with ```text (or
```plaintext) instead of just ``` so the directory tree renders as plain text —
update the existing fenced block that begins with the docs/ tree to use ```text.
docs/documentation-framework/scaling.md (1)

14-21: Add language specifier to fenced code blocks for file structures.

Multiple file structure code blocks (lines 14, 47, 128, 230) are missing language specifiers. Use text or plaintext for directory trees.

Example fix for line 14
-```
+```text
 docs/
 ├── getting-started.md

Apply the same fix to lines 47, 128, and 230.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/documentation-framework/scaling.md` around lines 14 - 21, The fenced
code blocks showing directory trees (the block starting with "docs/" and the
tree lines like "├── getting-started.md" etc.) are missing a language specifier;
update each of those fenced blocks (the ones beginning with the "docs/" tree at
the instances referenced) to use a plaintext/text specifier by changing the
opening fence from ``` to ```text (or ```plaintext) for the blocks containing
the directory trees so the trees at the "docs/" snippet (and the other similar
blocks at the other positions) are rendered correctly.
packages/cli/src/commands/draft.ts (2)

11-16: Convert comment to JSDoc format for the exported command.

The comment describes the function well but should use JSDoc format for consistency with the coding guidelines.

Proposed fix
-/**
- * Scaffold a new documentation file from a template.
- *
- * Prompts for the doc type and title when not provided via args,
- * then writes the rendered template to the specified output directory.
- */
+/**
+ * Scaffold a new documentation file from a template.
+ *
+ * Prompts for the doc type and title when not provided via args,
+ * then writes the rendered template to the specified output directory.
+ *
+ * `@returns` A CLI command definition for the `draft` subcommand
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/commands/draft.ts` around lines 11 - 16, Replace the leading
plain comment with a JSDoc block for the exported command in this module:
convert the existing comment into /** ... */ JSDoc and include brief tags
describing the command (e.g., `@description` "Scaffold a new documentation file
from a template"), and add `@param` tags for the CLI arguments (doc type, title,
output directory) and an `@returns` or `@async` tag if the exported command is
async; apply this to the exported command in this file so the module-level
comment follows the project JSDoc convention.

39-43: This error-handling pattern is consistent across all CLI commands in the project. While using process.exit(1) deviates from the Result tuple guideline, it's the established convention throughout the codebase. If Result-based error handling is preferred, it should be refactored consistently across all command handlers and potentially within the @kidd-cli/core command abstraction itself.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/commands/draft.ts` around lines 39 - 43, The current handler
in draft.ts logs an error then calls process.exit(1) (at the
registry.get(selectedType) failure path using ctx.logger.error and
process.exit(1)), which conflicts with the Result-tuple guideline; replace the
immediate process.exit call with returning a Result-style error from this
command handler (i.e., return the error variant the command abstraction expects)
and propagate that change through callers (or, if you intentionally keep the
existing exit behavior, document and preserve it consistently across all CLI
handlers and update `@kidd-cli/core` to reflect that convention); ensure the
change targets the registry.get(selectedType) branch where ctx.logger.error is
invoked.
packages/ui/src/theme/components/sidebar/sidebar-links.tsx (2)

56-56: Add JSDoc to exported SidebarLinks.

The exported function is missing JSDoc, which this repo requires for public API surface.

📝 Suggested patch
+/**
+ * Render configurable sidebar links in either the above or below slot.
+ */
 export function SidebarLinks(props: SidebarLinksProps): React.ReactElement | null {

As per coding guidelines Include JSDoc comments on exported functions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/theme/components/sidebar/sidebar-links.tsx` at line 56, Add a
JSDoc block above the exported function SidebarLinks describing its purpose, the
props parameter type SidebarLinksProps, and the return type (React.ReactElement
| null); include tags like `@param` {SidebarLinksProps} props and `@returns`
{React.ReactElement | null} and a short description of what the component
renders so the public API has required documentation.

10-10: icon.color is defined but never used.

Line [10] allows { id, color }, but rendering only consumes id. Either wire color through to the icon renderer or remove it from this type to avoid misleading config.

Also applies to: 18-26, 39-43

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ui/src/theme/components/sidebar/sidebar-links.tsx` at line 10, The
declared prop type readonly icon?: string | { readonly id: string; readonly
color: string } exposes icon.color but the render path only uses icon.id; update
the implementation so the color is actually applied (e.g., pass icon.color into
the icon renderer/Icon component or inline style/class where the icon is created
inside SidebarLinks/SidebarLinkItem), or if color is not needed remove color
from the union type to keep the type accurate; ensure the change touches the
icon type declaration and the render usage where id is consumed (look for
references to icon, id, and any Icon/RenderIcon call) so types and runtime usage
stay consistent.
packages/templates/src/registry.ts (1)

9-27: Use object parameters for multi-argument helpers.

Line [9] and Line [22] use positional args with 2 parameters; this conflicts with the project TS style rule and makes call sites less self-descriptive.

♻️ Suggested refactor
-function resolveBody(base: string, override: ExtendTemplateOptions['body']): string {
+function resolveBody(params: {
+  readonly base: string
+  readonly override: ExtendTemplateOptions['body']
+}): string {
+  const { base, override } = params
   if (override === undefined) {
     return base
   }
   if (isFunction(override)) {
     return override(base)
   }
   return override
 }
@@
-function applyExtension(base: Template, options: ExtendTemplateOptions): Template {
+function applyExtension(params: {
+  readonly base: Template
+  readonly options: ExtendTemplateOptions
+}): Template {
+  const { base, options } = params
   return {
     type: base.type,
     label: options.label ?? base.label,
     hint: options.hint ?? base.hint,
-    body: resolveBody(base.body, options.body),
+    body: resolveBody({ base: base.body, override: options.body }),
   }
 }
@@
-      const extended = applyExtension(base, options)
+      const extended = applyExtension({ base, options })

As per coding guidelines Use object parameters for functions with 2+ parameters and include explicit return types.

Also applies to: 47-47

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/templates/src/registry.ts` around lines 9 - 27, resolveBody and
applyExtension use positional arguments and lack explicit return types; change
resolveBody(base: string, override: ExtendTemplateOptions['body']) to
resolveBody({ base, override }: { base: string; override:
ExtendTemplateOptions['body'] }): string and change applyExtension(base:
Template, options: ExtendTemplateOptions) to applyExtension({ base, options }: {
base: Template; options: ExtendTemplateOptions }): Template, update their call
sites to pass an object instead of positional args, and ensure you add the
explicit return types (string and Template); also update any other
multi-argument helper in this file to the same object-parameter + explicit
return type pattern.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/sync/resolve/index.ts`:
- Around line 333-371: The JSDoc/behavior mismatch in deriveCommonPrefix must be
fixed: change the early return check from links.length === 0 to links.length < 2
so the function returns undefined when fewer than two children have links (per
the doc), and replace the Array.from(...).reduce usage that mutates `common`
with a simple deterministic loop that compares segments left-to-right and
accumulates matching segments without side-effecting inside a reducer (e.g., a
for loop over index i up to `shortest` that breaks on first divergence and
pushes into `common`), keeping the final return `/${common.join('/')}` or
undefined when common is empty; reference: function deriveCommonPrefix and
variable names links, segmentArrays, shortest, common.

In `@packages/templates/test/registry.test.ts`:
- Line 18: The tests use optional chaining (e.g., template?.type) in multiple
assertions which violates OXLint; replace each use by explicitly narrowing the
value before accessing properties: assert or guard that the variable (for
example template) is defined (e.g., expect(template).toBeDefined() or if
(!template) throw) and then access template.type normally. Apply this pattern to
all flagged symbols/lines (all occurrences of template?.<prop> and similar
optional chains on the registry test variables) so property access is
non-optional and CI-compliant.

---

Outside diff comments:
In `@packages/config/schemas/schema.json`:
- Around line 616-634: The schema renamed nav item field from text to title;
update the config objects that define nav entries to use title instead of text —
locate the nav arrays in the root zpress.config.ts (the exported config object)
and in the examples/kitchen-sink zpress.config.ts (the kitchen-sink exported
config) and replace each occurrence of the property name "text:" with "title:"
for all nav item objects (preserve values and other fields like
link/items/activeMatch).

---

Nitpick comments:
In `@docs/documentation-framework/recommended.md`:
- Around line 159-182: The fenced code block showing the docs directory tree is
missing a language specifier; edit the block in recommended.md to start with
```text (or ```plaintext) instead of just ``` so the directory tree renders as
plain text — update the existing fenced block that begins with the docs/ tree to
use ```text.

In `@docs/documentation-framework/scaling.md`:
- Around line 14-21: The fenced code blocks showing directory trees (the block
starting with "docs/" and the tree lines like "├── getting-started.md" etc.) are
missing a language specifier; update each of those fenced blocks (the ones
beginning with the "docs/" tree at the instances referenced) to use a
plaintext/text specifier by changing the opening fence from ``` to ```text (or
```plaintext) for the blocks containing the directory trees so the trees at the
"docs/" snippet (and the other similar blocks at the other positions) are
rendered correctly.

In `@packages/cli/src/commands/draft.ts`:
- Around line 11-16: Replace the leading plain comment with a JSDoc block for
the exported command in this module: convert the existing comment into /** ...
*/ JSDoc and include brief tags describing the command (e.g., `@description`
"Scaffold a new documentation file from a template"), and add `@param` tags for
the CLI arguments (doc type, title, output directory) and an `@returns` or `@async`
tag if the exported command is async; apply this to the exported command in this
file so the module-level comment follows the project JSDoc convention.
- Around line 39-43: The current handler in draft.ts logs an error then calls
process.exit(1) (at the registry.get(selectedType) failure path using
ctx.logger.error and process.exit(1)), which conflicts with the Result-tuple
guideline; replace the immediate process.exit call with returning a Result-style
error from this command handler (i.e., return the error variant the command
abstraction expects) and propagate that change through callers (or, if you
intentionally keep the existing exit behavior, document and preserve it
consistently across all CLI handlers and update `@kidd-cli/core` to reflect that
convention); ensure the change targets the registry.get(selectedType) branch
where ctx.logger.error is invoked.

In `@packages/config/turbo.json`:
- Around line 9-13: The "build" target's inputs array currently lists ["src/**",
"rslib.config.ts", "package.json"] but omits the TypeScript configuration;
update the "build" target (the "build" object and its "inputs" property) to
include "tsconfig.json" so changes to compiler settings trigger a rebuild.

In `@packages/templates/src/registry.ts`:
- Around line 9-27: resolveBody and applyExtension use positional arguments and
lack explicit return types; change resolveBody(base: string, override:
ExtendTemplateOptions['body']) to resolveBody({ base, override }: { base:
string; override: ExtendTemplateOptions['body'] }): string and change
applyExtension(base: Template, options: ExtendTemplateOptions) to
applyExtension({ base, options }: { base: Template; options:
ExtendTemplateOptions }): Template, update their call sites to pass an object
instead of positional args, and ensure you add the explicit return types (string
and Template); also update any other multi-argument helper in this file to the
same object-parameter + explicit return type pattern.

In `@packages/templates/test/built-in.test.ts`:
- Line 6: Update the test to use a lowercase describe title and replace map
calls used for side-effects with forEach: change describe('BUILT_IN_TEMPLATES',
...) to a lowercase string (e.g., 'built_in_templates') to satisfy
prefer-describe-function-title, and in the test body where
BUILT_IN_TEMPLATES.map(...) is iterating only for side effects, replace that
.map(...) with .forEach(...) (referencing the BUILT_IN_TEMPLATES usage and the
anonymous callback currently passed to .map).

In `@packages/ui/src/config.ts`:
- Around line 100-111: The return type of resolveSidebarLinks is inconsistent
with ZpressSidebarLink because the nested icon object lacks readonly modifiers;
change the function's return signature (for the icon shape in the union) from {
id: string; color: string } to { readonly id: string; readonly color: string }
so the resolved type matches ZpressSidebarLink and avoids type widening (update
the signature on resolveSidebarLinks accordingly).

In `@packages/ui/src/theme/components/nav/layout.tsx`:
- Around line 81-90: The sidebarSlots object is built by mutating a local slots
variable; replace that imperative mutation with a declarative object expression
that conditionally includes properties using spreads or conditional property
syntax: construct sidebarSlots directly (e.g., const sidebarSlots = {
...(aboveItems.length > 0 && { beforeSidebar: <SidebarLinks items={aboveItems}
position="above" /> }), ...(belowItems.length > 0 && { afterSidebar:
<SidebarLinks items={belowItems} position="below" /> }) } ) so you no longer
mutate slots and keep the same behavior for SidebarLinks, aboveItems, and
belowItems.

In `@packages/ui/src/theme/components/sidebar/sidebar-links.css`:
- Around line 36-39: Add a keyboard focus style matching the hover state for the
sidebar links: update the stylesheet to add a .zp-sidebar-link:focus-visible
rule that sets the same color and background-color as .zp-sidebar-link:hover and
provides an accessible focus indicator (e.g., outline or focus ring using a
contrast-safe variable) while removing default browser outline if you provide a
visible replacement; target the .zp-sidebar-link selector and use :focus-visible
for keyboard-only focus.

In `@packages/ui/src/theme/components/sidebar/sidebar-links.tsx`:
- Line 56: Add a JSDoc block above the exported function SidebarLinks describing
its purpose, the props parameter type SidebarLinksProps, and the return type
(React.ReactElement | null); include tags like `@param` {SidebarLinksProps} props
and `@returns` {React.ReactElement | null} and a short description of what the
component renders so the public API has required documentation.
- Line 10: The declared prop type readonly icon?: string | { readonly id:
string; readonly color: string } exposes icon.color but the render path only
uses icon.id; update the implementation so the color is actually applied (e.g.,
pass icon.color into the icon renderer/Icon component or inline style/class
where the icon is created inside SidebarLinks/SidebarLinkItem), or if color is
not needed remove color from the union type to keep the type accurate; ensure
the change touches the icon type declaration and the render usage where id is
consumed (look for references to icon, id, and any Icon/RenderIcon call) so
types and runtime usage stay consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9de90737-e802-43ea-8d36-03cd2087ed24

📥 Commits

Reviewing files that changed from the base of the PR and between 7d074af and 7d3379b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (77)
  • docs/concepts/auto-discovery.md
  • docs/concepts/deployment.md
  • docs/concepts/dynamic-content.md
  • docs/concepts/frontmatter.md
  • docs/concepts/landing-pages.md
  • docs/concepts/navigation.md
  • docs/concepts/sections-and-pages.md
  • docs/concepts/themes.mdx
  • docs/concepts/workspaces.md
  • docs/documentation-framework/overview.md
  • docs/documentation-framework/recommended.md
  • docs/documentation-framework/scaling.md
  • docs/documentation-framework/templates.md
  • docs/documentation-framework/types.md
  • docs/getting-started/introduction.mdx
  • docs/getting-started/quick-start.md
  • docs/references/frontmatter.md
  • docs/references/icons/colors.mdx
  • docs/references/icons/overview.mdx
  • docs/references/icons/technology/databases.mdx
  • docs/references/icons/technology/frameworks.mdx
  • docs/references/icons/technology/infrastructure.mdx
  • docs/references/icons/technology/integrations.mdx
  • docs/references/icons/technology/languages.mdx
  • docs/references/icons/technology/overview.mdx
  • docs/references/icons/technology/tooling.mdx
  • examples/kitchen-sink/zpress.config.ts
  • package.json
  • packages/cli/package.json
  • packages/cli/src/commands/draft.ts
  • packages/cli/src/index.ts
  • packages/config/README.md
  • packages/config/package.json
  • packages/config/schemas/schema.json
  • packages/config/src/index.ts
  • packages/config/src/schema.ts
  • packages/config/src/types.ts
  • packages/config/turbo.json
  • packages/core/src/define-config.ts
  • packages/core/src/index.ts
  • packages/core/src/sync/home.ts
  • packages/core/src/sync/index.ts
  • packages/core/src/sync/resolve/index.ts
  • packages/core/src/sync/resolve/recursive.ts
  • packages/core/src/sync/resolve/text.ts
  • packages/core/src/sync/sidebar/inject.ts
  • packages/core/src/sync/sidebar/multi.ts
  • packages/core/src/sync/types.ts
  • packages/core/src/sync/workspace.ts
  • packages/core/src/types.ts
  • packages/templates/package.json
  • packages/templates/rslib.config.ts
  • packages/templates/src/built-in.ts
  • packages/templates/src/define.ts
  • packages/templates/src/index.ts
  • packages/templates/src/registry.ts
  • packages/templates/src/render.ts
  • packages/templates/src/types.ts
  • packages/templates/test/built-in.test.ts
  • packages/templates/test/define.test.ts
  • packages/templates/test/registry.test.ts
  • packages/templates/test/render.test.ts
  • packages/templates/tsconfig.json
  • packages/templates/vitest.config.ts
  • packages/ui/src/config.ts
  • packages/ui/src/theme/components/home/feature-card.css
  • packages/ui/src/theme/components/nav/layout.tsx
  • packages/ui/src/theme/components/shared/section-card.tsx
  • packages/ui/src/theme/components/sidebar/sidebar-links.css
  • packages/ui/src/theme/components/sidebar/sidebar-links.tsx
  • packages/ui/src/theme/hooks/use-zpress.ts
  • packages/ui/src/theme/styles/overrides/home.css
  • packages/ui/src/theme/styles/overrides/section-card.css
  • packages/zpress/src/config.ts
  • packages/zpress/src/index.ts
  • turbo.json
  • zpress.config.ts
💤 Files with no reviewable changes (2)
  • packages/config/README.md
  • packages/core/src/sync/workspace.ts

zrosenbauer and others added 2 commits March 15, 2026 19:15
…geset

- Fix JSDoc in deriveCommonPrefix to match implementation
- Remove all optional chaining from registry tests (OXLint violation)
- Add changeset for core/ui minor and config patch

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove array mutation in deriveCommonPrefix reduce (use immutable accumulator)
- Use match expressions instead of nested if chains in resolveSectionTitle
- Replace ternary in draft command with match expressions
- Simplify defineTemplate to use spread
- Simplify createRegistry to use Object.entries directly
- Build sidebar slots immutably with spread instead of post-creation mutation
- Use match for icon resolution and null guards in sidebar-links

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/sync/resolve/text.ts`:
- Line 56: The .otherwise(() => 'Section') fallback in resolve/text.ts
reintroduces the reserved name "Section"; change the fallback to a non-reserved
value or omit generating the label here (e.g., return undefined/null or an empty
string) so consumers can supply a proper title later; update the .otherwise(...)
call (the chain that currently returns 'Section') to return a safe sentinel (or
nothing) and ensure the caller that consumes this resolver handles the
undefined/null case appropriately.
- Around line 51-53: The lastSegment extraction should avoid using
filter(...).pop() and returning explicit undefined; replace the current matcher
block so the P.string branch returns the last non-empty path segment via
Array.prototype.findLast (e.g. .with(P.string, p =>
p.split('/').findLast(Boolean))) and keep the .otherwise branch to return
undefined only if prefix isn't a string; update the code to use lastSegment from
that matcher so it no longer triggers prefer-array-find or no-useless-undefined
lint rules.

In `@packages/templates/test/registry.test.ts`:
- Around line 13-23: The test uses TEMPLATE_TYPES.map for side-effect assertions
which triggers the useIterableCallbackReturn lint rule; change the iteration to
TEMPLATE_TYPES.forEach in the test 'should return correct template for each
type' so you iterate for side effects only, call createRegistry(), then for each
type call registry.get(type) and run the expect assertions
(expect(template).toBeDefined() and expect(template.type).toBe(type)) while
preserving the existing early-return guard when template is undefined.
- Around line 30-34: Replace direct equality boolean assertions using toBe(true)
and toBe(false) with the truthy/falsy matchers toBeTruthy() and toBeFalsy();
specifically, update test assertions that call registry.has(...) (and any other
boolean-returning calls in the same file, e.g., results of createRegistry()
lookups) so expect(registry.has('...')).toBe(true) becomes
expect(registry.has('...')).toBeTruthy() and expect(...).toBe(false) becomes
expect(...).toBeFalsy(), ensuring all occurrences in the registry.test.ts file
are changed to satisfy the vitest/prefer-to-be-truthy and
vitest/prefer-to-be-falsy rules.

In `@packages/ui/src/theme/components/nav/layout.tsx`:
- Around line 82-87: The construction using ternaries when building the sidebar
slots causes an eslint no-ternary error; replace the ternary expressions with
explicit conditional assignment: create the slots object (or the props object
used in layout rendering) then, if aboveItems.length > 0 assign
slots.beforeSidebar = <SidebarLinks items={aboveItems} position="above" /> and
if belowItems.length > 0 assign slots.afterSidebar = <SidebarLinks
items={belowItems} position="below" />; update the code paths using
beforeSidebar/afterSidebar to use this slots object instead of the
ternary-spread pattern so no ternary operator is used.

In `@packages/ui/src/theme/components/sidebar/sidebar-links.tsx`:
- Line 44: The nav element in the SidebarLinks component renders an unlabeled
navigation landmark; update the JSX in the SidebarLinks (sidebar-links.tsx) so
the <nav> includes an aria-label that distinguishes the two instances (use
props.position to generate the label, e.g. "Sidebar links above" vs "Sidebar
links below" or a similar clear string) to ensure screen readers can
disambiguate the navigation regions.
- Line 41: Add a JSDoc block above the exported function SidebarLinks describing
its purpose, input props and return type: document the SidebarLinksProps
parameter (mentioning the shape/important fields if applicable) and that it
returns a React.ReactElement or null; include tags like `@param`
{SidebarLinksProps} props and `@returns` {React.ReactElement | null} and mark it
as exported/public according to project conventions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5a4dd9f-ccfd-4ba6-8700-49cd8b8b6882

📥 Commits

Reviewing files that changed from the base of the PR and between 0d3a688 and 35ee67e.

📒 Files selected for processing (9)
  • .changeset/feat-section-landing-pages.md
  • packages/cli/src/commands/draft.ts
  • packages/core/src/sync/resolve/index.ts
  • packages/core/src/sync/resolve/text.ts
  • packages/templates/src/define.ts
  • packages/templates/src/registry.ts
  • packages/templates/test/registry.test.ts
  • packages/ui/src/theme/components/nav/layout.tsx
  • packages/ui/src/theme/components/sidebar/sidebar-links.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/cli/src/commands/draft.ts
  • packages/templates/src/registry.ts
  • packages/core/src/sync/resolve/index.ts
  • packages/templates/src/define.ts

- Replace filter(Boolean).pop() with findLast(Boolean) in resolveSectionTitle
- Remove ternaries in layout.tsx sidebar slots, use match expressions
- Replace toBe(true/false) with toBeTruthy/toBeFalsy in registry tests
- Fix map callback returns and remove forEach usage in test files
- Replace Array.from() with spread operator in registry
- Add JSDoc and aria-label to SidebarLinks component
- Remove useless undefined returns

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/templates/test/built-in.test.ts (1)

19-24: Consider removing unnecessary array wrapper.

The array literal wrapping the two expect calls is unused. This works but adds visual noise without benefit.

♻️ Optional simplification
   it('should have non-empty label and hint on every template', () => {
-    Object.values(BUILT_IN_TEMPLATES).map((template) => [
-      expect(template.label.length).toBeGreaterThan(0),
-      expect(template.hint.length).toBeGreaterThan(0),
-    ])
+    Object.values(BUILT_IN_TEMPLATES).map((template) => {
+      expect(template.label.length).toBeGreaterThan(0)
+      return expect(template.hint.length).toBeGreaterThan(0)
+    })
   })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/templates/test/built-in.test.ts` around lines 19 - 24, The test
iterates BUILT_IN_TEMPLATES but wraps the two expect() calls in an unnecessary
array literal which creates visual noise and leaves map unused; change the
iteration in the "should have non-empty label and hint on every template" test
to use Object.values(BUILT_IN_TEMPLATES).forEach and call
expect(template.label.length).toBeGreaterThan(0) and
expect(template.hint.length).toBeGreaterThan(0) directly (remove the surrounding
[ ... ] array wrapper).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/cli/src/commands/draft.ts`:
- Around line 47-50: Replace the hard process exit with a Result-tuple style
error return: instead of calling process.exit(1) in the command handler when
template is falsy, log the error with ctx.logger.error(`Unknown template type:
${selectedType}`) and return an Err-result (e.g., a tuple like [null, new
Error(`Unknown template type: ${selectedType}`)] or your codebase's Result type)
from the enclosing command function; remove the process.exit(1) so the caller
can handle the error and compose/test flows (use the existing template,
selectedType and ctx.logger symbols to locate the block).
- Around line 58-67: The current prompt validator only checks title non-empty
but not whether the slug will be usable; update the validate function used when
prompting for title to compute the slug (call toSlug(title.trim()) or similar)
and return an error if that slug is empty or only punctuation so users can't
submit titles like "!!!"; reference the validate callback and the toSlug/title
variables (and ensure toSlug is imported/in-scope) and keep the existing "Title
is required" style message or replace it with something like "Please provide a
title that generates a valid filename".
- Around line 71-72: Before calling fs.writeFile, guard against clobbering by
checking whether filePath already exists (e.g., using fs.access or fs.stat) and
fail fast or prompt instead of overwriting; update the draft command flow around
the fs.mkdir(...) and await fs.writeFile(filePath, content, 'utf8') to first
verify non-existence of filePath and throw an explicit error (or call the
existing prompt flow) if it exists, otherwise proceed to create directories and
write the file.

---

Nitpick comments:
In `@packages/templates/test/built-in.test.ts`:
- Around line 19-24: The test iterates BUILT_IN_TEMPLATES but wraps the two
expect() calls in an unnecessary array literal which creates visual noise and
leaves map unused; change the iteration in the "should have non-empty label and
hint on every template" test to use Object.values(BUILT_IN_TEMPLATES).forEach
and call expect(template.label.length).toBeGreaterThan(0) and
expect(template.hint.length).toBeGreaterThan(0) directly (remove the surrounding
[ ... ] array wrapper).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 654e90b9-44ce-4721-b7f1-a14d0e277dcd

📥 Commits

Reviewing files that changed from the base of the PR and between 35ee67e and 91e7e96.

📒 Files selected for processing (7)
  • packages/cli/src/commands/draft.ts
  • packages/core/src/sync/resolve/text.ts
  • packages/templates/src/registry.ts
  • packages/templates/test/built-in.test.ts
  • packages/templates/test/registry.test.ts
  • packages/ui/src/theme/components/nav/layout.tsx
  • packages/ui/src/theme/components/sidebar/sidebar-links.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/ui/src/theme/components/sidebar/sidebar-links.tsx
  • packages/templates/src/registry.ts
  • packages/core/src/sync/resolve/text.ts

…PI support

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant