agentsclimarketplace

Linting

Skill 14BryanEspinoza/agent-stack/skills/linting

Skills modulares para asistentes de codificación por IA. Define reglas, flujos de trabajo y estándares técnicos mediante archivos Markdowm.

Install
npx -y skills add 14BryanEspinoza/agent-stack --skill linting

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 21 days oldThe repository was created 21 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Reglas de ESLint y Prettier - formato consistente, flat config, integración con husky/lint-staged, CI/CD

SKILL.md

12.7 KB, as published. Nobody here has run it

Linting — ESLint & Prettier


1. Filosofía

  1. Consistencia sobre preferencias — El linter y formatter eliminan discusiones de estilo. Lo importante es que el código sea uniforme, no qué estilo se elija.
  2. Formato automatizado — Prettier formatea solo, sin configuración por equipo. ESLint se enfoca en calidad de código, no en estilo.
  3. Flat config (ESLint 9+) — Desde ESLint v9, el formato legacy (.eslintrc) está deprecado. Usar eslint.config.js con flat config.
  4. Pre-commit hookslint-staged + husky garantizan que solo pase código linted y formateado. Sin atajos.
  5. CI como cortafuegos — El CI también corre lint. Si pasa local pero falla en CI, hay un desajuste de configuración.

2. Versiones Mínimas

TecnologíaVersión Mínima
Node.js22+
ESLint9+
Prettier3+
@eslint/js9+
typescript-eslint8+
husky9+
lint-staged15+

3. Instalación

# ESLint + Prettier + integración
pnpm add -D eslint prettier eslint-config-prettier

# Husky + lint-staged (pre-commit hooks)
pnpm add -D husky lint-staged

# TypeScript (opcional)
pnpm add -D typescript-eslint @eslint/js typescript

Inicializar Husky

pnpm exec husky init
# Crea .husky/pre-commit — luego agregar: pnpm exec lint-staged

4. ESLint — Flat Config (eslint.config.js)

ESLint 9+ usa flat config por defecto. No crear .eslintrc.*.

Configuración básica (JavaScript/ESM)

// eslint.config.js
import js from "@eslint/js";

export default [
  js.configs.recommended,

  {
    rules: {
      "no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
      "no-console": ["warn", { allow: ["warn", "error"] }],
      "no-debugger": "error",
      "no-duplicate-imports": "error",
      "prefer-const": "error",
      "no-var": "error",
      eqeqeq: ["error", "always"],
      curly: ["error", "all"],
      "no-throw-literal": "error",
      "prefer-template": "warn",
    },
  },

  {
    ignores: [
      "dist/",
      "build/",
      "node_modules/",
      ".git/",
      "coverage/",
      "*.config.*",
    ],
  },
];

TypeScript

// eslint.config.js
import js from "@eslint/js";
import tseslint from "typescript-eslint";

export default tseslint.config(
  js.configs.recommended,
  ...tseslint.configs.recommended,
  ...tseslint.configs.stylistic,

  {
    rules: {
      "@typescript-eslint/no-unused-vars": [
        "warn",
        { argsIgnorePattern: "^_" },
      ],
      "@typescript-eslint/explicit-function-return-type": "off",
      "@typescript-eslint/no-explicit-any": "warn",
      "@typescript-eslint/consistent-type-imports": [
        "error",
        { prefer: "type-imports" },
      ],
    },
  },

  {
    ignores: [
      "dist/",
      "build/",
      "node_modules/",
      ".git/",
      "coverage/",
      "*.config.*",
      "*.d.ts",
    ],
  },
);

React + JSX

// eslint.config.js
import js from "@eslint/js";
import reactPlugin from "eslint-plugin-react";
import reactHooksPlugin from "eslint-plugin-react-hooks";

export default [
  js.configs.recommended,

  {
    plugins: {
      react: reactPlugin,
      "react-hooks": reactHooksPlugin,
    },
    settings: {
      react: { version: "detect" },
    },
    rules: {
      ...reactPlugin.configs.recommended.rules,
      ...reactHooksPlugin.configs.recommended.rules,

      "react/react-in-jsx-scope": "off",
      "react/jsx-uses-react": "off",
      "react/prop-types": "off",
      "react/jsx-no-target-blank": "error",
      "react/self-closing-comp": "error",
    },
  },

  {
    ignores: ["dist/", "build/", "node_modules/", ".git/", "coverage/"],
  },
];

