Agent Skills: Static Code Analysis for TypeScript Projects

Creates, reviews, and modernizes static code analysis setups for Node.js and TypeScript repositories, covering ESLint flat config, typescript-eslint, tsconfig, Prettier, import sorting, Husky, lint-staged, package.json quality scripts, and CI quality gates. Use when setting up or auditing linting, formatting, type-checking, commit hooks, or GitHub Actions quality checks in a TypeScript project.

UncategorizedID: jaktestowac/awesome-copilot-for-testers/static-code-analysis-typescript

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jaktestowac/awesome-copilot-for-testers/tree/HEAD/skills/static-code-analysis-typescript

Skill Files

Browse the full folder contents for static-code-analysis-typescript.

Download Skill

Loading file tree…

skills/static-code-analysis-typescript/SKILL.md

Skill Metadata

Name
static-code-analysis-typescript
Description
'Creates, reviews, and modernizes static code analysis setups for Node.js and TypeScript repositories, covering ESLint flat config, typescript-eslint, tsconfig, Prettier, import sorting, Husky, lint-staged, package.json quality scripts, and CI quality gates. Use when setting up or auditing linting, formatting, type-checking, commit hooks, or GitHub Actions quality checks in a TypeScript project.'

Static Code Analysis for TypeScript Projects

Use this skill when you need to create, review, fix, or modernize static code analysis in a Node.js + TypeScript repository.

It is designed for repositories that use or should use:

  • eslint (flat config)
  • typescript-eslint
  • typescript
  • tsconfig.json
  • prettier
  • eslint-plugin-simple-import-sort (import sorting via ESLint)
  • husky
  • lint-staged
  • package.json scripts
  • CI quality gates (GitHub Actions)

When to Use

Use this skill when the user asks things like:

  • "set up static analysis for TypeScript"
  • "add ESLint / typescript-eslint / Prettier"
  • "review our lint, tsc, husky, or lint-staged setup"
  • "fix package.json scripts for code quality"
  • "prepare CI checks for linting and type checking"
  • "standardize naming for static code analysis scripts"
  • "audit whether this repo follows current best practices"
  • "set up import sorting"
  • "replace trivago import sorting plugin"
  • "add a CI quality gate workflow"

Goals

This skill should help produce a setup that is:

  • explicit
  • reproducible
  • CI-friendly
  • fast enough for local development
  • strict enough to catch issues early
  • easy to understand from package.json, README.md, and the config files
  • portable across Playwright, Cypress, and general TypeScript projects

Recommended Outcome

A strong baseline should usually include:

  • ESLint flat config (eslint.config.mjs)
  • typescript-eslint for TypeScript-aware linting
  • direct typescript dependency when tsc is used directly
  • strict tsconfig.json
  • clear split between formatting and linting responsibilities
  • import sorting via ESLint (eslint-plugin-simple-import-sort)
  • husky hook for local guardrails
  • lint-staged for staged-file workflows
  • CI commands that do not mutate files
  • explicit Node version support in package.json#engines
  • a CI quality gate (integrated into an existing workflow when one exists)

Concrete baseline files (eslint.config.mjs, package.json scripts, tsconfig, Prettier, Husky, VS Code settings, CI workflows) live in ./resources/example-configs.md.

Procedure

1. Inspect the existing setup

