Agent skill

Eslint Rule Dev

by shepherdjerred in shepherdjerred/monorepo

ESLint custom rule development - AST traversal, rule testing, plugins, and flat config When user creates ESLint rules, develops ESLint plugins, works with AST, or mentions RuleTester

GPL-3.0Auto-check passedDevelopment

Install Eslint Rule Dev

skills CLI
$ npx skills add shepherdjerred/monorepo --skill eslint-rule-dev -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install shepherdjerred/monorepo eslint-rule-dev --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/shepherdjerred/monorepo.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/dotfiles/dot_agents/skills/eslint-rule-dev .claude/skills/eslint-rule-dev && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
eslint-rule-dev
GitHub stars
112
Token cost
~3.5k tokens
SKILL.md length
391 words
Files
1
Skills in repo
63
Repo updated
First seen
Licence
GPL-3.0

At a glance

ESLint custom rule development - AST traversal, rule testing, plugins, and flat config When user creates ESLint rules, develops ESLint plugins, works with AST, or mentions RuleTester

  • Works in 10 steps: Use messageId instead of inline strings… → Define schema for any rule options → Set meta.fixable if providing auto-fixes → …
  • Creates ESLint rules
  • SKILL.md covers What's New in ESLint 9+…, Rule Structure, Meta Properties and The Context Object, plus 11 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Eslint Rule Dev is an agent skill from shepherdjerred/monorepo. ESLint custom rule development - AST traversal, rule testing, plugins, and flat config When user creates ESLint rules, develops ESLint plugins, works with AST, or mentions RuleTester

Its SKILL.md is about 3.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Linting and formatting. It works with ESLint. The repository describes itself as: Monorepo for all of my projects. The licence is GPL-3.0.

When your agent uses it

  • Creates ESLint rules
  • Develops ESLint plugins
  • Mentions RuleTester

Example prompts

  • “/eslint-rule-dev”

Workflow steps

10 steps, taken from the first numbered list in SKILL.md.

  1. Use messageId instead of inline strings for messages
  2. Define schema for any rule options
  3. Set meta.fixable if providing auto-fixes
  4. Make fixes minimal - only change what's necessary
  5. Test both valid and invalid cases with RuleTester
  6. Use AST Explorer (astexplorer.net) to understand node structure
  7. Handle edge cases - optional chaining, spread operators, etc.
  8. Provide suggestions when multiple valid fixes exist
  9. Check for comments before removing/replacing code
  10. Document thoroughly with examples and rationale

What it can do on your machine

Read from SKILL.md and the folder at commit 46ddf2f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript and typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Eslint Rule Dev loads about 3.5k tokens when it runs. Until then it costs about 50 tokens; SKILL.md has 391 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~50
When it runs · the whole SKILL.md, loaded when a task matches
~3.5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from shepherdjerred/monorepo at commit 46ddf2f, republished under its GPL-3.0 licence (© shepherdjerred). 391 words, ~3,525 tokens.

