Skip to content

fix(packages/ui,packages/cli): fix FileTree build failure and add --ref to diff#58

Merged
zrosenbauer merged 6 commits intomainfrom
fix/filetree-and-diff-ref
Mar 23, 2026
Merged

fix(packages/ui,packages/cli): fix FileTree build failure and add --ref to diff#58
zrosenbauer merged 6 commits intomainfrom
fix/filetree-and-diff-ref

Conversation

@zrosenbauer
Copy link
Member

@zrosenbauer zrosenbauer commented Mar 23, 2026

Summary

  • Bug 1: zpress build fails because rspress-plugin-file-tree@1.0.4 shipped without its dist/ directory. Pin to 1.0.3 and copy FileTree component files into @zpress/ui/dist/components/ so Rspress webpack resolves them at build time.
  • Bug 2: zpress diff uses git status which always returns empty on clean CI checkouts (e.g. Vercel). Add --ref option that uses git diff --name-only <ref> HEAD instead, with exit code 1 when changes are detected (Vercel ignoreCommand convention).
  • Upgrades all dependencies to latest (except mermaid, pinned to v10).

Changes

  • packages/ui/package.json — pin rspress-plugin-file-tree to 1.0.3, upgrade deps
  • packages/ui/rslib.config.ts — copy FileTree component files from plugin into dist
  • packages/cli/src/commands/diff.ts — add --ref option with git diff and exit code semantics
  • pnpm-workspace.yaml — catalog version bumps (typescript, vitest, tsgo)
  • Two changesets: @zpress/ui patch, @zpress/cli minor

Test plan

  • pnpm build passes (verifies FileTree files are copied)
  • npm pack --dry-run on @zpress/ui shows dist/components/FileTree/ files
  • zpress diff --ref HEAD^ detects changes and exits 1
  • zpress diff --ref HEAD with no changes exits 0
  • zpress diff (no --ref) still works as before with git status

Summary by CodeRabbit

  • New Features

    • Added a --ref option to the diff command for commit-to-commit comparisons.
    • Added a verbose flag to the build command for verbose build checks.
  • Bug Fixes

    • Restored the missing FileTree UI component by bundling a compatible plugin release.
  • Chores

    • Added changeset entries and bumped several dependency versions and build/tooling configs; updated the UI build to include copied plugin components.

…ef to diff

Bug 1: Pin rspress-plugin-file-tree to 1.0.3 (1.0.4 shipped without dist/)
and copy its component files into @zpress/ui dist so Rspress webpack can
resolve them at build time.

Bug 2: Add --ref option to zpress diff that uses git diff instead of
git status, enabling use as a Vercel ignoreCommand. When --ref is set
and changes are detected, exits 1 to signal "proceed with build".

Also upgrades all dependencies to latest (except mermaid, pinned to v10).

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

vercel bot commented Mar 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
oss-zpress Ready Ready Preview, Comment Mar 23, 2026 6:02pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Mar 23, 2026

🦋 Changeset detected

Latest commit: feb37be

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

This PR includes changesets to release 3 packages
Name Type
@zpress/cli Minor
@zpress/ui 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 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a --ref option to zpress diff for commit-to-commit comparisons, pins and copies rspress-plugin-file-tree components into the @zpress/ui build, adds a --verbose flag to zpress build and forwards it to the build check, and updates several dependency versions across the monorepo and workspace configs.

Changes

Cohort / File(s) Summary
Changesets
​.changeset/fix-cli-diff-ref.md, ​.changeset/fix-ui-filetree.md
Two new changeset entries: minor bump for @zpress/cli (adds --ref) and patch bump for @zpress/ui (FileTree packaging fix).
CLI — diff command
packages/cli/src/commands/diff.ts
Added optional --ref option, new gitDiffFiles helper using git diff --name-only <ref> HEAD, conditional changed-file detection, adjusted non-pretty output path, and exit behavior when --ref is provided.
CLI — build/check
packages/cli/src/commands/build.ts, packages/cli/src/lib/check.ts
Added --verbose option to build command; threaded verbose into runBuildCheck. RunBuildCheckParams accepts verbose? and a new verbose execution path (runBuildCheckVerbose) was added.
UI build & packaging
packages/ui/rslib.config.ts, packages/ui/package.json
Added output.copy rule to include rspress-plugin-file-tree prebuilt dist/components into the UI package; pinned the plugin version for packaging consistency.
Dependency bumps
package.json, packages/cli/package.json, packages/core/package.json, packages/ui/package.json
Bumped: @iconify-json/simple-icons -> ^1.2.75, get-port -> ^7.2.0, liquidjs -> ^10.25.1; rspress-plugin-file-tree pinned to 1.0.3.
Workspace metadata
pnpm-workspace.yaml
Updated catalog constraints: exact dev build for @typescript/native-preview, typescript -> ^6.0.2, vitest -> ^4.1.1.
Lint overrides
.oxlintrc.json
Disabled prefer-destructuring for **/MermaidRenderer.tsx in addition to existing unicorn/filename-case override.

