Files
airship/biome.jsonc
T
Nayan a884e72f66 chore(lint): adopt biome through the ultracite preset
Biome replaces the eslint + prettier pair outright: one binary, one pass, and it is fast
enough to run on every save and every commit without anyone noticing.

Ultracite is the preset — zero-config, strict, and mostly auto-fixable — so
biome.jsonc only carries what this repo overrides on top of it.
2026-07-25 11:40:00 +05:30

91 lines
3.9 KiB
JSON

{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"extends": [
"ultracite/biome/core",
"ultracite/biome/vitest",
"ultracite/biome/react",
"ultracite/biome/next",
"ultracite/biome/tanstack"
],
"files": {
// An imported UI icon set, vendored verbatim. These are build inputs for
// scripts/gen.mjs, not authored source: formatting them churns 507 files
// and reorders SVG attributes for no benefit, and `noSvgWithoutTitle` does
// not apply to a corpus that only ever reaches the DOM through the
// generator.
"includes": [
"!packages/editor-icons/assets",
// Static assets apps/web serves from /public — the wallpapers, the dock
// glyphs, the favicon. Hand-drawn SVGs, never parsed as JSX: they reach
// the page through an <img src> or a CSS url(), so `noSvgWithoutTitle` is
// checking a file that has no accessible name to give. The call site
// supplies the alt text instead.
"!**/apps/*/public"
]
},
"linter": {
"rules": {
"suspicious": {
// Unreliable here, in two ways that between them cover all 54 hits it
// reported, and every one of its "fixes" deletes a live guard:
//
// - It reads `a?.b` as non-nullish even when `a` is nullable, so it
// calls the fallback in `options.width ?? preset?.width ?? 1440`
// (`presetById` returns `DevicePreset | null`) unreachable. It is
// reached whenever the id matches no preset.
// - It does not model class fields mutated from another method, so
// `private replaying = false` reads as permanently false at its
// `if (this.replaying)` guard — the flag that stops undo/redo from
// re-recording its own replays. Same for `awaiting` and `editing`.
//
// Revisit when the rule leaves nursery; the genuine hits it also found
// were redundant `?? ""` on non-optional strings, which cost nothing.
"noUnnecessaryConditions": "off"
}
}
},
"overrides": [
{
// Each package's `src/index.ts` *is* its published surface — it is what
// the `exports` map in package.json points at. `dnd/manager.ts` is the
// same idea internally: one wrapper that owns the dnd-kit dependency so
// nothing else imports it directly. `noBarrelFile` is aimed at re-export
// hubs that defeat tree-shaking inside an app, not at a declared API.
//
// The `**/` prefix is now redundant — every package lives at
// packages/*/ under this one workspace root — but it is harmless and
// matches the same set, so it stays rather than churning the glob.
"includes": [
"**/packages/*/src/index.ts",
"packages/overlay/src/dnd/manager.ts"
],
"linter": { "rules": { "performance": { "noBarrelFile": "off" } } }
},
{
// `ultracite/biome/next` is extended at the root for the packages that do
// target Next. apps/web does not: it is a TanStack Start app, where
// `<img>` is the image element and the `<head>` in the root route's shell
// component is the document head it is supposed to render. Both rules
// exist to push you toward `next/image` and the metadata API, neither of
// which exists here — following them would mean importing from a
// framework this app does not depend on.
"includes": ["apps/web/**"],
"linter": {
"rules": {
"performance": { "noImgElement": "off" },
"style": { "noHeadElement": "off" }
}
}
},
{
// Generated by the TanStack Router CLI on every dev run and every build.
// It ships its own @ts-nocheck and lint-disable banner and is rewritten
// from src/routes, so formatting it is churn that the next `tsr generate`
// discards.
"includes": ["**/src/routeTree.gen.ts"],
"formatter": { "enabled": false },
"linter": { "enabled": false }
}
]
}