Download SKILL.mdSave it as .claude/skills/eslint-rule-dev/SKILL.md (or your agent's skills folder).
name
eslint-rule-dev
description
ESLint custom rule development - AST traversal, rule testing, plugins, and flat config When user creates ESLint rules, develops ESLint plugins, works with AST, or mentions RuleTester

ESLint Rule Development Agent

What's New in ESLint 9+ (2024-2025)

  • Flat config: eslint.config.js replaces .eslintrc.*
  • ESM support: Native ES modules in configs and rules
  • defineConfig() helper: Type-safe configuration with autocomplete
  • Stricter plugin format: Plugins must use new object structure
  • Removed formatters: Many built-in formatters moved to packages

Rule Structure

Every ESLint rule exports an object with meta and create:

javascript
export default {
  meta: {
    type: "problem", // "problem" | "suggestion" | "layout"
    docs: {
      description: "Disallow foo assigned to anything other than bar",
      recommended: true,
      url: "https://example.com/rules/no-foo",
    },
    fixable: "code", // "code" | "whitespace" | null
    hasSuggestions: true,
    schema: [], // JSON Schema for rule options
    messages: {
      avoidFoo: "Avoid using 'foo' - use 'bar' instead.",
      suggestBar: "Replace with 'bar'.",
    },
  },

  create(context) {
    return {
      // Visitor methods for AST nodes
      Identifier(node) {
        if (node.name === "foo") {
          context.report({
            node,
            messageId: "avoidFoo",
          });
        }
      },
    };
  },
};

Meta Properties

PropertyPurpose
typeRule category: "problem", "suggestion", "layout"
docs.descriptionShort description for documentation
docs.recommendedInclude in recommended config
docs.urlLink to full documentation
fixableEnable auto-fix ("code" or "whitespace")
hasSuggestionsRule provides suggestions
schemaJSON Schema for options validation
messagesMessage templates with IDs
defaultOptionsDefault values for options
deprecatedMark rule as deprecated

The Context Object

The context object passed to create() provides:

Properties
javascript
create(context) {
  // Rule configuration
  context.id              // Rule ID (e.g., "no-console")
  context.options         // Array of configured options
  context.settings        // Shared settings from config

  // File information
  context.filename        // Current file path
  context.cwd             // Current working directory

  // Source code access
  context.sourceCode      // SourceCode object for analysis

  // Language configuration
  context.languageOptions // Parser options, globals, etc.
}
Methods
javascript
// Report a problem
context.report({
  node,
  messageId: "myMessage",
  data: { name: "foo" },
  fix: (fixer) => fixer.replaceText(node, "bar"),
});

AST Node Visitors

Rules work by defining visitor functions for AST node types:

javascript
create(context) {
  return {
    // Called when entering a node
    CallExpression(node) {
      // Analyze call expressions
    },

    // Called when exiting a node (use ":exit" suffix)
    "FunctionDeclaration:exit"(node) {
      // Run after all children processed
    },

    // Selector syntax for complex matching
    "CallExpression[callee.name='require']"(node) {
      // Only matches require() calls
    },
  };
}
Common Node Types
Node TypeMatches
IdentifierVariable names, function names
LiteralStrings, numbers, booleans
CallExpressionFunction calls
MemberExpressionProperty access (a.b, a['b'])
FunctionDeclarationNamed function declarations
ArrowFunctionExpressionArrow functions
VariableDeclarationlet, const, var declarations
ImportDeclarationimport statements
ExportDefaultDeclarationexport default

AST Selectors

ESLint supports CSS-like selectors for targeting nodes:

javascript
// Basic selectors
"Identifier"; // Any identifier
"CallExpression"; // Any function call

// Attribute selectors
"Identifier[name='foo']"; // Identifier named "foo"
"Literal[value=123]"; // Literal with value 123
"CallExpression[callee.name='require']"; // require() calls

// Descendant selectors
"FunctionDeclaration Identifier"; // Identifiers inside functions

// Child selectors
"CallExpression > MemberExpression"; // Direct child

// Sibling selectors
"VariableDeclaration ~ VariableDeclaration"; // Following sibling

// Pseudo-classes
":first-child"; // First child node
":last-child"; // Last child node
":nth-child(2)"; // Second child
":not(Literal)"; // Not a Literal

// Combinations
"CallExpression[callee.object.name='console'][callee.property.name='log']";

Reporting Problems

Basic Report
javascript
context.report({
  node: node,
  messageId: "unexpectedFoo",
  data: { name: node.name },
});
Report with Location
javascript
context.report({
  loc: {
    start: { line: 1, column: 0 },
    end: { line: 1, column: 5 },
  },
  messageId: "unexpectedFoo",
});
Report with Fix
javascript
context.report({
  node,
  messageId: "useBar",
  fix(fixer) {
    return fixer.replaceText(node, "bar");
  },
});
Report with Suggestions
javascript
context.report({
  node,
  messageId: "useBetterName",
  suggest: [
    {
      messageId: "renameToBar",
      fix(fixer) {
        return fixer.replaceText(node, "bar");
      },
    },
    {
      messageId: "renameToQux",
      fix(fixer) {
        return fixer.replaceText(node, "qux");
      },
    },
  ],
});

Fixer Methods

The fixer object provides these methods:

javascript
// Insert text
fixer.insertTextBefore(node, "text");
fixer.insertTextAfter(node, "text");
fixer.insertTextBeforeRange([start, end], "text");
fixer.insertTextAfterRange([start, end], "text");

// Remove
fixer.remove(node);
fixer.removeRange([start, end]);

// Replace
fixer.replaceText(node, "newText");
fixer.replaceTextRange([start, end], "newText");
Multiple Fixes

Return an array or iterable for multiple fixes:

javascript
fix(fixer) {
  return [
    fixer.insertTextBefore(node, "/* comment */ "),
    fixer.replaceText(node.property, "info"),
  ];
}

Accessing Source Code

javascript
create(context) {
  const sourceCode = context.sourceCode;

  return {
    CallExpression(node) {
      // Get source text
      const text = sourceCode.getText(node);

      // Get tokens
      const tokens = sourceCode.getTokens(node);
      const firstToken = sourceCode.getFirstToken(node);
      const lastToken = sourceCode.getLastToken(node);

      // Get comments
      const commentsBefore = sourceCode.getCommentsBefore(node);
      const commentsAfter = sourceCode.getCommentsAfter(node);
      const commentsInside = sourceCode.getCommentsInside(node);

      // Get scope information
      const scope = sourceCode.getScope(node);
      const variables = sourceCode.getDeclaredVariables(node);
    }
  };
}

Scope Analysis

Access variable scopes for advanced analysis:

javascript
create(context) {
  return {
    "Program:exit"(node) {
      const scope = context.sourceCode.getScope(node);

      // All variables in scope
      scope.variables.forEach(variable => {
        console.log(variable.name);
        console.log(variable.references);  // Where it's used
        console.log(variable.defs);        // Where it's defined
      });

      // Unresolved references (global access)
      scope.through.forEach(reference => {
        console.log(reference.identifier.name);
      });

      // Child scopes
      scope.childScopes.forEach(childScope => {
        console.log(childScope.type);  // "function", "block", etc.
      });
    }
  };
}
Show full SKILL.md (159 more words)Show less

Rule Options

Define options using JSON Schema:

javascript
export default {
  meta: {
    schema: [
      {
        type: "object",
        properties: {
          allowFoo: { type: "boolean", default: false },
          maxLength: { type: "integer", minimum: 1 },
        },
        additionalProperties: false,
      },
    ],
    defaultOptions: [{ allowFoo: false, maxLength: 10 }],
  },

  create(context) {
    const options = context.options[0] || {};
    const allowFoo = options.allowFoo ?? false;
    const maxLength = options.maxLength ?? 10;

    return {
      /* visitors */
    };
  },
};

Testing with RuleTester

Basic Test Setup
javascript
import { RuleTester } from "eslint";
import rule from "./my-rule.js";

const ruleTester = new RuleTester({
  languageOptions: {
    ecmaVersion: 2022,
    sourceType: "module",
  },
});

ruleTester.run("my-rule", rule, {
  valid: [
    // Code that should pass
    "const bar = 'hello';",
    { code: "const foo = 'bar';", options: [{ allowFoo: true }] },
  ],

  invalid: [
    {
      code: "const foo = 'hello';",
      errors: [{ messageId: "unexpectedFoo" }],
    },
    {
      code: "const foo = 'hello';",
      output: "const foo = 'bar';", // Expected after fix
      errors: [{ messageId: "unexpectedFoo" }],
    },
  ],
});
Test Case Properties
javascript
{
  code: "const foo = 123;",           // Code to lint
  output: "const foo = 'bar';",       // Expected output after fix
  options: [{ allowFoo: false }],     // Rule options
  errors: [
    {
      messageId: "unexpectedFoo",
      data: { name: "foo" },
      type: "VariableDeclarator",
      line: 1,
      column: 7,
      endLine: 1,
      endColumn: 10,
      suggestions: [
        {
          messageId: "renameToBar",
          output: "const bar = 123;",
        }
      ]
    }
  ],
  filename: "test.js",                // Virtual filename
  only: true,                         // Run only this test
}
TypeScript-ESLint Testing
javascript
import { RuleTester } from "@typescript-eslint/rule-tester";
import rule from "./my-ts-rule";

const ruleTester = new RuleTester({
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: "./tsconfig.json",
  },
});