Sequence Diagram(s)

sequenceDiagram
  participant User as User/Invoker
  participant CLI as zpress CLI
  participant Git as Git
  participant Node as Node Process

  rect rgba(100,150,240,0.5)
  User->>CLI: run `zpress diff --ref <ref>` or `zpress diff`
  end

  CLI->>Git: if --ref -> `git diff --name-only <ref> HEAD` \n else -> `git status --short`
  Git-->>CLI: stdout (list of changed files or empty)
  CLI->>CLI: filter files by configured directories
  alt changes found
    CLI->>User: print changed files (pretty or space-separated)
    CLI->>Node: if --ref -> process.exit(1)
  else no changes
    CLI->>User: print "no changes"
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through diffs and chased a ref,
I copied FileTree so components stay deft,
Verbose on build, I nudged the check loud,
I listed changed files and gave Node a bow,
A tiny rabbit cheer for tidy changes — hop proud.

🚥 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 title clearly and concisely summarizes the two main changes in the PR: fixing a FileTree build failure in @zpress/ui and adding a --ref option to the diff command in @zpress/cli.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/filetree-and-diff-ref

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

Co-Authored-By: Claude <noreply@anthropic.com>
Replace forbidden ternary expression with ts-pattern match() to select
between gitDiffFiles and gitChangedFiles. Also disable prefer-destructuring
lint rule for raw-copied MermaidRenderer component.

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: 1

🧹 Nitpick comments (1)
packages/cli/src/commands/diff.ts (1)

315-318: Consider sharing file-list parsing logic between git helpers.

gitChangedFiles and gitDiffFiles both split/filter lines; extracting a small shared parser would reduce drift risk.

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

In `@packages/cli/src/commands/diff.ts` around lines 315 - 318, gitChangedFiles
and gitDiffFiles both parse git output by splitting on '\n' and filtering empty
lines; extract this into a small shared helper (e.g., parseGitOutputLines or
parseFileList) and use it in both functions to avoid duplication and drift.
Update the implementations of gitChangedFiles and gitDiffFiles to call the new
helper instead of repeating .split('\n').filter(...) and ensure the helper
returns the same array shape currently returned so the callers' return tuple
([null, files]) behavior remains unchanged.
🤖 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/diff.ts`:
- Around line 85-87: The ternary used to assign [gitErr, changed] causes an
ESLint "no-ternary" failure; replace it with an if/else assignment: declare let
gitErr, changed; then if (ref) call gitDiffFiles({ repoRoot: paths.repoRoot,
dirs, ref }) and assign its result to [gitErr, changed], else call
gitChangedFiles({ repoRoot: paths.repoRoot, dirs }) and assign to [gitErr,
changed]; keep the same variable names (gitErr, changed) and same call sites
(gitDiffFiles, gitChangedFiles) so behavior is unchanged.

---

Nitpick comments:
In `@packages/cli/src/commands/diff.ts`:
- Around line 315-318: gitChangedFiles and gitDiffFiles both parse git output by
splitting on '\n' and filtering empty lines; extract this into a small shared
helper (e.g., parseGitOutputLines or parseFileList) and use it in both functions
to avoid duplication and drift. Update the implementations of gitChangedFiles
and gitDiffFiles to call the new helper instead of repeating
.split('\n').filter(...) and ensure the helper returns the same array shape
currently returned so the callers' return tuple ([null, files]) behavior remains
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9796fa35-200b-45ac-aea8-d427543a6a9a

📥 Commits

Reviewing files that changed from the base of the PR and between e138bda and e455efd.

📒 Files selected for processing (1)
  • packages/cli/src/commands/diff.ts

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.

🧹 Nitpick comments (1)
packages/cli/src/commands/diff.ts (1)

310-314: Consider protecting against refs that look like git options.

If a user passes a ref starting with - (e.g., a branch named -feature or accidentally --help), git will interpret it as an option since it appears before the -- delimiter. While rare and low-severity (the user controls their own input), this could cause unexpected behavior.

🛡️ Optional: prefix ambiguous refs
 function gitDiffFiles(params: {
   readonly repoRoot: string
   readonly dirs: readonly string[]
   readonly ref: string
 }): Result<readonly string[]> {
+  // Prefix refs starting with '-' to prevent git option interpretation
+  const safeRef = params.ref.startsWith('-') ? `refs/heads/${params.ref}` : params.ref
   const [err, output] = execSilent({
     file: 'git',
-    args: ['diff', '--name-only', params.ref, 'HEAD', '--', ...params.dirs],
+    args: ['diff', '--name-only', safeRef, 'HEAD', '--', ...params.dirs],
     cwd: params.repoRoot,
   })

Alternatively, validate and reject refs starting with - at the option parsing level with a zod refinement.

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

In `@packages/cli/src/commands/diff.ts` around lines 310 - 314, The git ref passed
in params.ref can start with '-' and be misinterpreted as a git option; before
calling execSilent (the call building args ['diff','--name-only', params.ref,
'HEAD','--', ...params.dirs]), validate params.ref and reject or normalize any
ref that begins with '-' (e.g., throw/return a clear error asking for an
explicit ref like refs/heads/<name> or require a non-leading-dash ref), or add a
zod refinement at input parsing to enforce this; update the check near the
execSilent invocation in diff.ts so the args array is never constructed with an
ambiguous params.ref.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/cli/src/commands/diff.ts`:
- Around line 310-314: The git ref passed in params.ref can start with '-' and
be misinterpreted as a git option; before calling execSilent (the call building
args ['diff','--name-only', params.ref, 'HEAD','--', ...params.dirs]), validate
params.ref and reject or normalize any ref that begins with '-' (e.g.,
throw/return a clear error asking for an explicit ref like refs/heads/<name> or
require a non-leading-dash ref), or add a zod refinement at input parsing to
enforce this; update the check near the execSilent invocation in diff.ts so the
args array is never constructed with an ambiguous params.ref.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74ace88d-3cfa-4460-ad2b-8974f5fabcfc

