lint-new

par sentry

Créer une nouvelle règle ESLint avec des tests pour eslintPluginScraps. Utiliser lorsqu'on demande de "créer une règle de lint", "ajouter une règle eslint", "générer une règle", "écrire une nouvelle…

npx skills add https://github.com/getsentry/sentry --skill lint-new

Create a new ESLint rule named $ARGUMENTS in the eslintPluginScraps plugin.

Step 1: Choose Your Archetype

Read references/rule-archetypes.md and pick the archetype that matches your rule's intent:

You want to...ArchetypeReference to load
Rewrite import pathsImport rewriteInline — simple pattern
Validate token/value usage per CSS propertyProperty validationstyle-collector-guide.md
Restrict JSX elements in specific propsJSX structuralrule-archetypes.md §Archetype 3
Detect patterns in static CSS textTemplate text analysisrule-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/eslint/eslintPluginScraps/src/ast/ for reusable code:

UtilityLocationUse for
getStyledCallInfosrc/ast/utils/styled.tsClassifying styled/css calls as element, component, or css
createQuasiScannersrc/ast/scanner/index.tsScanning static CSS text in template literals (Archetype 4)
createImportTrackersrc/ast/tracker/imports.tsResolving where a local name was imported from
createStyleCollectorsrc/ast/extractor/index.tsCollecting CSS-in-JS dynamic value declarations (NOT static text)
shouldAnalyzesrc/ast/extractor/index.tsFast pre-scan to skip files without Emotion usage
normalizePropertyNamesrc/ast/utils/normalizePropertyName.tsNormalizing CSS property names
decomposeValuesrc/ast/extractor/value-decomposer.tsBreaking complex expressions into all possible values
Theme trackersrc/ast/tracker/theme.tsTracking 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/eslint/eslintPluginScraps/src/rules/$ARGUMENTS.ts
  2. Test: static/eslint/eslintPluginScraps/src/rules/$ARGUMENTS.spec.ts

Rule Template

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.

Test Template

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:

pnpm test-ci "static/eslint/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

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/eslint/eslintPluginScraps/src/rules/index.ts:

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:

'@sentry/scraps/$ARGUMENTS': 'error',
// or with options:
'@sentry/scraps/$ARGUMENTS': ['error', { /* options */ }],

3. Verify

pnpm test-ci "static/eslint/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)

Plus de skills de sentry

generate-frontend-forms
sentry
Guide pour créer des formulaires à l'aide du nouveau système de formulaires de Sentry. À utiliser lors de l'implémentation de formulaires, de champs de formulaire, de validation ou de fonctionnalité de sauvegarde automatique.
official
sentry-snapshots-cocoa
sentry
Configuration complète de Sentry Snapshots pour les projets Apple/Cocoa. Utiliser lorsqu’on demande de « configurer SnapshotPreviews », « configurer les tests de snapshots Apple », « télécharger les snapshots Apple vers…
official
architecture-review
sentry
Revue de la santé du codebase au niveau de l'équipe. Détecte les modules monolithiques, les échecs silencieux, les lacunes de sécurité de type, les trous de couverture de test et les problèmes de convivialité pour les LLM.
official
linear-type-labeler
sentry
Classe les tickets Linear et applique un label de type issu de la taxonomie de labels de l'espace de travail Sentry, en fonction du contenu du titre et de la description de chaque ticket.
official
sentry-flutter-sdk
sentry
Configuration complète du SDK Sentry pour Flutter et Dart. Utiliser lorsqu'il est demandé d'« ajouter Sentry à Flutter », d'« installer sentry_flutter », de « configurer Sentry dans Dart » ou de paramétrer la gestion des erreurs…
official
sentry-svelte-sdk
sentry
Configuration complète du SDK Sentry pour Svelte et SvelteKit. Utiliser lorsqu'il est demandé d'« ajouter Sentry à Svelte », d'« ajouter Sentry à SvelteKit », d'« installer @sentry/sveltekit », ou de configurer…
official
vercel-react-best-practices
sentry
Directives d'optimisation des performances React et Next.js de l'équipe Vercel Engineering. Cette compétence doit être utilisée lors de l'écriture, de la révision ou du refactoring de code React/Next.js…
official
sentry-tanstack-start-sdk
sentry
Configuration complète du SDK Sentry pour TanStack Start React. À utiliser lorsqu'on vous demande "ajouter Sentry à TanStack Start", "installer @sentry/tanstackstart-react", ou configurer la gestion des erreurs…
official