Reglas recomendadas por categoría

Posibles errores

{
  rules: {
    "no-console": ["warn", { allow: ["warn", "error"] }],
    "no-debugger": "error",
    "no-duplicate-imports": "error",
    "no-constant-binary-expression": "error",
    "no-promise-executor-return": "error",
    "no-self-compare": "error",
    "no-template-curly-in-string": "error",
    "no-unmodified-loop-condition": "error",
    "no-unreachable-loop": "error",
    "require-atomic-updates": "error",
  },
}

Buenas prácticas

{
  rules: {
    "array-callback-return": "error",
    "block-scoped-var": "error",
    curly: ["error", "all"],
    "default-case-last": "error",
    eqeqeq: ["error", "always"],
    "no-eval": "error",
    "no-extend-native": "error",
    "no-implied-eval": "error",
    "no-iterator": "error",
    "no-lone-blocks": "error",
    "no-new-wrappers": "error",
    "no-proto": "error",
    "no-return-assign": "error",
    "no-script-url": "error",
    "no-throw-literal": "error",
    "no-unused-expressions": "error",
    "no-useless-concat": "error",
    "prefer-regex-literals": "error",
    "require-await": "warn",
    yoda: "error",
  },
}

Estilo

{
  rules: {
    "consistent-return": "error",
    "no-lonely-if": "error",
    "no-multi-assign": "error",
    "no-nested-ternary": "error",
    "no-unneeded-ternary": "error",
    "one-var": ["error", "never"],
    "prefer-const": "error",
    "prefer-destructuring": "warn",
    "prefer-object-spread": "error",
    "prefer-template": "warn",
    "sort-imports": ["warn", { ignoreDeclarationSort: true }],
  },
}

5. Prettier

.prettierrc

{
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  "bracketSpacing": true,
  "arrowParens": "always",
  "endOfLine": "lf",
  "quoteProps": "as-needed"
}

Alternativa en eslint.config.js

import prettierConfig from "eslint-config-prettier";

export default [
  // ... otras configs
  prettierConfig, // Siempre al final para desactivar reglas conflictivas
];

Ignorar archivos (.prettierignore)

# .prettierignore
dist/
build/
node_modules/
.git/
coverage/
*.min.js
*.map
*.lock
*.svg
*.png
*.jpg
*.ico
CHANGELOG.md

Scripts en package.json

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}

6. Integración ESLint + Prettier

eslint-config-prettier (recomendado)

Desactiva todas las reglas de ESLint que entran en conflicto con Prettier. Se coloca al final del array en flat config.

// eslint.config.js
import js from "@eslint/js";
import prettierConfig from "eslint-config-prettier";

export default [
  js.configs.recommended,
  // ... otros plugins y reglas
  prettierConfig, // último — desactiva reglas de estilo conflictivas
];

eslint-plugin-prettier (no recomendado)

Ejecuta Prettier como regla de ESLint. Tiene problemas de rendimiento y puede duplicar errores. Preferir eslint-config-prettier + ejecutar Prettier por separado.

// ❌ No recomendado
import eslintPluginPrettier from "eslint-plugin-prettier";

export default [
  {
    plugins: { prettier: eslintPluginPrettier },
    rules: {
      "prettier/prettier": "error",
    },
  },
];

Flujo recomendado

1. ESLint detecta errores de calidad (no estilo)
2. Prettier formatea automáticamente (estilo)
3. eslint-config-prettier evita conflictos entre ambos
4. lint-staged ejecuta ambos en pre-commit

7. Husky + lint-staged (Pre-commit Hooks)

Instalación

pnpm add -D husky lint-staged
pnpm exec husky init

Configurar pre-commit hook

# .husky/pre-commit
pnpm exec lint-staged

Configuración en package.json

{
  "lint-staged": {
    "*.{js,ts,tsx,mjs,cjs}": ["eslint --fix", "prettier --write"],
    "*.{json,md,css,html,yaml,yml}": ["prettier --write"]
  }
}

Sin husky (git hooks nativos)