📥 Commits

Reviewing files that changed from the base of the PR and between e455efd and e56f85c.

📒 Files selected for processing (2)
  • .oxlintrc.json
  • packages/cli/src/commands/diff.ts
✅ Files skipped from review due to trivial changes (1)
  • .oxlintrc.json

When --verbose is passed, the build check skips output capture so
Rspress/Rspack errors are printed directly to stdout/stderr. This
makes it easier to diagnose build failures on CI.

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.

🧹 Nitpick comments (1)
packages/cli/src/lib/check.ts (1)

86-96: Consider updating JSDoc to mention verbose behavior.

The JSDoc documents the output-capture behavior but doesn't mention that when verbose is true, the capture is skipped and deadlink parsing won't occur. This is a minor documentation improvement.

📝 Suggested JSDoc update
 /**
  * Run a silent Rspress build to detect deadlinks.
  *
  * Rspress's `remarkLink` plugin checks internal links during build. In
  * production mode it logs colored error messages per file via `logger.error()`
  * then throws `Error("Dead link found")`. We capture stderr to parse the
  * diagnostics and present them in our own clean format.
  *
+ * When `verbose` is true, output capture is skipped and Rspress/Rspack
+ * writes directly to stdout/stderr. Deadlink parsing is not performed in
+ * this mode — the result will be `passed` or a generic `error`.
+ *
  * `@param` params - Config and paths for the build
  * `@returns` A `BuildCheckResult` with pass/fail status and any deadlinks found
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/lib/check.ts` around lines 86 - 96, Update the JSDoc for the
function that performs the silent Rspress build (the one returning
BuildCheckResult and described as "Run a silent Rspress build to detect
deadlinks") to explicitly state that when the verbose parameter is true the
stderr/stdout capture is skipped and deadlink parsing is not performed; mention
the verbose flag behavior and its effect on diagnostics so callers know parsing
only occurs when verbose is false.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/cli/src/lib/check.ts`:
- Around line 86-96: Update the JSDoc for the function that performs the silent
Rspress build (the one returning BuildCheckResult and described as "Run a silent
Rspress build to detect deadlinks") to explicitly state that when the verbose
parameter is true the stderr/stdout capture is skipped and deadlink parsing is
not performed; mention the verbose flag behavior and its effect on diagnostics
so callers know parsing only occurs when verbose is false.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 38dccd2c-899f-4f8a-aa27-eb9016531630

📥 Commits

Reviewing files that changed from the base of the PR and between e56f85c and 1cb5d62.

📒 Files selected for processing (2)
  • packages/cli/src/commands/build.ts
  • packages/cli/src/lib/check.ts

The 1.0.4 package does ship dist/ — the earlier missing files were from
a stale pnpm store. The copy rule in rslib.config.ts is the actual fix.

Co-Authored-By: Claude <noreply@anthropic.com>
Copy rspress-plugin-file-tree chunk files (0~*.js) to dist root so
FileTree.js relative imports resolve correctly. Exclude index.* and
components/** to avoid overwriting our own build output.

Co-Authored-By: Claude <noreply@anthropic.com>
@zrosenbauer zrosenbauer merged commit 56862d1 into main Mar 23, 2026
5 checks passed
@zrosenbauer zrosenbauer deleted the fix/filetree-and-diff-ref branch March 23, 2026 18:04
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