Skip to main content

lint-new

Create a new ESLint rule with tests for eslintPluginScraps. Use when asked to "create a lint rule", "add an eslint rule", "scaffold a rule", "write a new scraps rule", or "new design system lint rule". Covers rule creation, test authoring, registration, and autofix implementation.

Quellinformationen

Repository
getsentry/sentry
Letzte Quellaktivität
3. September 2026 um 20:35
Erkannte Sprache von SKILL.md
Englisch
Sterne
45.574
Forks
4.930

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
4 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
lint-new
description
Create a new ESLint rule with tests for eslintPluginScraps. Use when asked to "create a lint rule", "add an eslint rule", "scaffold a rule", "write a new scraps rule", or "new design system lint rule". Covers rule creation, test authoring, registration, and autofix implementation.
Create a new ESLint rule named `$ARGUMENTS` in the eslintPluginScraps plugin. ## Step 1: Choose Your Archetype Read [references/rule-archetypes.md](references/rule-archetypes.md) and pick the archetype that matches your rule's intent: | You want to... | Archetype | Reference to load | | ------------------------------------------- | ---------------------- | ---------------------------------------------------------------- | | Rewrite import paths | Import rewrite | Inline — simple pattern | | Validate token/value usage per CSS property | Property validation | [style-collector-guide.md](references/style-collector-guide.md) | | Restrict JSX elements in specific props | JSX structural | [rule-archetypes.md](references/rule-archetypes.md) §Archetype 3 | | Detect patterns in static CSS text | Template text analysis | [rule-archetypes.md](references/rule-archetypes.md) §Archetype 4 | Read the relevant reference before writing code. The archetypes document which AST visitors to use, which shared utilities apply, and which patterns are NOT appropriate for each approach. ## Step 2: Check Shared Utilities Before writing AST traversal logic, check `static/oxlint/eslintPluginScraps/src/ast/` for reusable code: | Utility | Location | Use for | | ----------------------- | ---------------------------------------- | ------------------------------------------------------------------- | | `getStyledCallInfo` | `src/ast/utils/styled.ts` | Classifying styled/css calls as element, component, or css | | `createQuasiScanner` | `src/ast/scanner/index.ts` | Scanning static CSS text in template literals (Archetype 4) | | `createImportTracker` | `src/ast/tracker/imports.ts` | Resolving where a local name was imported from | | `createStyleCollector` | `src/ast/extractor/index.ts` | Collecting CSS-in-JS _dynamic value_ declarations (NOT static text) | | `shouldAnalyze` | `src/ast/extractor/index.ts` | Fast pre-scan to skip files without Emotion usage | | `normalizePropertyName` | `src/ast/utils/normalizePropertyName.ts` | Normalizing CSS property names | | `decomposeValue` | `src/ast/extractor/value-decomposer.ts` | Breaking complex expressions into all possible values | | Theme tracker | `src/ast/tracker/theme.ts` | Tracking `useTheme()` and callback theme bindings | If another rule already solves a similar problem, extract shared logic into `src/ast/utils/` and reuse it. ## Step 3: Create Files 1. **Rule**: `static/oxlint/eslintPluginScraps/src/rules/$ARGUMENTS.ts` 2. **Test**: `static/oxlint/eslintPluginScraps/src/rules/$ARGUMENTS.spec.ts` ### Rule Template ```typescript import {ESLintUtils} from '@typescript-eslint/utils'; export const $RULE_NAME = ESLintUtils.RuleCreator.withoutDocs({ meta: { type: 'problem', docs: { description: '[Rule description]', }, fixable: 'code', // include if rule has autofix — see Autofix Guidance schema: [], messages: { forbidden: 'Error message shown to user', }, }, create(context) { return { // AST visitor methods — see your chosen archetype }; }, }); ``` If your rule needs configurable options, load [references/schema-patterns.md](references/schema-patterns.md). ### Test Template ```typescript import {RuleTester} from '@typescript-eslint/rule-tester'; import {$RULE_NAME} from './$ARGUMENTS'; const ruleTester = new RuleTester(); ruleTester.run('$ARGUMENTS', $RULE_NAME, { valid: [ { code: '// valid code', filename: '/project/src/file.tsx', }, ], invalid: [ { code: '// invalid code', filename: '/project/src/file.tsx', errors: [{messageId: 'forbidden'}], output: '// expected output after autofix', // REQUIRED for fixable rules }, ], }); ``` Run tests: ```bash pnpm test-ci "static/oxlint/eslintPluginScraps/src/rules/$ARGUMENTS.spec.ts" ``` ## Autofix Guidance **Default stance: implement autofix** unless the transformation is ambiguous or could change runtime behavior. ### Safe autofix patterns - Import path rewrites (see `no-core-import.ts` as canonical example) - Adding/removing JSX attributes with known values - Wrapping expressions in a known component - Identifier renames with no shadowing risk ### Do NOT autofix when - Multiple valid fixes exist and the right choice requires human judgment - The fix requires type information not available from the AST alone - The transformation alters control flow or runtime behavior - The change spans multiple files ### Fixer API ```typescript context.report({ node, messageId: 'forbidden', fix(fixer) { return fixer.replaceText(node, newText); // Also: fixer.replaceTextRange([start, end], text) // fixer.insertTextBefore(node, text) // fixer.insertTextAfter(node, text) // fixer.remove(node) // Return single fix or array of fixes }, }); ``` When a rule is fixable, every invalid test case MUST include `output` showing the expected code after the fix. ## Step 4: Register the Rule ### 1. Rule Index Add to `static/oxlint/eslintPluginScraps/src/rules/index.ts`: ```typescript import {$RULE_NAME} from './$ARGUMENTS'; export const rules = { // existing rules... $ARGUMENTS: $RULE_NAME, }; ``` ### 2. ESLint Config Add to `eslint.config.ts` inside the `name: 'plugin/@sentry/scraps'` block: ```typescript '@sentry/scraps/$ARGUMENTS': 'error', // or with options: '@sentry/scraps/$ARGUMENTS': ['error', { /* options */ }], ``` ### 3. Verify ```bash pnpm test-ci "static/oxlint/eslintPluginScraps/src/rules/$ARGUMENTS.spec.ts" ``` ## Extending an Existing Rule If modifying an existing rule rather than creating a new one: 1. Read the existing rule and its config files to understand the architecture 2. For **config-driven rules** (like `use-semantic-token`): changes often only require editing the config file (e.g., `src/config/tokenRules.ts`), not the rule logic 3. Watch for reverse-mapping side effects — adding a new category can change which category is _suggested_ for shared properties (last writer wins in `buildPropertyToRule`) 4. Update existing tests for any changed behavior, then add new test cases ## Naming Convention - **Rule name** (kebab-case): `my-rule-name` — verb-noun pattern (e.g., `no-token-import`, `use-semantic-token`) - **Export name** (camelCase): `myRuleName` - **File name**: matches rule name exactly (`my-rule-name.ts`, `my-rule-name.spec.ts`)
Auf GitHub ansehen