Gsd-2 lint
Lint and format code. Auto-detects ESLint, Biome, Prettier, or language-native formatters and runs them with auto-fix. Reports remaining issues with actionable suggestions.
git clone https://github.com/gsd-build/gsd-2
T=$(mktemp -d) && git clone --depth=1 https://github.com/gsd-build/gsd-2 "$T" && mkdir -p ~/.claude/skills && cp -r "$T/src/resources/skills/lint" ~/.claude/skills/gsd-build-gsd-2-lint && rm -rf "$T"
src/resources/skills/lint/SKILL.md- No arguments: Lint only files changed in the current working tree (
andgit diff --name-only
).git diff --cached --name-only - A file or directory path: Lint only that specific path (e.g.,
)./lint src/utils
: Automatically apply safe fixes. Can be combined with a path (e.g.,--fix
)./lint src/ --fix
without a path: Auto-fix changed files only.--fix
Parse the arguments before proceeding. If
--fix is present, set fix mode. If a non-flag argument is present, treat it as the target path.
</arguments>
<detection>
Auto-detect the project's linter and formatter by checking configuration files in the project root. Check in this order and use the **first match found** for each category (linter vs. formatter). A project may have both a linter and a formatter.
JavaScript/TypeScript Linters:
-
Biome — Look for
orbiome.json
in the project root.biome.jsonc- Lint command:
(ornpx @biomejs/biome check .
with--apply
)--fix - Format command:
(ornpx @biomejs/biome format .
with--write
)--fix - Biome handles both linting and formatting. No need for a separate formatter if Biome is detected.
- Lint command:
-
ESLint — Look for
,.eslintrc
(js, cjs, json, yml, yaml),.eslintrc.*
(js, mjs, cjs, ts, mts, cts), or aneslint.config.*
key in"eslintConfig"
.package.json- Lint command:
(ornpx eslint .
with--fix
)--fix - Check
for the installed version. ESLint 9+ uses flat config (package.json
).eslint.config.*
- Lint command:
JavaScript/TypeScript Formatters (only if Biome was NOT detected):
- Prettier — Look for
,.prettierrc
,.prettierrc.*
, or aprettier.config.*
key in"prettier"
.package.json- Format check:
npx prettier --check . - Format fix:
npx prettier --write .
- Format check:
Rust:
- rustfmt — Look for
orrustfmt.toml
, or.rustfmt.toml
in the project root.Cargo.toml- Format check:
cargo fmt -- --check - Format fix:
cargo fmt - Lint:
(if available)cargo clippy
- Format check:
Go:
- Go tools — Look for
in the project root.go.mod- Format check:
gofmt -l . - Format fix:
gofmt -w . - Lint:
(if installed), otherwisegolangci-lint rungo vet ./...
- Format check:
Python:
-
Ruff — Look for
or aruff.toml
section in[tool.ruff]
.pyproject.toml- Lint command:
(orruff check .
with--fix
)--fix - Format command:
(orruff format .
without--check
)--fix
- Lint command:
-
Black — Look for a
section in[tool.black]
, orpyproject.toml
in requirements files.black- Format check:
black --check . - Format fix:
black .
- Format check:
If no linter or formatter is detected, inform the user and suggest common options for their project type based on the files present. </detection>
<execution>Step 1: Determine target files
- If a path argument was provided, use that path.
- If no path argument, get changed files:
Filter to files that still exist on disk. If no files are changed, inform the user and offer to lint the entire project instead.git diff --name-only git diff --cached --name-only
Step 2: Run the detected tools
Run the linter and/or formatter against the target files or directory.
- Without
: Run in check/report mode only. Do NOT modify any files.--fix - With
: Run with auto-fix flags enabled.--fix
When running formatters without
--fix, show a preview of what would change:
- For Prettier: use
and list files that would change.--check - For Biome: use
withoutcheck
.--apply - For Black: use
to show the diff preview.--check --diff - For Ruff: use
for format and standard output for lint.--diff - For rustfmt/gofmt: use
or--check
to list files, then show a diff for up to 5 files using-l
.diff <(command) file
Step 3: Parse and organize output
Parse the tool output and organize issues:
## Lint Results ### Errors (X issues) | File | Line | Rule | Message | |------|------|------|---------| | ... | ... | ... | ... | ### Warnings (X issues) | File | Line | Rule | Message | |------|------|------|---------| | ... | ... | ... | ... | ### Formatting - X files would be reformatted - [list files] ### Summary - Total issues: X errors, Y warnings, Z formatting - Auto-fixable: N issues (run `/lint --fix` to apply)
Step 4: Suggest fixes for common issues
For the most frequent issues, provide brief actionable guidance:
- If the same rule appears 5+ times, suggest a bulk fix or config change.
- For unused imports/variables, list them for quick removal.
- For formatting-only issues, note that
will resolve them safely.--fix - For issues that cannot be auto-fixed, provide a one-line explanation of how to resolve each unique rule violation.
<critical_rules>
- Never modify files without
: Default mode is report-only. Respect the user's working tree.--fix - Use the project's own config: Do not invent lint rules. Use whatever config files exist in the project.
- Use the project's installed version: Always prefer
,npx
, or the project-local binary. Do not use globally installed tools unless no local version exists.cargo - Handle missing tools gracefully: If a config file exists but the tool is not installed, inform the user and provide the install command (e.g.,
).npm install --save-dev eslint - Respect
and ignore patterns: Do not lint.gitignore
,node_modules
,dist
,build
,target
, or other commonly ignored directories. Most tools handle this automatically; verify they do..git - Limit output: If there are more than 50 issues, show the first 30 grouped by severity, then summarize the rest with counts per file. Do not flood the user with hundreds of lines.
- Exit cleanly: After presenting results, do not take further action. Let the user decide next steps.
</critical_rules>