diff --git a/AGENTS.md b/AGENTS.md index 1722ece..d1a1d91 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -207,11 +207,42 @@ records.each { syntactically valid. - Never write Ruby, TypeScript, or TSX lines longer than 99 characters. - Aim to keep Ruby, TypeScript, and TSX lines within 79 characters where practical. -- TypeScript and TSX use 4-space logical indentation. -- In TypeScript and TSX only, replace every leading run of 8 spaces with a tab. -- Tabs are only for leading indentation, never for spaces after non-space text. +- In TypeScript and TSX, use 2-space block indentation. +- In TypeScript and TSX, block bodies for components, functions, callbacks, + `if`, `try`, `catch`, `finally`, loops, and JSX nesting use 2 spaces per + level. +- In TypeScript and TSX, use 4-space continuation indentation for wrapped + expressions, arguments, conditions, arrays, object literals, JSX + attributes, and similar continuations. +- Treat the user's `PostImportSourcePage.tsx` and `PostImportReviewPage.tsx` + formatting as the local reference shape: component and callback bodies use + 2-space block indentation, single-line bodies do not gain unnecessary + braces, wrapped expressions use 4-space continuation indentation, multi- + stage ternaries use explicit parentheses, and only complete leading runs + of 8 spaces are compressed to tabs. +- In TypeScript and TSX only, tabs are for leading 8-column compression only. +- A tab does not represent one indentation level. +- Do not replace 2-space or 4-space indentation with tabs. +- First determine visible indentation using 2-space block indentation and + 4-space continuation indentation, then compress only complete leading runs + of 8 spaces into tabs. +- Tabs are only for leading indentation, never for spaces after non-space + text. +- Keep residual leading 2, 4, or 6 spaces after any tab compression. +- Examples: 2 columns = 2 spaces, 4 columns = 4 spaces, 6 columns = 6 + spaces, 8 columns = 1 tab, 10 columns = 1 tab + 2 spaces, 12 columns = 1 + tab + 4 spaces, 16 columns = 2 tabs. - TypeScript and TSX imports may stay on one line if they remain within the line limit; do not expand short type-only imports mechanically. +- Keep runtime value imports and type imports in separate declarations. +- Do not write `import { value, type TypeName } from ...`. +- Type-only declarations must use `import type`. +- Do not merge type imports into value imports merely to save lines. +- In TypeScript and TSX, order imports as four groups with a blank line + between groups: external value imports, `@/...` value imports, external + type imports, `@/...` type imports. +- Do not mechanically split a short value import from one module across + multiple lines when it still fits within 99 characters. - In TypeScript and TSX, when breaking a line at an operator, break before the operator and put the operator at the beginning of the next line. A trailing operator at end of line is unacceptable. This rule does not apply to Ruby, @@ -417,14 +448,17 @@ Good: beginning of a line. - The TSX-specific self-review must confirm JSX closing markers and closing parentheses keep the surrounding compact style. -- The TypeScript/TSX self-review must confirm leading indentation follows - 4-space logical indentation with tabs only as leading 8-space compression. +- The TypeScript/TSX self-review must confirm leading block indentation uses + 2 spaces per level, wrapped continuations use the repository's 4-space + continuation alignment, and complete leading runs of 8 spaces may be + compressed to tabs. - Prefer `const` arrow functions for TypeScript/TSX component and helper declarations. - Put two blank lines before and after top-level `const` function declarations, unless imports, exports, or file boundaries make that awkward. -- In TSX, indent with 4-space logical indentation. -- In TypeScript and TSX, convert every leading run of 8 spaces to a tab - character. +- In TSX, use 2-space block indentation and 4-space continuation + indentation. +- In TypeScript and TSX, convert every complete leading run of 8 spaces to a + tab character. - A leading tab is exactly equivalent to 8 leading spaces. - In TypeScript and TSX function declarations, including `const` arrow function declarations, classify the parameter list before placing the closing @@ -1052,8 +1086,9 @@ to `.ts` and `.tsx`: 7. JSX `>` and `/>` stay with the final prop unless nearby code proves otherwise. 8. JSX closing parentheses keep the compact local style. -9. Leading indentation is 4-space logical indentation with tabs used only as - leading 8-space compression. +9. Leading block indentation uses 2 spaces per level, wrapped continuations + use the repository's 4-space continuation alignment, and complete leading + runs of 8 spaces may be compressed to tabs. 10. No line has trailing whitespace. Preferred: diff --git a/frontend/AGENTS.md b/frontend/AGENTS.md index e61b8b7..77398dc 100644 --- a/frontend/AGENTS.md +++ b/frontend/AGENTS.md @@ -50,16 +50,27 @@ pass or the remaining failure is clearly blocked. - Prefer single quotes for strings unless interpolation or escaping makes double quotes better. - Never write a TypeScript or TSX line longer than 99 characters. - Aim to keep TypeScript and TSX lines within 79 characters where practical. -- Use 4-space logical indentation in TypeScript and TSX. +- Use 2-space block indentation in TypeScript and TSX. +- Use 4-space continuation indentation for wrapped expressions, arguments, + ternary branches, method chains, object pairs, arrays, and JSX attributes. +- Treat the user's `PostImportSourcePage.tsx` and + `PostImportReviewPage.tsx` formatting as the local reference shape. - For arrays, never put whitespace or a line break immediately before `]`. - Keep the first element on the same line as `[` by default. - If an array would exceed the line limit, break after `[` and indent elements by 4 spaces. -- In TypeScript and TSX only, replace every leading run of 8 spaces with a tab - to reduce bytes. +- In TypeScript and TSX only, use tabs for leading 8-column compression only. +- A tab does not represent one indentation level. +- Determine visible indentation with 2-space block indentation and 4-space + continuation indentation first, then compress only complete leading runs of + 8 spaces into tabs. - Treat one leading tab as exactly equivalent to 8 leading spaces. - Use tabs only for leading indentation. Never replace spaces that occur after a non-space character on the same line. +- Keep residual leading 2, 4, or 6 spaces after any tab compression. +- Examples: 2 columns = 2 spaces, 4 columns = 4 spaces, 6 columns = 6 + spaces, 8 columns = 1 tab, 10 columns = 1 tab + 2 spaces, 12 columns = 1 + tab + 4 spaces. ## React @@ -102,7 +113,14 @@ pass or the remaining failure is clearly blocked. - The `@` alias points to `frontend/src`. - Prefer `@/...` imports for app code instead of long relative paths. - Keep type imports separate with `import type`. -- Match existing import grouping: external packages, app modules, then type imports. +- Do not mix runtime values and `type` specifiers in one named import + declaration. +- Do not write `import { value, type TypeName } from ...`. +- Keep short value imports from one module on one line when they fit within + 99 characters. +- Order imports as four groups with a blank line between groups: external + value imports, `@/...` value imports, external type imports, `@/...` + type imports. ## Tailwind and UI @@ -129,10 +147,30 @@ pass or the remaining failure is clearly blocked. it is JSX- or React-specific. - Preserve compact TSX expression shapes such as inline ternary branches and closing `)` forms when nearby code uses them. +- Block bodies for components, functions, callbacks, `if`, `try`, `catch`, + `finally`, loops, and JSX nesting use 2 spaces per level. +- Wrapped expressions, arguments, ternary branches, method chains, and object + pairs use 4-space continuation indentation relative to the owning + expression. Do not confuse this with 2-space block indentation. +- Tabs are leading 8-column compression only. They do not represent one + nesting level. Decide visible indentation first, then compress only + complete leading runs of 8 spaces into tabs. +- Do not add braces around a single-line `if` body merely for formatting. +- Use braces for multi-line `if`, `else`, and loop bodies. - Multi-stage ternary expressions must use explicit parentheses for each - condition group and nested ternary branch. Do not rely on indentation alone - to show `?` / `:` pairing, and extract a helper or `if` when a three-stage - ternary still reads poorly after grouping. + condition group and nested branch. Do not rely on indentation alone to show + `?` / `:` pairing. +- Keep short inline props types local when they remain readable and within the + line limit; do not mechanically extract a named type with no reuse benefit. +- In multi-line object literals, keep the opening `{` with the first pair when + the line length allows it; do not mechanically explode short objects into + Prettier-style vertical blocks. +- Method chains should align as a continuation under the receiver expression; + do not indent chains more deeply than the normal continuation depth. +- `PostImportSourcePage.tsx` and `PostImportReviewPage.tsx` are the current + canonical examples for block indentation, continuation indentation, import + grouping, ternary grouping, method-chain placement, and local inline props + types. - Treat TypeScript and TSX formatting rules as hard constraints, not preferences. Before finishing a TypeScript or TSX edit, inspect the edited hunks for closing `)`, `]`, and `}` placement and fix violations instead of @@ -162,14 +200,76 @@ pass or the remaining failure is clearly blocked. beginning of a line. - The TSX-specific self-review must confirm JSX closing markers and closing parentheses keep the surrounding compact style. -- The TypeScript/TSX self-review must confirm leading indentation follows - 4-space logical indentation with tabs only as leading 8-space compression. +- The TypeScript/TSX self-review must confirm leading block indentation uses + 2 spaces per level, wrapped continuations use the repository's 4-space + continuation alignment, and complete leading runs of 8 spaces may be + compressed to tabs. - For long Tailwind `className` strings, wrap across lines only when needed. -- Keep continuation indentation aligned with the 4-space logical indentation - rule, using tabs only as leading 8-space compression. +- Keep continuation indentation aligned with the repository's 4-space + continuation rule while keeping block indentation at 2 spaces. +- Keep short value imports from one module on one line when they fit within + 99 characters. - In TypeScript and TSX function declarations, including `const` arrow function declarations, classify the parameter list before placing the closing `)`. +- Block indentation example: + +```ts +const Component = () => { + const value = loadValue () + + useEffect (() => { + if (value != null) + useValue (value) + }, [value]) +} +``` + +- Continuation indentation example: + +```ts +const editingRow = + Number.isFinite (editingSourceRow) + ? rows.find (_1 => _1.sourceRow === editingSourceRow) ?? null + : null +``` + +- Import grouping example: + +```ts +import { useNavigate, useParams, useSearchParams } from 'react-router-dom' + +import { loadPostImportSession } from '@/lib/postImportSession' + +import type { FC } from 'react' + +import type { PostImportRow } from '@/lib/postImportSession' +``` + +- Inline props type example: + +```ts +const Footer = ( + { loading, + onSubmit }: { loading: boolean + onSubmit: () => void }, +) => null +``` + +- Ternary grouping example: + +```ts +const rows = + repairMode === 'failed' + ? ( + [...source].sort ((a, b) => { + const aFailed = a.failed ? 0 : 1 + const bFailed = b.failed ? 0 : 1 + return aFailed - bFailed + })) + : source +``` + - If the parameter list itself is given its own multi-line block after the function's opening `(`, put the closing parameter `)` at the beginning of its own line before the return type or `=>`. @@ -567,8 +667,9 @@ hunks line by line: 7. JSX `>` and `/>` stay with the final prop unless nearby code proves otherwise. 8. JSX closing parentheses keep the compact local style. -9. Leading indentation is 4-space logical indentation with tabs used only as - leading 8-space compression. +9. Leading block indentation uses 2 spaces per level, wrapped continuations + use the repository's 4-space continuation alignment, and complete leading + runs of 8 spaces may be compressed to tabs. 10. No line has trailing whitespace. ## Lint and build constraints