plugins/static-code-analysis-typescript/skills/static-code-analysis-typescript/SKILL.md
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.
npx skillsauth add jaktestowac/awesome-copilot-for-testers static-code-analysis-typescriptInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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-eslinttypescripttsconfig.jsonprettiereslint-plugin-simple-import-sort (import sorting via ESLint)huskylint-stagedpackage.json scriptsUse this skill when the user asks things like:
This skill should help produce a setup that is:
package.json, README.md, and the config filesA strong baseline should usually include:
eslint.config.mjs)typescript-eslint for TypeScript-aware lintingtypescript dependency when tsc is used directlytsconfig.jsoneslint-plugin-simple-import-sort)husky hook for local guardrailslint-staged for staged-file workflowspackage.json#enginesConcrete baseline files (eslint.config.mjs, package.json scripts, tsconfig, Prettier, Husky, VS Code settings, CI workflows) live in ./resources/example-configs.md.
Check at least these files when they exist:
package.jsoneslint.config.* (or legacy .eslintrc*)tsconfig.json.prettierrc*.prettierignore.husky/*.github/workflows/*.vscode/settings.json.vscode/extensions.jsonREADME.mdIdentify:
typescript is direct or transitivetsc is used as a real gateprettier is standalone, inside ESLint, or split by file typesource.organizeImports could conflict with other import sortingChoose the current model before editing anything:
prettier --check used directly; eslint-config-prettier avoids rule conflicts.eslint-plugin-prettier runs formatting checks inside ESLint, often paired with a separate Prettier CLI check for non-TS files.When possible, make the final state explicit in docs so the split is understandable.
For TypeScript repositories, prefer these principles:
tsc, add typescript directly in devDependenciestypescript-eslint is installed, ensure versions are compatible with ESLint and TypeScriptpackage.json#enginesTypical 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-playwrightplaywright-report/** and test-results/**Check how imports are currently sorted:
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 separationeslint-plugin-simple-import-sort → already optimaleslint-plugin-perfectionist → acceptable if broader sorting rules are wantedsource.organizeImports → remove if any other import sorting tool is active; it conflictsRationale, 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.
package.jsonPrefer predictable script names:
lint → runs ESLint in non-fix mode and should fail on warnings if that is the chosen policyformat → mutating formatter run, usually prettier --writeformat:check → non-mutating formatting validationtsc:check → tsc --noEmitcheck → aggregate quality command (local, may mutate)check:ci → aggregate quality command (CI, non-mutating)lint-staged → entrypoint for staged-file validationGuidelines:
check (local, with --write) and check:ci (CI, with --check)format:check and format:check:non-tsMake one of the following explicit:
eslint-config-prettier disables formatting-conflicting lint rules.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.
For tsconfig.json, prefer:
strict: truemodule: "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_modulesnoEmit: true when TypeScript is used only for type checkingbaseUrl / paths only when justifiedCommon 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.
Recommended pattern:
lint-staged handles staged-file formatting and fixable lint checks (including import sorting)tsc:check may still run in pre-commit or pre-push, depending on repo size and tolerance for slower hooksGood staged-file mapping examples:
*.ts → prettier --write, eslint --fix (auto-sorts imports and fixes lint issues)*.{json,md,yml,yaml,mjs} → prettier --writeGuidelines:
lint-staged for fast local feedbacktsc:check is too slow for pre-commit, move it to pre-push or CIA minimal CI quality job should:
npm ci)npm run format:checknpm run lintnpm run tsc:checkPipeline discovery strategy (IMPORTANT): always prefer integrating quality checks into an existing CI workflow rather than creating a separate one.
.github/workflows/ for any existing CI pipeline (e.g. playwright-e2e-tests.yml, ci.yml, test.yml, build.yml)quality job to that workflow, with the test job depending on it via needs: quality./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:
permissions: contents: read for least-privilegenpm dependencies for speedengines.node from package.jsonAlways 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.
After editing, verify:
npm run lint - passes with zero warningsnpm run format:check - passesnpm run tsc:check - passesnpm 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.
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).
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
A task using this skill is complete when:
check:ci exists as a non-mutating aggregate commandtypescript and Node requirements are documented in engineslint-staged are aligned.vscode/settings.json does not have source.organizeImports conflicting with ESLint import sortingREADME.md) match the actual setuplint, format:check, tsc:check all pass)./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 problemscode-review-advanced - when the static-analysis audit should be paired with a code-level reviewtech-debt-analysis - when lint/type findings should feed a broader debt assessmentcreating-instructions - when the resulting conventions should become instruction filesThis skill is complete when:
/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 projecttesting
Tests the customization assets themselves - skills, prompts, custom agents, instructions - the way a product is tested: activation cases that check an asset fires when it should and stays quiet when it should not, output-contract cases, safety cases, collision cases between assets competing for the same trigger, a weighted rubric scored blind, and a baseline-versus-candidate gate before an edit ships. Use when a skill is edited and nobody knows whether behaviour changed, when two skills fight over the same request, when a description is being tuned for discoverability, when a collection has grown past manual spot-checking, or when the request mentions skill evals, prompt regression, or "does this skill actually work".
development
Shapes QA output for the person who has to act on it: result and blocker in the first two lines, one decision per report, findings ordered by what they cost, the long artifact in a file and the decisions in the message, and magnitude stated in units the reader can count. Use when a report is accurate but nobody acts on it, when a finding set is too long to read under time pressure, when the same findings must be retold for a developer, a release manager, and an on-call engineer, or when the request mentions "too long", "make this readable", "just tell me what to do", "so what", or "summarize this for stakeholders". Pairs with unslop-answers, which makes the same report honest.
testing
Verifies that the lines and branches a change actually touched are executed by tests, using LCOV or Cobertura diff coverage instead of whole-repo percentages, and escalates uncovered high-risk changes into a blocking finding. Use when a pull request needs a coverage gate that unrelated tests cannot satisfy, when total coverage looks healthy but the diff is untested, when wiring diff coverage into CI, or when someone claims a change is covered because the suite is green.
development
Cuts AI tells from test code: tests that pass without proving anything, tautological assertions, mock-only tests, hardcoded waits, coverage theater, vague names, swallowed errors, retries used as fixes. Use whenever test code is written, changed, or reviewed, including tests produced as a side effect of a feature task, and when the request mentions "review these tests", "are these tests any good", "this test always passes", "this suite is flaky", or "clean up these tests". Must always apply to test code.