chore(frontend): consolidate on Biome and drop oxlint/oxfmt [#10390] - #10399
Open
saltas888 wants to merge 3 commits into
Open
chore(frontend): consolidate on Biome and drop oxlint/oxfmt [#10390]#10399saltas888 wants to merge 3 commits into
saltas888 wants to merge 3 commits into
Conversation
frontend/packages/ui and frontend/packages/graph shipped oxlint + oxfmt configs that CI never ran, so both packages had gone unchecked since they were created, while frontend/app was gated by Biome. Two toolchains, one of them enforced. Biome now owns the whole frontend/ pnpm workspace. A root config at frontend/biome.jsonc holds the shared formatter, import sorting and lint rules; thin per-member configs inherit it via "extends": "//". Those per-package configs are what make each package its own Biome project -- without them noUndeclaredDependencies cannot resolve the package's own package.json and reports every import as undeclared. CI's frontend-lint job now runs a single `biome ci .` from the workspace root, covering the app and the packages together. Enforcing Biome on the previously unchecked packages reformatted 28 files and reordered Tailwind classes in 81 places. Class order inside a className is a no-op for rendering, and a token audit of the diff confirms no class was added or dropped. The two oxlint-disable directives became plain rationale comments: both rules they suppressed are off under Biome, so a biome-ignore would be an unused suppression. oxfmt is gone from the lockfile entirely (40 package entries removed). oxlint survives only as a transitive dependency of react-scan -> react-doctor; nothing we own configures or runs it. Biome is a devDependency of the workspace root so there is one entry point, `cd frontend && pnpm biome:fix`. The member-level biome scripts were removed deliberately -- invoking Biome from frontend/app silently leaves packages/* unchecked, which is how the split went unnoticed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
22 issues found across 78 files
Confidence score: 3/5
- In
frontend/biome.jsonc, thefiles.includesarrays use only negated!patterns without a leading positive**. Biome 2 docs require**first for negated patterns to match anything, so this could cause Biome to ignore the intended files, leaving code unformatted or breaking CI lint checks — add a leading**pattern. - This PR is a pure tooling/CI/docs reorganization (Biome consolidation, no product behavior) but targets
developacross many files (e.g.,.github/workflows/claude-code.yml,frontend/app/AGENTS.md,frontend/packages/ui/src/components/checkbox/checkbox.tsx). Per the base-branch policy these should land onstable; retarget or split the PR to avoid policy violations, and updatefrontend/app/README.mdwhich still references the removedbiome:fixscript.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="changelog/+frontend-biome-consolidation.housekeeping.md">
<violation number="1" location="changelog/+frontend-biome-consolidation.housekeeping.md:1">
P3: This is a pure tooling/CI/documentation change (no product code, no user-visible behavior), but the PR targets develop. Per the release-vehicle policy, repo tooling and CI changes should target stable since they cannot affect a running product and should ship before the next minor. Consider retargeting this consolidation to stable.</violation>
</file>
<file name="frontend/packages/ui/src/components/checkbox-card/checkbox-card.tsx">
<violation number="1" location="frontend/packages/ui/src/components/checkbox-card/checkbox-card.tsx:16">
P3: Per the base-branch policy, a pure tooling/CI refactor (Biome consolidation, no product behavior change) should target `stable`, not `develop`, since it cannot affect a running product. This is a low-severity note, not blocking.</violation>
</file>
<file name=".github/workflows/bug-agent-fix.md">
<violation number="1" location=".github/workflows/bug-agent-fix.md:205">
P3: This is a pure tooling/docs/CI change (frontend Biome invocation in the bug-fix workflow) and the PR targets develop. Per the repo's base-branch policy, repo tooling changes belong on stable; consider retargeting to stable so this ships outside the feature release train, or confirm the develop target is intentional.</violation>
</file>
<file name="frontend/app/AGENTS.md">
<violation number="1" location="frontend/app/AGENTS.md:17">
P3: This is a pure tooling/docs (AGENTS.md) change, which per the repo's base-branch policy should land on `stable` since it can't affect a running product. The PR targets `develop`, so move the docs (and the rest of this tooling consolidate) to `stable` to avoid shipping a versionless docs/CI change on the product release train.</violation>
</file>
<file name="frontend/packages/ui/src/components/checkbox/checkbox.tsx">
<violation number="1" location="frontend/packages/ui/src/components/checkbox/checkbox.tsx:14">
P3: This PR is a pure tooling/CI consolidation (Biome replacing oxlint/oxfmt; no product behavior change — class order is a no-op for rendering). Per the base-branch convention, changes that can't affect a running product (repo tooling, CI, docs) belong on stable, while develop is reserved for product changes on the normal release train. Consider targeting stable rather than develop. Non-blocking note.</violation>
</file>
<file name=".agents/commands/pre-ci.md">
<violation number="1" location=".agents/commands/pre-ci.md:47">
P3: This is a pure developer-tooling/docs change (repointing the Biome command in pre-ci.md), which per the release-vehicle policy belongs on stable, not develop. The PR targets develop; note that this splits the tooling migration from the release train it should ride, and lower-severity tooling/docs/CI work shipping on develop will only reach users on the next minor.</violation>
</file>
<file name=".github/workflows/claude-code.yml">
<violation number="1" location=".github/workflows/claude-code.yml:140">
P3: This PR is a pure tooling/CI/docs reorganization and targets `develop`. Per the base-branch convention, repo tooling/CI changes should target `stable` (since they cannot affect the running product) rather than ride the normal release train on `develop`; product features/fixes are what belong on `develop`. Non-blocking note only.</violation>
</file>
<file name="frontend/packages/ui/src/components/breadcrumbs/breadcrumbs.tsx">
<violation number="1" location="frontend/packages/ui/src/components/breadcrumbs/breadcrumbs.tsx:34">
P3: This is a no-op formatting change (Tailwind class reorder and trailing-comma removal) with zero impact on the running product, but the PR targets develop. Per the base-branch selection rule, changes that cannot affect a running product belong on stable, and only product changes ride the develop release train. Consider pointing this reformatting onto stable to avoid shipping a source-only churn on the normal release path.</violation>
</file>
<file name="AGENTS.md">
<violation number="1" location="AGENTS.md:97">
P3: This PR is pure repo tooling/docs/CI (migrating frontend linting to Biome) and, per the repo's base-branch convention, should target `stable` rather than `develop`, which is reserved for the normal product release train. Tooling/doc/CI changes don't affect a running product and can ship ahead of the next minor.</violation>
</file>
<file name="frontend/packages/graph/package.json">
<violation number="1" location="frontend/packages/graph/package.json:22">
P3: This is a pure repo-tooling change (removing lint/format scripts and toolchain devDependencies), which per the base-branch policy belongs on stable rather than develop. Nothing in the diff affects a running product. Move/cherry-pick this to stable, or confirm the develop targeting is deliberate.</violation>
</file>
<file name="frontend/packages/ui/src/components/breadcrumbs/breadcrumbs.stories.tsx">
<violation number="1" location="frontend/packages/ui/src/components/breadcrumbs/breadcrumbs.stories.tsx:25">
P3: This is a pure tooling/formatting change (Biome migration + reformatting) that cannot affect a running product, but it targets develop. Per the release-vehicle rule, repo tooling/formatting should target stable; consider retargeting the branch (or noting the deliberate exception) so the formatting churn stays off the product release train.</violation>
</file>
<file name=".github/workflows/bug-agent-test.md">
<violation number="1" location=".github/workflows/bug-agent-test.md:259">
P3: This PR is a pure tooling/docs/CI change (Biome/ultracite consolidation, config and workflow updates, AGENTS.md and docs, 28 reformatted frontend files with no functional change) and per repo convention should target stable, since repo tooling can't affect a running product. It currently targets develop; this is a low-severity note, not blocking.</violation>
</file>
<file name="frontend/app/biome.jsonc">
<violation number="1" location="frontend/app/biome.jsonc:2">
P3: This is a pure repo-tooling/docs/CI change (Biome/radoxlint consolidation with no runtime effect) and is targeting develop rather than stable. Per the base-branch convention, changes that can't affect a running product should ship on stable; targeting develop puts tooling churn on the product release train and creates the cherry-pick risk already noted in the description. Low-severity note, not blocking.</violation>
</file>
<file name="frontend/package.json">
<violation number="1" location="frontend/package.json:8">
P3: This PR is a pure tooling/dev-dependency change (consolidating frontend tooling on Biome, removing oxfmt/oxlint), which targets develop. Per the base-branch convention, pure tooling/docs/CI changes should target stable since they cannot affect a running product and can ship before the next minor. Low severity, non-blocking.</violation>
<violation number="2" location="frontend/package.json:10">
P3: The `biome:fix` script was moved from `frontend/app` to the workspace root, but `frontend/app/README.md` still tells users to run `pnpm biome:fix` inside the app, where the script no longer exists and the command now fails. Update the app README to `cd frontend && pnpm biome:fix` like AGENTS.md.</violation>
</file>
<file name="frontend/packages/graph/src/components/export-menu/export-menu.tsx">
<violation number="1" location="frontend/packages/graph/src/components/export-menu/export-menu.tsx:73">
P3: This change is repo tooling/CI/docs consolidation (Biome migration plus cosmetic reformatting with no behavioral impact) and is targeted at develop. Per the release-vehicle policy, tooling/docs/CI changes that can't affect the running product should target stable rather than the normal-develop release train. Low-severity note only, not blocking.</violation>
</file>
<file name="frontend/app/package.json">
<violation number="1" location="frontend/app/package.json:21">
P3: Removing the `biome:fix` script from `frontend/app/package.json` leaves `frontend/app/README.md` (line 12) still documenting `pnpm biome:fix` as an app-local command. A developer following the app README from `frontend/app` now gets "Command 'biome:fix' not found". Update the README to the root command `cd frontend && pnpm biome:fix` (as AGENTS.md already does).</violation>
<violation number="2" location="frontend/app/package.json:21">
P3: This is a pure repo-tooling/CI change, which per your base-branch convention belongs on `stable` (changes that can't affect a running product), yet the PR description states "Targeting develop (not stable)". Note intended as informational, not blocking.</violation>
</file>
<file name="frontend/packages/ui/src/components/sortable-list/sortable-list.stories.tsx">
<violation number="1" location="frontend/packages/ui/src/components/sortable-list/sortable-list.stories.tsx:49">
P3: Per the release-vehicle convention, a pure tooling/docs/CI change should target stable, not develop. This PR consolidates frontend tooling onto Biome (config, CI gates, script removal) and, per the PR description, targets develop. It is a no-op for the running product (only formatting/class-order changes), so it belongs on the stable release vehicle rather than the feature train.</violation>
</file>
<file name="dev/knowledge/frontend/design-system.md">
<violation number="1" location="dev/knowledge/frontend/design-system.md:101">
P3: This is a pure tooling/docs change (Biome consolidation plus developer docs) that cannot affect a running product, so per the base-branch policy it belongs on stable, not develop. The PR description states it targets develop. Move it (or the doc-only portions) to stable, or confirm the tooling change intends to ship as a product change.</violation>
</file>
<file name="frontend/packages/graph/src/index.ts">
<violation number="1" location="frontend/packages/graph/src/index.ts:3">
P3: This is a pure tooling/formatting/CI consolidation (Biome migration) placed on the develop release train. Per release-vehicle policy, repo tooling changes that cannot affect a running product belong on stable; confirm this isn't accidentally queued for the next minor. If develop is required (the description notes frontend/packages diverge between branches and cherry-picking is a concern), that's acceptable — this is a low-severity, non-blocking note.</violation>
</file>
<file name="frontend/biome.jsonc">
<violation number="1" location="frontend/biome.jsonc:11">
P1: Each `files.includes` array in this PR (root, app, packages/ui, packages/graph) contains only negated `!` patterns with no leading positive `**`. Biome 2 docs require `**` first for negated patterns to match anything, and I verified with Biome 2.5.1 that a config whose `includes` is only negated patterns processes zero source files (only the config file itself). As written, `cd frontend && pnpm biome ci .` would silently lint/format no source files, defeating the unified gate this PR introduces. Add `"**"` as the first entry in each `files.includes` array.</violation>
</file>
Shadow auto-approve: would not auto-approve because issues were found.
Re-trigger cubic
…0390] Three follow-ups on #10399: - Reword the changelog fragment; vale's release-notes style rejects "config" (wants "configuration") and flags "CI's" as a spelling error. - frontend/app/README.md still documented `pnpm biome:fix` as an app-local script after the script moved to the workspace root (caught by review). Point it at `pnpm -w biome:fix`. - Exclude src/shared/api/errors/catalogue.generated.ts in the app's Biome config alongside the other generated artefacts. It was already skipped -- ultracite's preset force-excludes `!!**/*.generated.*` -- but the explicit entry documents the intent next to its two generated siblings instead of relying on the preset. Review also claimed the negated-only files.includes arrays make Biome check zero files and prescribed adding "**". Both halves are wrong here: the arrays merge onto ultracite's preset, which already supplies the "**" catch-all (the gate demonstrably checks 1542 files and the negations were verified to exclude schema-visualizer and plugins), and adding our own "**" trips Biome's noBiomeFirstException error while accidentally re-including generated files the preset deliberately excludes. Left as-is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
1 issue found across 3 files (changes from recent commits).
Confidence score: 4/5
frontend/app/README.mdtargetsdevelopeven though this repository’s convention routes tooling and documentation changes tostable; the change could be delayed or follow the wrong release path—retarget the PR tostable.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="frontend/app/README.md">
<violation number="1" location="frontend/app/README.md:12">
P3: This is a pure tooling/docs/CI change targeting `develop`. Per this repo's base-branch convention, repo tooling and docs changes go to `stable` (so they ship without waiting for the next minor); `develop` is reserved for product changes on the normal release train. Low-severity, non-blocking note.</violation>
</file>
Shadow auto-approve: would not auto-approve because issues were found.
Re-trigger cubic
saltas888
marked this pull request as ready for review
August 25, 2026 12:16
The frontend workspace is pnpm-managed, but pre-ci.md and the claude-code workflow allowlist still invoked biome, betterer and codegen via npx/npm run. Switch them to the pnpm equivalents (pnpm biome:fix, pnpm exec betterer, pnpm codegen:graphql). npx markdownlint stays: docs/ is npm-managed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval blocked by 4 unresolved issues from previous reviews.
Re-trigger cubic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #10390. Supersedes #10393.
Why
The frontend supported two linters.
frontend/app(1457 files) was gated by Biome in CI,frontend/packages/uiandfrontend/packages/graph(81 files) shippedoxlint+oxfmtconfigs that nothing ever ran, so both packages had been unchecked since they were created (packages/ui2026-03-18,packages/graph2026-06-11). No ADR recorded the split, and because it was undocumented it actively misled: runningbiome check --writeagainst a package file reformats it to whatever config Biome finds by walking up, which in a worktree is a different checkout entirely.#10393 proposed enforcing each package's existing toolchain in CI. That fixes the coverage hole but keeps two toolchains, so this PR replaces it.
Why Biome rather than oxc
Measured both directions rather than guessing:
noBarrelFileoverridesultraciterule decisions, no oxc equivalentAGENTS.md,pre-ci, editor configBiome wins on every axis, and a pre-1.0 formatter owning 1458 files means reformat churn on each bump. Worth noting the submodule
packages/schema-visualizeris already on Biome too, so oxc was the only outlier.The concern I expected to block this did not: Biome's Tailwind class sorting is a WIP nursery rule with no custom-utility support, while
packages/uipointed oxfmt at a Tailwind v4 stylesheet. ButuseSortedClassesis already enabled viaultracite/biome/coreand the app is clean on all 1457 files, so it is in force and satisfied today. The design system gets lower-fidelity ordering, not none.oxfmt'ssortPackageJsonis genuinely lost.What changed
Biome now owns the whole
frontend/pnpm workspace, using Biome 2's monorepo layout:frontend/biome.jsoncultracitepresetsfrontend/app/biome.jsoncfrontend/packages/{ui,graph}/biome.jsoncnoBarrelFileoff,src/index.tsis each package's public APIThe per-package configs are load-bearing, not decoration: without them the packages are not Biome projects, and
noUndeclaredDependenciescannot resolve their ownpackage.json, reporting all 139 imports as undeclared.frontend-lintjob runs onebiome ci .from./frontendinstead of./frontend/app, so the app and the packages are gated together. No install change,pnpm install --frozen-lockfilealready installs the whole workspace.ultracitemoved to the workspace root package, so there is a single entry point,cd frontend && pnpm biome:fix. The member-levelbiomescripts were removed on purpose, invoking Biome fromfrontend/appsilently leavespackages/*unchecked, which is exactly how the split went unnoticed.packages/plugins/templateis excluded, it is a standalone published scaffold on its own npm + ESLint setup.packages/schema-visualizeris excluded as a submodule with its own config.ox*.config.tsfiles are deleted. The twooxlint-disable-next-linedirectives became plain rationale comments, since both rules they suppressed are off under Biome and abiome-ignorewould be an unused suppression.oxfmtis gone from the lockfile entirely, 40 package entries removed.oxlintsurvives only as a transitive ofreact-scantoreact-doctor, nothing we own configures or runs it.Also updated so nobody runs Biome from the wrong directory:
AGENTS.md,frontend/app/AGENTS.md,.agents/commands/pre-ci.md,dev/knowledge/frontend/design-system.md(which now documents the toolchain, the gap #10390 called out),dev/setup-environment.sh, and the four bug-agent workflow/doc invocation sites.Reformatting risk
Enforcing Biome on previously unchecked code reformatted 28 files and reordered Tailwind classes in 81 places. Class order inside a
classNameis a no-op for rendering, but a dropped class would not be, so I audited the diff token-by-token: every Tailwind utility in a removed line reappears in the corresponding added line. The only tokens unique to either side are trailing commas from re-wrapping and the two rewritten comments. No class was added or dropped.Base branch
Targeting
develop, notstable. Of the 42 files this rewrites underfrontend/packages/, 33 are also modified ondeveloprelative tostable, and whole-file reformats against content changes in the same regions do not auto-merge. Five shared files it edits also differ between the branches (app/package.json,pnpm-lock.yaml,ci.yml,app/AGENTS.md,design-system.md).release-1.11is live, anddev/guidelines/git-workflow.mdforbids mergingstableforward into an older release branch, so astablebase would need cherry-picking there too. This is tooling debt, not a bug in released code.Test plan
Every gate run locally, all green:
cd frontend && pnpm exec biome ci .cd frontend/app && pnpm knipcd frontend/app && pnpm exec betterer cicd frontend/app && pnpm testcd frontend/packages/graph && pnpm testcd frontend/packages/graph && tsc -byamllint -son the changed workflowspnpm install --frozen-lockfileThe one thing local runs cannot cover is Chromatic on
packages/ui. Class reordering is semantically inert and the component tests pass, but a visual diff would make that certain.🤖 Generated with Claude Code