diff --git a/AGENTS.md b/AGENTS.md index b1f11bd3db1..c66bda6a28d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -586,8 +586,8 @@ The mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks. over raw `Theme.of(context)` calls. - **Keep widgets small and composable.** One public widget per file; push private sub-widgets (`_Foo`) into sibling `part` files under a - `/` folder rather than growing the page file. Hard ceiling: - **1000 lines/file**, enforced across Desktop, Web, and Mobile by the + `/` folder rather than growing the page file. Mobile's hard ceiling is + **1200 lines/file**, enforced with the other surface-specific limits by the repository-level `just file-size-check` gate (`just check`, CI, and every pre-push). If the guard trips, **split the file — never bump the limit or add an override to slip under it.** diff --git a/desktop/scripts/check-file-sizes.mjs b/desktop/scripts/check-file-sizes.mjs index bfe4fcc8570..97dc4d125aa 100644 --- a/desktop/scripts/check-file-sizes.mjs +++ b/desktop/scripts/check-file-sizes.mjs @@ -5,52 +5,57 @@ import { runFileSizeCheck } from "../../scripts/check-file-sizes-core.mjs"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const projectRoot = path.resolve(__dirname, ".."); -const MAX_LINES = 1000; +const DESKTOP_FRONTEND_MAX_LINES = 1200; +const DESKTOP_RUST_MAX_LINES = 1500; const rules = [ - { root: "src-tauri/src", extensions: new Set([".rs"]), maxLines: MAX_LINES }, + { + root: "src-tauri/src", + extensions: new Set([".rs"]), + maxLines: DESKTOP_RUST_MAX_LINES, + }, // Workspace member crates. Without this the ratchet's only Rust root is // `src-tauri/src`, and a crate under `src-tauri/crates/` is born outside the // repo's one size discipline -- silently, since the check still exits 0. { root: "src-tauri/crates", extensions: new Set([".rs"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_RUST_MAX_LINES, }, { root: "src/app", extensions: new Set([".ts", ".tsx"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_FRONTEND_MAX_LINES, }, { root: "src/features", extensions: new Set([".ts", ".tsx"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_FRONTEND_MAX_LINES, }, { root: "src/shared/api", extensions: new Set([".ts", ".tsx"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_FRONTEND_MAX_LINES, }, { root: "src/shared/context", extensions: new Set([".ts", ".tsx"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_FRONTEND_MAX_LINES, }, { root: "src/shared/lib", extensions: new Set([".ts", ".tsx"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_FRONTEND_MAX_LINES, }, { root: "src/shared/ui", extensions: new Set([".ts", ".tsx"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_FRONTEND_MAX_LINES, }, { root: "src/shared/styles", extensions: new Set([".css"]), - maxLines: MAX_LINES, + maxLines: DESKTOP_FRONTEND_MAX_LINES, }, ]; diff --git a/mobile/scripts/check-file-sizes.mjs b/mobile/scripts/check-file-sizes.mjs index 765cd8edcfb..4d3fb781ce7 100644 --- a/mobile/scripts/check-file-sizes.mjs +++ b/mobile/scripts/check-file-sizes.mjs @@ -5,7 +5,7 @@ import { runFileSizeCheck } from "../../scripts/check-file-sizes-core.mjs"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const projectRoot = path.resolve(__dirname, ".."); -const MAX_LINES = 1000; +const MAX_LINES = 1200; const rules = [ { diff --git a/scripts/check-file-sizes-core.test.mjs b/scripts/check-file-sizes-core.test.mjs index 9b4b910404d..846f0e71767 100644 --- a/scripts/check-file-sizes-core.test.mjs +++ b/scripts/check-file-sizes-core.test.mjs @@ -1,6 +1,6 @@ import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; -import { mkdtempSync } from "node:fs"; +import { mkdtempSync, readFileSync } from "node:fs"; import { tmpdir } from "node:os"; import path from "node:path"; import test from "node:test"; @@ -53,6 +53,27 @@ test("counts empty, LF, and CRLF content with the existing semantics", () => { assert.equal(countLines("one\r\ntwo"), 2); }); +test("surface entrypoints keep the intended ceilings", () => { + const repoRoot = path.resolve(import.meta.dirname, ".."); + const desktop = readFileSync( + path.join(repoRoot, "desktop/scripts/check-file-sizes.mjs"), + "utf8", + ); + const mobile = readFileSync( + path.join(repoRoot, "mobile/scripts/check-file-sizes.mjs"), + "utf8", + ); + const web = readFileSync( + path.join(repoRoot, "web/scripts/check-file-sizes.mjs"), + "utf8", + ); + + assert.match(desktop, /DESKTOP_FRONTEND_MAX_LINES = 1200/); + assert.match(desktop, /DESKTOP_RUST_MAX_LINES = 1500/); + assert.match(mobile, /MAX_LINES = 1200/); + assert.match(web, /MAX_LINES = 1000/); +}); + test("new files use the configured ceiling", () => { assert.equal(allowedLineCount(null, 1000), 1000); assert.deepEqual(