Creating a Plugin

Plugin Structure
javascript
// eslint-plugin-myplugin/index.js
import noFoo from "./rules/no-foo.js";
import preferBar from "./rules/prefer-bar.js";

export default {
  meta: {
    name: "eslint-plugin-myplugin",
    version: "1.0.0",
  },

  rules: {
    "no-foo": noFoo,
    "prefer-bar": preferBar,
  },

  configs: {
    recommended: {
      plugins: {
        myplugin: plugin,
      },
      rules: {
        "myplugin/no-foo": "error",
        "myplugin/prefer-bar": "warn",
      },
    },
  },
};

const plugin = { meta, rules, configs };
Using the Plugin
javascript
// eslint.config.js
import myplugin from "eslint-plugin-myplugin";

export default [
  {
    plugins: { myplugin },
    rules: {
      "myplugin/no-foo": "error",
    },
  },

  // Or use the recommended config
  myplugin.configs.recommended,
];

Local Rules (Without Publishing)

Using eslint-plugin-local-rules
javascript
// eslint-local-rules/no-foo.js
export default {
  meta: { /* ... */ },
  create(context) { /* ... */ }
};

// eslint-local-rules/index.js
import noFoo from "./no-foo.js";

export default {
  rules: { "no-foo": noFoo }
};
javascript
// eslint.config.js
import localRules from "./eslint-local-rules/index.js";

