ESLint flat config validation and templates for eslint.config.js files in MetaSaver monorepos. Includes 5 required standards (correct config type for projectType, simple re-export pattern from shared library, flat config filename eslint.config.js, shared config dependency, required npm scripts). Use when creating or auditing eslint.config.js files to ensure correct linting configuration.
Inherits all available tools
Additional assets for this skill
This skill inherits all available tools. When active, it can use any tool Claude has access to.
templates/eslint.config.template.jsThis skill provides eslint.config.js templates and validation logic for ESLint flat config setup.
Manage eslint.config.js configuration to:
This skill is invoked by the eslint-agent when:
Standard templates are located at:
templates/eslint.config.template.js
Each projectType maps to a specific config type from @metasaver/core-eslint-config:
| projectType | Config Type | Description |
|---|---|---|
| base | base | Minimal config (utilities) |
| node | node | Node.js backend services |
| web-standalone | vite-web | Vite React web applications |
| react-library | react-library | React component libraries |
The config type determines which shared configuration is imported.
Configuration files must use simple re-export only:
export { default } from "@metasaver/core-eslint-config/{type}";
Where {type} is one of: base, node, vite-web, react-library
All ESLint rules and configuration complexity lives in the shared @metasaver/core-eslint-config library. Individual projects must NOT define custom rules or overrides.
Must be named exactly eslint.config.js:
eslint.config.ts, eslint.config.mjs, .eslintrc.jsMust have in package.json devDependencies:
{
"devDependencies": {
"@metasaver/core-eslint-config": "workspace:*"
}
}
For monorepos, use workspace:* protocol to reference the shared config package.
Must include lint scripts in package.json:
For packages:
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}
}
For monorepo root:
{
"scripts": {
"lint": "turbo run lint",
"lint:fix": "turbo run lint:fix"
}
}
Monorepo root delegates to Turborepo for parallel linting across packages.
To validate an eslint.config.js file:
metasaver.projectType// Rule 1: Map projectType to config type
const typeMap = {
base: "base",
node: "node",
"web-standalone": "vite-web",
"react-library": "react-library",
};
const expectedType = typeMap[projectType];
// Rule 2: Check re-export pattern
const reExportPattern = new RegExp(
`export\\s*{\\s*default\\s*}\\s*from\\s*["']@metasaver/core-eslint-config/${expectedType}["']`,
);
if (!reExportPattern.test(content)) {
errors.push(
`Rule 2: Must use re-export pattern for config type "${expectedType}"`,
);
}
// Rule 3: Check filename
if (!path.endsWith("eslint.config.js")) {
errors.push("Rule 3: Must be named eslint.config.js (flat config)");
}
// Rule 4: Check dependency
const deps = packageJson.devDependencies || {};
if (!deps["@metasaver/core-eslint-config"]) {
errors.push(
"Rule 4: Missing @metasaver/core-eslint-config in devDependencies",
);
}
// Rule 5: Check npm scripts
const scripts = packageJson.scripts || {};
const isMonorepoRoot = packageJson.name === undefined; // Root has no name
if (isMonorepoRoot) {
if (!scripts.lint?.includes("turbo")) {
errors.push('Rule 5: Monorepo root must use "turbo run lint"');
}
} else {
if (!scripts.lint?.includes("eslint")) {
errors.push('Rule 5: Missing "lint" script with eslint');
}
if (!scripts["lint:fix"]?.includes("eslint")) {
errors.push('Rule 5: Missing "lint:fix" script with eslint --fix');
}
}
Consumer repos may declare exceptions in package.json:
{
"metasaver": {
"exceptions": {
"eslint-config": {
"type": "custom-rules",
"reason": "Requires custom import ordering rules for legacy codebase"
}
}
}
}
This skill integrates with:
scope parameter. If not provided, use /skill scope-check/skill audit-workflow - Bi-directional comparison workflow/skill remediation-options - Conform/Update/Ignore choicestypescript-agent - Coordination with TypeScript configurationprettier-agent - Coordination with Prettier formatting