fix(precommit): pin @biomejs/biome@^1 in every bun x biome invocation #407

Merged
charles merged 1 commit from fix/precommit-biome-resolution into main 2026-04-26 23:06:21 +00:00
Collaborator

Summary

Container worktrees have no node_modules/, so bun x biome … resolved the bare biome npm package — an unrelated tool that exits 0 silently without touching files. The husky pre-commit hook (bun x lint-stagedbun x biome check --write) therefore lied: every agent commit looked formatted but landed unformatted, and CI then caught the issue on the Forgejo Actions runner.

This is the chain operators were seeing — "agent commits succeed but CI fails".

Reproduction

Reproduced live inside claude-hooks-dev-default:

$ echo "const   x =1" > test.ts
$ bun x biome check --write test.ts
exit=0
$ cat test.ts
const   x =1                # untouched

After the pin:

$ bun x @biomejs/biome@^1 check --write test.ts
Checked 1 file in 1282µs. Fixed 1 file.
exit=0
$ cat test.ts
const x = 1;

Changes

Replace every bun x biome with bun x @biomejs/biome@^1 in:

  • root package.jsonqa, lint, lint:fix, fmt, fmt:check scripts + lint-staged config.
  • apps/web/package.jsonlint script.
  • justfilelint, fmt, fmt-check, lint-fix recipes.

The ^1 caret matches the existing devDependency pin (@biomejs/biome ^1.9.0).

Why pin v1 (not latest v2)

@biomejs/biome v2 is out (2.4.13) but it's a major bump with config schema changes (organizeImports.enabledassist.actions.source.organizeImports, overrides[].includeincludes, files.ignorefiles.includes with ! negation patterns) and new default lint rules. biome migrate --write rewrites the config automatically, but the new rule defaults will surface pre-existing lint failures across the repo. That's a separate PR with its own cleanup pass — keeping it out of this one so the hook fix can ship now.

Test plan

  • Reproduced the silent-no-op behaviour in claude-hooks-dev-default (see Reproduction above).
  • just lintChecked 8169 files in 3s. No fixes applied.
  • just fmt-checkChecked 8169 files in 1353ms. No fixes applied.
  • Pre-commit hook on this PR (which now uses the new pinned command) ran without diff.
  • Operator — next agent commit (in any container) should produce a real biome run; subsequent CI on that PR should not catch new format-only diffs.

🤖 Generated with Claude Code

## Summary Container worktrees have no `node_modules/`, so `bun x biome …` resolved the **bare `biome` npm package** — an unrelated tool that exits 0 silently without touching files. The husky pre-commit hook (`bun x lint-staged` → `bun x biome check --write`) therefore *lied*: every agent commit looked formatted but landed unformatted, and CI then caught the issue on the Forgejo Actions runner. This is the chain operators were seeing — *"agent commits succeed but CI fails"*. ## Reproduction Reproduced live inside `claude-hooks-dev-default`: ```sh $ echo "const x =1" > test.ts $ bun x biome check --write test.ts exit=0 $ cat test.ts const x =1 # untouched ``` After the pin: ```sh $ bun x @biomejs/biome@^1 check --write test.ts Checked 1 file in 1282µs. Fixed 1 file. exit=0 $ cat test.ts const x = 1; ``` ## Changes Replace every `bun x biome` with `bun x @biomejs/biome@^1` in: - root `package.json` — `qa`, `lint`, `lint:fix`, `fmt`, `fmt:check` scripts + `lint-staged` config. - `apps/web/package.json` — `lint` script. - `justfile` — `lint`, `fmt`, `fmt-check`, `lint-fix` recipes. The `^1` caret matches the existing devDependency pin (`@biomejs/biome ^1.9.0`). ## Why pin v1 (not latest v2) `@biomejs/biome` v2 is out (2.4.13) but it's a major bump with config schema changes (`organizeImports.enabled` → `assist.actions.source.organizeImports`, `overrides[].include` → `includes`, `files.ignore` → `files.includes` with `!` negation patterns) and new default lint rules. `biome migrate --write` rewrites the config automatically, but the new rule defaults will surface pre-existing lint failures across the repo. That's a separate PR with its own cleanup pass — keeping it out of this one so the hook fix can ship now. ## Test plan - [x] Reproduced the silent-no-op behaviour in `claude-hooks-dev-default` (see Reproduction above). - [x] `just lint` → `Checked 8169 files in 3s. No fixes applied.` - [x] `just fmt-check` → `Checked 8169 files in 1353ms. No fixes applied.` - [x] Pre-commit hook on this PR (which now uses the new pinned command) ran without diff. - [ ] **Operator** — next agent commit (in any container) should produce a real biome run; subsequent CI on that PR should not catch new format-only diffs. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(precommit): pin @biomejs/biome@^1 in every bun x biome invocation
All checks were successful
qa / qa (pull_request) Successful in 7m2s
qa / dockerfile (pull_request) Successful in 13s
3fa969b00b
Container worktrees have no `node_modules/`, so `bun x biome ...` resolved
the bare `biome` npm package — an unrelated tool that exits 0 silently
without touching files. The husky pre-commit hook (`bun x lint-staged`
→ `bun x biome check --write`) therefore lied: every commit looked
formatted but landed unformatted, and CI then caught the issue on the
Forgejo Actions runner.

Reproduced inside `claude-hooks-dev-default`:

    $ echo "const   x =1" > test.ts
    $ bun x biome check --write test.ts
    exit=0
    $ cat test.ts
    const   x =1                # untouched

After pin:

    $ bun x @biomejs/biome@^1 check --write test.ts
    Checked 1 file in 1282µs. Fixed 1 file.
    exit=0
    $ cat test.ts
    const x = 1;

Replaces `bun x biome` with `bun x @biomejs/biome@^1` in:
- root `package.json` scripts (qa, lint, lint:fix, fmt, fmt:check) and
  `lint-staged` config
- `apps/web/package.json` lint script
- `justfile` recipes (lint, fmt, fmt-check, lint-fix)

The `^1` semver caret matches the existing devDependency pin
(`@biomejs/biome ^1.9.0`); a v2 upgrade is a separate PR with its own
config migration + rule cleanup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
charles deleted branch fix/precommit-biome-resolution 2026-04-26 23:06:21 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!407
No description provided.