export default [
  {
    plugins: { local: localRules },
    rules: {
      "local/no-foo": "error",
    },
  },
];

TypeScript Rules

Using @typescript-eslint/utils
typescript
import { ESLintUtils } from "@typescript-eslint/utils";

const createRule = ESLintUtils.RuleCreator(
  (name) => `https://example.com/rules/${name}`,
);

export default createRule({
  name: "no-unsafe-any",
  meta: {
    type: "problem",
    docs: { description: "Disallow unsafe any usage" },
    messages: { unsafeAny: "Avoid using 'any' type" },
    schema: [],
  },

  defaultOptions: [],

  create(context) {
    return {
      TSAnyKeyword(node) {
        context.report({ node, messageId: "unsafeAny" });
      },
    };
  },
});
Accessing Type Information
typescript
import { ESLintUtils } from "@typescript-eslint/utils";

create(context) {
  const services = ESLintUtils.getParserServices(context);
  const checker = services.program.getTypeChecker();

  return {
    Identifier(node) {
      const tsNode = services.esTreeNodeToTSNodeMap.get(node);
      const type = checker.getTypeAtLocation(tsNode);
      const typeString = checker.typeToString(type);

      if (typeString === "any") {
        context.report({ node, messageId: "foundAny" });
      }
    },
  };
}

Best Practices Summary

  1. Use messageId instead of inline strings for messages
  2. Define schema for any rule options
  3. Set meta.fixable if providing auto-fixes
  4. Make fixes minimal - only change what's necessary
  5. Test both valid and invalid cases with RuleTester
  6. Use AST Explorer (astexplorer.net) to understand node structure
  7. Handle edge cases - optional chaining, spread operators, etc.
  8. Provide suggestions when multiple valid fixes exist
  9. Check for comments before removing/replacing code
  10. Document thoroughly with examples and rationale

When to Ask for Help

  • Complex scope analysis across multiple files
  • Type-aware rules needing TypeScript integration
  • Performance optimization for large codebases
  • Migration from eslintrc to flat config
  • Custom parsers for non-standard syntax
  • Rule conflicts and fix ordering issues

© shepherdjerred, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in packages/dotfiles/dot_agents/skills/eslint-rule-dev of shepherdjerred/monorepo.

Open the folder on GitHubat commit 46ddf2f

Compare with similar skills

Eslint Rule Dev next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Eslint Rule Dev compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Eslint Rule Dev this skillshepherdjerred/monorepo112—~3.5kAutomated safety check: PassGPL-3.0
LobeHub Alint Rule Set Maintenancelobehub/lobehub83k—~1.9kAutomated safety check: PassCustom licence
Ultraciteagustinusnathaniel/nextarter-tailwind1252 repos~1.2kAutomated safety check: PassMIT
Code Qualityredis/RedisInsight8.9k—~1.2kAutomated safety check: PassCustom licence
Boundaries Architectjavierbrea/eslint-plugin-boundaries997—~4.2kAutomated safety check: PassMIT
Port Ruleweb-infra-dev/rslint460—~1.7kAutomated safety check: PassMIT

Similar skills

  • Maintains LobeHub's model-backed alint rule set: writing rules, removing false positives against real code, deciding warn versus error and tracking token cost.

    83k GitHub stars~1.9k tokensUpdated today
    DevelopmentAuto-check passed
  • Ultracite

    agustinusnathaniel/nextarter-tailwind

    Ultracite is a zero-config linting and formatting preset for JavaScript/TypeScript projects.

    125 GitHub starsUsed in 2 repos~1.2k tokens
    DevelopmentAuto-check passed
  • Code Quality

    redis/RedisInsight

    Official

    Code-quality standards for RedisInsight: TypeScript strictness, naming conventions (camelCase, PascalCase, UPPERSNAKECASE), linting rules, no any without reason, no !important in styles, and…

    8.9k GitHub stars~1.2k tokensUpdated 3 days ago
    DevelopmentAuto-check passed
  • Boundaries Architect

    javierbrea/eslint-plugin-boundaries

    Act as a software architect: analyze a repository's folder structure and cross-file import dependencies, detect its architectural pattern, design element/file boundaries with the user, and configure…

    997 GitHub stars~4.2k tokensUpdated 2 days ago
    DevelopmentAuto-check passed
  • Port Rule

    web-infra-dev/rslint

    Port a new ESLint core or plugin rule to rslint, including explicitly requested batches.

    460 GitHub stars~1.7k tokensUpdated today
    DevelopmentAuto-check passed
  • Lint New

    getsentry/sentry

    Official

    Create a new ESLint rule with tests for eslintPluginScraps. An agent skill from getsentry/sentry.

    45k GitHub stars~1.8k tokensUpdated today
    DevelopmentAuto-check passed

