Skip to content

fix(ci): make biome lint/format robust to the .claude worktree path#20

Merged
stephane-segning merged 1 commit into
mainfrom
fix/biome-worktree-paths
May 29, 2026
Merged

fix(ci): make biome lint/format robust to the .claude worktree path#20
stephane-segning merged 1 commit into
mainfrom
fix/biome-worktree-paths

Conversation

@stephane-segning
Copy link
Copy Markdown
Contributor

Summary

Follow-up to #19. That PR fixed the unformatted fixture; this one fixes the root cause — the local format/lint gate was a silent no-op from a Claude Code worktree, so the regression was invisible until CI.

biome.json excludes **/.claude. Claude Code worktrees live under .claude/worktrees/<id>/, so biome … . run from a worktree resolves . to a path under .claude, self-excludes, and processes zero files while exiting 0.

Fix: the root lint / format / format:check scripts pass explicit paths (packages test-env *.json) instead of .. Biome evaluates includes relative to biome.json, so those relative paths never match the .claude exclusion. Same 62 files processed from a worktree or a clean checkout — local and CI can no longer diverge.

Verification (from a worktree)

Command Before After
pnpm lint Checked 0 files Checked 62 files, pass
pnpm format:check Checked 0 files Checked 62 files, pass

Negative test: a stray blank line in a fixture now makes pnpm format:check exit 1 (was exit 0) — the gate actually catches regressions again.

Notes

  • *.json covers the three root config files (package.json, biome.json, tsconfig.base.json); packages and test-env cover the rest. If a new top-level lintable directory is added, append it to these three scripts — documented in the updated CLAUDE.md gotcha note.
  • The !**/.claude exclusion stays in biome.json (still useful so a manual biome lint . from the main checkout doesn't descend into sibling worktrees).

🤖 Generated with Claude Code

`biome.json` excludes `**/.claude`. Claude Code worktrees live under
`.claude/worktrees/<id>/`, so a bare `biome … .` run from a worktree
self-excludes (the `.` arg resolves to a path under `.claude`) and
silently processes ZERO files, exiting 0. That's exactly how an
unformatted fixture sailed past local `pnpm format:check` and only blew
up in CI (which runs from a normal checkout).

Fix: the root lint / format / format:check scripts now pass explicit
paths (`packages test-env *.json`) instead of `.`. Biome evaluates its
`includes` patterns relative to biome.json, so those relative paths
never match the `.claude` exclusion — the scripts process the same 62
files whether run from a worktree or the main checkout.

Verified from a worktree:
- `pnpm lint`         → Checked 62 files, pass (was: 0 files)
- `pnpm format:check` → Checked 62 files, pass (was: 0 files)
- negative test: a stray blank line in a fixture now makes
  `pnpm format:check` exit 1 (previously exit 0).

CLAUDE.md gotcha note updated to document the explicit-paths convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the Biome linting and formatting scripts in package.json to target explicit paths (packages test-env *.json) instead of . to prevent Biome from self-excluding when run from a Claude Code worktree, and updates CLAUDE.md to document this behavior. The review feedback points out that the *.json glob pattern is not natively supported by Biome and will fail on Windows shells (like cmd.exe) that do not perform glob expansion. It is recommended to replace the wildcard with explicit filenames in both the package.json scripts and the CLAUDE.md documentation.

Comment thread package.json
"scripts": {
"build": "pnpm -r build",
"lint": "biome lint .",
"lint": "biome lint packages test-env *.json",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Biome does not natively support glob expansion (like *.json) in CLI arguments. On Windows environments using shells that do not perform glob expansion (such as cmd.exe), passing *.json literally to Biome will cause it to fail with an error. To ensure cross-platform compatibility, explicitly list the root JSON files instead of using a wildcard.

Suggested change
"lint": "biome lint packages test-env *.json",
"lint": "biome lint packages test-env package.json biome.json tsconfig.base.json",

Comment thread package.json
Comment on lines +16 to +17
"format": "biome format --write packages test-env *.json",
"format:check": "biome format packages test-env *.json"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Similarly, replace the *.json glob with explicit filenames to prevent failures on Windows shells (like cmd.exe) that do not perform glob expansion.

Suggested change
"format": "biome format --write packages test-env *.json",
"format:check": "biome format packages test-env *.json"
"format": "biome format --write packages test-env package.json biome.json tsconfig.base.json",
"format:check": "biome format packages test-env package.json biome.json tsconfig.base.json"

Comment thread CLAUDE.md
- **Default shell is zsh** on this laptop. `bash -c` scripts in tooling should stay POSIX-portable or be invoked under zsh explicitly.
- **`gh` auth** lives in the interactive zsh profile. If `gh` looks unauthenticated under a plain non-interactive shell, retry under `zsh -i -c '…'` — `GITHUB_TOKEN` is loaded from `.zshrc`.
- **Biome ignores `**/.claude`** in `biome.json`. The Claude Code worktree path lives under `.claude/worktrees/<id>/`, which means running `pnpm lint` from a worktree silently lints zero files. Lint per-package (`pnpm --filter <pkg> exec biome lint .`) from a worktree, or run the workspace lint from the main checkout.
- **Biome and the `.claude` worktree path.** `biome.json` excludes `**/.claude`, and Claude Code worktrees live under `.claude/worktrees/<id>/`. A bare `biome … .` therefore self-excludes (the `.` arg resolves under `.claude`) and silently processes **zero** files. To avoid that trap, the root `lint` / `format` / `format:check` scripts pass **explicit paths** (`packages test-env *.json`) instead of `.` — Biome evaluates `includes` relative to `biome.json`, so those relative paths never hit the `.claude` exclusion and the scripts work identically from a worktree or the main checkout. If you add a new top-level lintable directory, add it to those three scripts (otherwise it won't be checked).
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Update the documentation to reflect the explicit JSON filenames (package.json biome.json tsconfig.base.json) instead of the *.json glob pattern for accuracy and consistency with the updated package.json scripts.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 977d5e635e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread package.json
"scripts": {
"build": "pnpm -r build",
"lint": "biome lint .",
"lint": "biome lint packages test-env *.json",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid shell-only globs in package scripts

On Windows, pnpm scripts run under cmd.exe by default, which does not expand *.json; Biome also documents that “Glob patterns used on the command line are not interpreted by Biome” and are expanded by the shell (https://next.biomejs.dev/guides/configure-biome/#include-files-via-cli). In that environment this script passes a literal *.json path, so root JSON files are not linted and the command may fail instead of providing the intended cross-platform gate; the same pattern is used in the format scripts below.

Useful? React with 👍 / 👎.

@stephane-segning stephane-segning merged commit 92f5daf into main May 29, 2026
3 checks passed
@stephane-segning stephane-segning deleted the fix/biome-worktree-paths branch May 29, 2026 01:37
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