# .git/hooks/pre-commit
#!/bin/sh
pnpm exec lint-staged

8. CI/CD

Pipeline básico

name: Lint & Format
on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: "pnpm"

      - run: pnpm install --frozen-lockfile
      - run: pnpm lint
      - run: pnpm format:check

Con múltiples versiones de Node

jobs:
  lint:
    strategy:
      matrix:
        node-version: [20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: "pnpm"
      - run: pnpm install --frozen-lockfile
      - run: pnpm lint

9. ESLint en Editores

VS Code (settings.json)

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "eslint.validate": [
    "javascript",
    "typescript",
    "javascriptreact",
    "typescriptreact"
  ]
}

Neovim / Vim (lazy.nvim)

{
  "nvimtools/none-ls.nvim",
  dependencies = { "nvim-lua/plenary.nvim" },
  opts = function()
    local null_ls = require("null-ls")
    return {
      sources = {
        null_ls.builtins.formatting.prettier,
        null_ls.builtins.diagnostics.eslint,
        null_ls.builtins.code_actions.eslint,
      },
    }
  end,
}

10. Linting para Otros Archivos

Markdown

pnpm add -D eslint-plugin-markdown
// eslint.config.js
import markdownPlugin from "eslint-plugin-markdown";

export default [
  ...markdownPlugin.configs.recommended,
  {
    files: ["**/*.md"],
    processor: "markdown/markdown",
  },
];

JSON

pnpm add -D prettier-plugin-packagejson
{
  "plugins": ["prettier-plugin-packagejson"]
}

CSS / SCSS

pnpm add -D stylelint stylelint-config-standard
// stylelint.config.js
export default {
  extends: ["stylelint-config-standard"],
  rules: {
    "selector-class-pattern": null,
  },
};

11. Troubleshooting

ESLint no encuentra la config

# Verificar que eslint.config.js existe en la raíz
ls eslint.config.js

# Verificar que no hay .eslintrc.* (legacy)
ls .eslintrc* 2>/dev/null || echo "No legacy config"

# ESLint 9+ ignora .eslintrc si existe eslint.config.js
rm .eslintrc* 2>/dev/null; echo "Legacy configs removed"

Conflicto entre ESLint y Prettier

# eslint-config-prettier desactiva reglas conflictivas
# Asegúrate de que prettierConfig está AL FINAL del array flat config

lint-staged no ejecuta

# Verificar hook
cat .husky/pre-commit

# Asegurar que husky está instalado
pnpm exec husky

# Ejecutar manualmente
pnpm exec lint-staged --verbose

ESLint lento

# Ignorar node_modules y dist
# Usar --cache
pnpm lint --cache

# En flat config, los ignores en objeto tienen más prioridad

Error: "ESLint couldn't find the config"

# Asegurar que eslint.config.js exporta un array
node -e "import('./eslint.config.js').then(m => console.log(Array.isArray(m.default)))"

12. Prohibiciones

  • NO usar .eslintrc.* legacy en proyectos nuevos (usar flat config eslint.config.js)
  • NO desactivar reglas sin comentario explicativo (// eslint-disable-next-line reason)
  • NO committear console.log — usar no-console: warn y revisar antes de commit
  • NO usar eslint-plugin-prettier — preferir eslint-config-prettier + Prettier separado
  • NO ignorar warnings de lint en PRs (configurar max-warnings: 0 en CI)
  • NO saltar hooks de pre-commit (git commit --no-verify solo en emergencias)
  • NO mezclar flat config con legacy config en el mismo proyecto
  • NO usar // eslint-disable-next-line sin especificar la regla exacta
  • NO tener reglas de estilo en ESLint que Prettier ya maneja
  • NO poner archivos autogenerados en lint (ignorar dist/, build/, .next/)
  • NO usar @babel/eslint-parser si usas TypeScript (usar @typescript-eslint/parser)
  • NO instalar ESLint globalmente (usar la versión local del proyecto)

13. Referencias

Nota: Para CI/CD, ver Deploy Nota: Para scripts en package.json, ver Package Manager Nota: Para control de versiones y hooks, ver Git Nota: Para JavaScript/TypeScript, ver JavaScript

Última actualización: 2026-07

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.