More from shepherdjerred/monorepo

All 63 skills in this repo
  • Bun Runtime Best Practices

    shepherdjerred/monorepo

    Bun runtime APIs and current operational patterns for files, processes, modules, networking, databases, tests, and deployment.

    112 GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Bun Test Patterns

    shepherdjerred/monorepo

    Current Bun test runner guidance for discovery, isolation, parallelism, sharding, changed tests, mocks, timers, snapshots, coverage, DOM Testing Library, and integration teardown.

    112 GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Bun Workspaces

    shepherdjerred/monorepo

    Current Bun workspace guidance for isolated and hoisted linkers, catalogs, filters, scripts, dependency classes, lockfiles, lifecycle trust, caches, publishing, TypeScript package exports, and…

    112 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Deep Research

    shepherdjerred/monorepo

    This skill should be used when the user asks to "deep research", "research this topic", "investigate thoroughly", "do a deep dive on", "comprehensive research on", "find everything about", "survey…

    112 GitHub stars~4.7k tokensUpdated today
    Auto-check: notes
  • Figma Use

    shepherdjerred/monorepo

    This skill should be used when the user asks to "create a Figma design", "design in Figma", "make a Figma mockup", "create an app icon", "design UI", "render JSX to Figma", "export from Figma"…

    112 GitHub stars~946 tokensUpdated today
    Auto-check passed
  • Fish Helper

    shepherdjerred/monorepo

    Current Fish shell scripting, functions, abbreviations, completions, variables, events, configuration, plugins, testing, and safety guidance.

    112 GitHub stars~2k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Eslint Rule Dev

What does Eslint Rule Dev do?

ESLint custom rule development - AST traversal, rule testing, plugins, and flat config When user creates ESLint rules, develops ESLint plugins, works with AST, or mentions RuleTester. Eslint Rule Dev is an agent skill from shepherdjerred/monorepo.

When should I use Eslint Rule Dev?

Eslint Rule Dev fits situations like: creates ESLint rules; develops ESLint plugins; mentions RuleTester.

How do I install Eslint Rule Dev in Claude Code?

Run `npx skills add shepherdjerred/monorepo --skill eslint-rule-dev -a claude-code`. Or copy the skill folder (packages/dotfiles/dot_agents/skills/eslint-rule-dev in shepherdjerred/monorepo) into .claude/skills/eslint-rule-dev in your project. Claude Code loads it when a task matches its description.

How do I install Eslint Rule Dev in Codex?

Run `npx skills add shepherdjerred/monorepo --skill eslint-rule-dev -a codex`. Or copy the skill folder (packages/dotfiles/dot_agents/skills/eslint-rule-dev in shepherdjerred/monorepo) into .agents/skills/eslint-rule-dev in your project. Codex loads it when a task matches its description.

Can I use Eslint Rule Dev in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add shepherdjerred/monorepo --skill eslint-rule-dev -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/eslint-rule-dev, .gemini/skills/eslint-rule-dev, .github/skills/eslint-rule-dev and .opencode/skills/eslint-rule-dev in your project.

What does Eslint Rule Dev need to run?

SKILL.md names no scripts, command-line tools or credentials: Eslint Rule Dev is instructions for the agent only.

Does Eslint Rule Dev access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Eslint Rule Dev safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Eslint Rule Dev use?

Eslint Rule Dev is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Eslint Rule Dev use?

About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Eslint Rule Dev?

Skills that share tags, products or a category with Eslint Rule Dev: LobeHub Alint Rule Set Maintenance (lobehub/lobehub, 83k stars), Ultracite (agustinusnathaniel/nextarter-tailwind, 125 stars), Code Quality (redis/RedisInsight, 8.9k stars) and Boundaries Architect (javierbrea/eslint-plugin-boundaries, 997 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Eslint Rule Dev?

shepherdjerred (a GitHub user) maintains it in shepherdjerred/monorepo, which has 112 GitHub stars. The repository holds 63 skills in this directory. The repository was last updated on October 7, 2026.

Source: shepherdjerred/monorepo on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.