Check at least these files when they exist:

  • package.json
  • eslint.config.* (or legacy .eslintrc*)
  • tsconfig.json
  • .prettierrc*
  • .prettierignore
  • .husky/*
  • .github/workflows/*
  • .vscode/settings.json
  • .vscode/extensions.json
  • README.md
  • any existing audit or decision documents

Identify:

  • what tools are already installed
  • whether the repo uses flat config or legacy ESLint config
  • whether typescript is direct or transitive
  • whether tsc is used as a real gate
  • whether prettier is standalone, inside ESLint, or split by file type
  • whether commit hooks validate the whole repo or only staged files
  • whether CI enforces the same checks as local hooks
  • how import sorting is handled (Prettier plugin, ESLint plugin, VS Code, or not at all)
  • whether VS Code source.organizeImports could conflict with other import sorting

2. Classify the current architecture

Choose the current model before editing anything:

  • Model A — Separate responsibilities: ESLint for code quality; Prettier for formatting; prettier --check used directly; eslint-config-prettier avoids rule conflicts.
  • Model B — ESLint also enforces Prettier in TypeScript: eslint-plugin-prettier runs formatting checks inside ESLint, often paired with a separate Prettier CLI check for non-TS files.
  • Model C — Mixed or inconsistent: scripts overlap, responsibilities are unclear, TS formatting may be checked twice or not clearly at all.

When possible, make the final state explicit in docs so the split is understandable.

3. Normalize dependency expectations

For TypeScript repositories, prefer these principles:

  • if the repo runs tsc, add typescript directly in devDependencies
  • if ESLint is used, make the config style explicit and modern (flat config)
  • if typescript-eslint is installed, ensure versions are compatible with ESLint and TypeScript
  • if tooling requires newer Node versions, declare them in package.json#engines

Typical direct dev dependencies: eslint, @eslint/js, typescript-eslint, typescript, prettier, eslint-config-prettier, eslint-plugin-simple-import-sort, globals, husky, lint-staged, optionally eslint-plugin-prettier and repo-specific plugins such as eslint-plugin-playwright.

If the repository contains Playwright tests, strongly consider:

  • eslint-plugin-playwright
  • Playwright-specific rule tuning in ESLint
  • ignoring generated Playwright artifacts such as playwright-report/** and test-results/**

4. Assess import sorting

Check how imports are currently sorted:

  • No sorting → add eslint-plugin-simple-import-sort
  • @trivago/prettier-plugin-sort-imports → migrate to eslint-plugin-simple-import-sort (Babel parser, no Prettier 4 support)
  • @ianvs/prettier-plugin-sort-imports → consider migrating for cleaner separation
  • eslint-plugin-simple-import-sort → already optimal
  • eslint-plugin-perfectionist → acceptable if broader sorting rules are wanted
  • VS Code source.organizeImports → remove if any other import sorting tool is active; it conflicts

Rationale, decision tree, and step-by-step migrations are in ./resources/import-sorting.md.

After migration, run npx eslint . --fix to normalize all imports, then verify with npx eslint . --max-warnings=0.

5. Normalize script naming in package.json

Prefer predictable script names:

  • lint → runs ESLint in non-fix mode and should fail on warnings if that is the chosen policy
  • format → mutating formatter run, usually prettier --write
  • format:check → non-mutating formatting validation
  • tsc:checktsc --noEmit
  • check → aggregate quality command (local, may mutate)
  • check:ci → aggregate quality command (CI, non-mutating)
  • lint-staged → entrypoint for staged-file validation

Guidelines:

  • commands used in CI should not mutate files
  • provide both check (local, with --write) and check:ci (CI, with --check)
  • if the repo intentionally splits non-TS and TS formatting, make that explicit with names such as format:check and format:check:non-ts

6. Decide how formatting should work

Make one of the following explicit:

  • Preferred modern baseline: Prettier CLI validates formatting; ESLint handles code-quality rules; eslint-config-prettier disables formatting-conflicting lint rules.
  • Acceptable intentional split: TypeScript files are checked via ESLint + eslint-plugin-prettier; non-TypeScript files are checked by prettier --check; docs clearly explain the split.

Avoid leaving the repo in a state where it is unclear whether *.ts files are checked by Prettier CLI, by ESLint, twice, or not consistently at all.

7. Validate TypeScript configuration

For tsconfig.json, prefer:

  • strict: true
  • module: "ESNext" when the project uses ESM import/export syntax (the default for modern TypeScript projects)
  • moduleResolution: "bundler"required when module is "ESNext" and TypeScript does not emit code; without it TS falls back to "classic" resolution which cannot resolve node_modules
  • noEmit: true when TypeScript is used only for type checking
  • explicit baseUrl / paths only when justified

Common mistake: "module": "CommonJS" with "target": "ESNext" — the project writes ESM but tells TypeScript to resolve modules as CJS. See the tsconfig notes in ./resources/example-configs.md for the full rationale.

If the repo uses path aliases, confirm they are supported consistently by TypeScript, runtime/test tooling, and editor tooling.

8. Set up Husky and lint-staged correctly

Recommended pattern:

  • lint-staged handles staged-file formatting and fixable lint checks (including import sorting)
  • full-project tsc:check may still run in pre-commit or pre-push, depending on repo size and tolerance for slower hooks

Good staged-file mapping examples:

  • *.tsprettier --write, eslint --fix (auto-sorts imports and fixes lint issues)
  • *.{json,md,yml,yaml,mjs}prettier --write

Guidelines:

  • use lint-staged for fast local feedback
  • avoid running whole-repo ESLint in pre-commit if staged-only checks are enough
  • if full tsc:check is too slow for pre-commit, move it to pre-push or CI
  • review ignored outputs so formatters and linters do not waste time on generated artifacts

9. Define CI quality gates

A minimal CI quality job should:

  1. Install dependencies reproducibly (npm ci)
  2. npm run format:check
  3. npm run lint
  4. npm run tsc:check

Pipeline discovery strategy (IMPORTANT): always prefer integrating quality checks into an existing CI workflow rather than creating a separate one.

  1. Search for existing workflows — look in .github/workflows/ for any existing CI pipeline (e.g. playwright-e2e-tests.yml, ci.yml, test.yml, build.yml)
  2. If a main pipeline exists — add a quality job to that workflow, with the test job depending on it via needs: quality
  3. Only if NO existing pipeline is found — create a new standalone workflow (example in ./resources/example-configs.md)

Why integrate rather than separate: a single workflow gives one status check in PRs, shared triggers and concurrency reduce drift, and needs ensures tests don't waste CI minutes on code that fails basic quality checks.

CI principles:

  • use non-mutating commands only
  • do not rely solely on local hooks — CI is the authoritative gate
  • keep CI aligned with local script names
  • use permissions: contents: read for least-privilege
  • cache npm dependencies for speed
  • match the CI Node version to engines.node from package.json

10. Update documentation

Always reflect the final design in docs. At minimum, update README.md (plus audit/report docs and .vscode/settings.json recommendations when relevant).

Document clearly: required Node version, what each quality script does, whether TS formatting is checked by ESLint or Prettier CLI, how import sorting works, what Husky runs on commit, what CI runs, and what files are ignored by Prettier/ESLint and why.

11. Verify and report

After editing, verify:

  • npm run lint — passes with zero warnings
  • npm run format:check — passes
  • npm run tsc:check — passes
  • npm run lint-staged — exits cleanly (may report nothing staged)

The final report should distinguish between configuration problems, dependency problems, and code-quality violations in the current codebase.

If verification hits unexpected behavior, consult ./resources/troubleshooting.md.

Decision Rules

Prefer adding typescript directly when: tsc is invoked from package.json; the repo depends on TypeScript version stability; the current install works only because of a transitive dependency.

Prefer adding engines.node when: key tools require a newer Node version; the README requirement is vague or outdated; the project is team-shared or CI-managed.

Prefer lint-staged when: the repo uses Husky; pre-commit currently runs whole-repo checks that are unnecessarily slow; the user wants local guardrails without painful commit latency.

Prefer eslint-plugin-simple-import-sort when: setting up a new repo; migrating away from @trivago/prettier-plugin-sort-imports; the team wants clean separation of concerns; VS Code source.organizeImports is causing conflicts.

Allow @ianvs/prettier-plugin-sort-imports when: the repo already uses it and it works well; the team prefers regex-based import grouping; complex import order requirements benefit from explicit regex patterns.

Avoid @trivago/prettier-plugin-sort-imports in new projects because: it uses a Babel-based parser (slower, less TypeScript-aware); it has no Prettier 4 support; it conflicts with VS Code's source.organizeImports; @ianvs/prettier-plugin-sort-imports is a strictly better fork.

Prefer separate Prettier CLI over eslint-plugin-prettier when: setting up a new repo; performance and simplicity matter; the team wants the current mainstream recommendation from Prettier docs.

Allow eslint-plugin-prettier when: the repo already uses it intentionally; it is part of a documented TS/non-TS split; changing the model would create unnecessary churn right now.

Prefer a CI workflow when: the repo is team-shared; quality enforcement should not depend on individual developer hooks; the project uses pull requests; even for solo projects, CI catches hook-bypass scenarios (--no-verify).

Quick Setup from Scratch

For setting up a new Playwright + TypeScript project with full static analysis:

# 1. Initialize and install core dependencies
npm init -y
npm install -D @playwright/test typescript

# 2. Install static analysis tools (latest stable versions)
npm install -D eslint @eslint/js typescript-eslint globals
npm install -D prettier eslint-config-prettier eslint-plugin-prettier
npm install -D eslint-plugin-simple-import-sort
npm install -D eslint-plugin-playwright
npm install -D husky lint-staged

# 3. Initialize Husky
npx husky init

# 4. Create config files using ./resources/example-configs.md:
#    eslint.config.mjs, .prettierrc.json, .prettierignore, tsconfig.json,
#    .husky/pre-commit, .vscode/settings.json, .vscode/extensions.json

# 5. Add quality scripts to package.json (see ./resources/example-configs.md)

# 6. CI quality gate:
#    - If .github/workflows/ already has a CI pipeline → add a quality job there
#    - If no pipeline exists → create a standalone quality workflow

# 7. Verify
npm run lint
npm run format:check
npm run tsc:check

Completion Checklist

A task using this skill is complete when:

  • [ ] Dependency declarations are explicit (no transitive reliance)
  • [ ] Script names are clear and consistent
  • [ ] check:ci exists as a non-mutating aggregate command
  • [ ] Formatting responsibility is understandable and documented
  • [ ] Import sorting is handled by ESLint, not Prettier plugins
  • [ ] typescript and Node requirements are documented in engines
  • [ ] Husky and lint-staged are aligned
  • [ ] A CI quality job exists (integrated into an existing workflow, or standalone only when none exists)
  • [ ] .vscode/settings.json does not have source.organizeImports conflicting with ESLint import sorting
  • [ ] Docs (README.md) match the actual setup
  • [ ] Verification results are recorded (lint, format:check, tsc:check all pass)

Resource Map

  • ./resources/example-configs.md - baseline eslint.config.mjs, package.json scripts, tsconfig, Prettier, Husky, VS Code, and CI workflow examples
  • ./resources/import-sorting.md - import sorting rationale, decision tree, and migration guides
  • ./resources/troubleshooting.md - symptoms, causes, and fixes for common setup problems

Related Skills

  • code-review-advanced - when the static-analysis audit should be paired with a code-level review
  • tech-debt-analysis - when lint/type findings should feed a broader debt assessment
  • creating-instructions - when the resulting conventions should become instruction files

Definition of Done

This skill is complete when:

  • the current architecture is classified (Model A/B/C) before any edits
  • dependencies, scripts, tsconfig, hooks, and CI follow the decision rules above
  • import sorting is ESLint-based or an intentional documented exception
  • all verification commands pass and results are reported
  • documentation matches the final setup

Example prompts

  • /static-code-analysis-typescript review this repo and standardize eslint, typescript, husky, lint-staged, and CI scripts
  • /static-code-analysis-typescript create a modern static analysis setup for a Node + TypeScript test repository
  • /static-code-analysis-typescript explain whether TS formatting should be handled by eslint-plugin-prettier or prettier --check in this project
  • /static-code-analysis-typescript migrate from @trivago/prettier-plugin-sort-imports to eslint-plugin-simple-import-sort
  • /static-code-analysis-typescript add a CI quality gate workflow for GitHub Actions
  • /static-code-analysis-typescript set up import sorting for a Playwright project