diff --git a/.github/config/super-linter.env b/.github/config/super-linter.env index 3f7678d..fcaff22 100644 --- a/.github/config/super-linter.env +++ b/.github/config/super-linter.env @@ -12,7 +12,6 @@ VALIDATE_JSONC=true VALIDATE_MARKDOWN=true VALIDATE_MARKDOWN_PRETTIER=true VALIDATE_NATURAL_LANGUAGE=true -VALIDATE_PYTHON_ISORT=true VALIDATE_PYTHON_RUFF=true VALIDATE_PYTHON_RUFF_FORMAT=true VALIDATE_SHELL_SHFMT=true diff --git a/.textlintrc b/.textlintrc new file mode 100644 index 0000000..5070696 --- /dev/null +++ b/.textlintrc @@ -0,0 +1,8 @@ +{ + "filters": { + "comments": true + }, + "rules": { + "terminology": true + } +} diff --git a/AGENTS.md b/AGENTS.md index 56f5c9d..446aac8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -108,10 +108,10 @@ This ensures all files pass CI linting (Biome formatting, shellcheck, etc.). Review the auto-fixed files before committing — auto-fixes may produce unexpected results. -A pre-commit hook can automate this — run -`mise run setup:pre-commit-hook` once per clone to install -it. The hook runs native linters with autofix on every -commit. +Linting can be automated via a Git pre-commit hook or an +agent-specific hook (e.g. a Claude Code `PreToolUse` hook +that intercepts `git push`). Use whichever fits your +workflow — both are optional. To install the Git hook: ```bash # Auto-fix and verify (recommended dev workflow) @@ -120,7 +120,7 @@ mise run fix # Verify only (same command used in CI) mise run lint -# Install pre-commit hook (one-time setup) +# Install git pre-commit hook (one-time, opt-in) mise run setup:pre-commit-hook ``` @@ -145,9 +145,10 @@ standard locations (project root), not in `.github/linters/` (super-linter's convention). The script errors if `.github/linters/` exists. All supported linters auto-discover their config: +`textlint`→`.textlintrc`, `shellcheck`→`.shellcheckrc`, `markdownlint`→`.markdownlint.json`, -`editorconfig-checker`→`.ecrc`, +`ec` (editorconfig-checker)→`.ecrc`, `actionlint`→`.github/actionlint.yml`, `hadolint`→`.hadolint.yaml`, `golangci-lint`→`.golangci.yml`, diff --git a/mise.toml b/mise.toml index 075d3b8..9615cb3 100644 --- a/mise.toml +++ b/mise.toml @@ -13,11 +13,6 @@ SUPER_LINTER_VERSION="slim-v8.5.0@sha256:857dcc3f0bf5dd065fdeed1ace63394bb200423 description = "Run Super-Linter on the repository" file = "tasks/lint/super-linter.sh" -[tasks."lint:super-linter-native"] -description = "Run linters natively (fast, for local dev)" -depends = ["setup:native-lint-tools"] -run = [{ task = "lint:super-linter", env = { NATIVE = "true" } }] - [tasks."setup:native-lint-tools"] description = "Install native lint tools matching the pinned super-linter version" file = "tasks/setup/native-lint-tools.sh" diff --git a/super-linter-versions/v8.4.0.toml b/super-linter-versions/v8.4.0.toml index da811e9..9ac66b8 100644 --- a/super-linter-versions/v8.4.0.toml +++ b/super-linter-versions/v8.4.0.toml @@ -13,6 +13,8 @@ hadolint = "v2.14.0" "npm:markdownlint-cli" = "0.47.0" "npm:prettier" = "3.8.1" "npm:@biomejs/biome" = "2.3.13" +"npm:textlint" = "15.5.1" +"npm:textlint-rule-terminology" = "5.2.16" "pipx:ruff" = "0.14.14" "pipx:codespell" = "2.4.1" editorconfig-checker = "v3.6.0" diff --git a/super-linter-versions/v8.5.0.toml b/super-linter-versions/v8.5.0.toml index c73d409..c1833cc 100644 --- a/super-linter-versions/v8.5.0.toml +++ b/super-linter-versions/v8.5.0.toml @@ -13,6 +13,8 @@ hadolint = "v2.14.0" "npm:markdownlint-cli" = "0.47.0" "npm:prettier" = "3.8.1" "npm:@biomejs/biome" = "2.3.14" +"npm:textlint" = "15.5.1" +"npm:textlint-rule-terminology" = "5.2.16" "pipx:ruff" = "0.15.0" "pipx:codespell" = "2.4.1" editorconfig-checker = "v3.6.1" diff --git a/tasks/lint/super-linter.sh b/tasks/lint/super-linter.sh index e7102c3..968ebf0 100755 --- a/tasks/lint/super-linter.sh +++ b/tasks/lint/super-linter.sh @@ -55,15 +55,29 @@ ENV_FILE="${SUPER_LINTER_ENV_FILE:-.github/config/super-linter.env}" # --- Native mode --- if [ "$NATIVE" = "true" ]; then - # Activate the mise environment created by setup:native-lint-tools so that - # installed tools (shfmt, actionlint, codespell, etc.) are on PATH. + # Activate the mise environment so installed tools are on PATH. + # The .mise.super-linter-*.toml is created by setup:native-lint-tools. + # In worktrees it won't exist — create it from the tracked version mapping. _SL_ENV_TOML=$(compgen -G ".mise.super-linter-*.toml" | head -1 || true) + if [ -z "$_SL_ENV_TOML" ] && [ -n "${SUPER_LINTER_VERSION:-}" ]; then + _SL_TAG="${SUPER_LINTER_VERSION#slim-}" + _SL_TAG="${_SL_TAG%%@*}" + _SL_VERSION_TOML="super-linter-versions/${_SL_TAG}.toml" + if [ -f "$_SL_VERSION_TOML" ]; then + _SL_ENV_TOML=".mise.super-linter-${_SL_TAG}.toml" + cp "$_SL_VERSION_TOML" "$_SL_ENV_TOML" + mise trust "$_SL_ENV_TOML" + fi + fi if [ -n "$_SL_ENV_TOML" ]; then _SL_ENV_NAME="${_SL_ENV_TOML#.mise.}" _SL_ENV_NAME="${_SL_ENV_NAME%.toml}" - # Allow failure so the script falls through to the "Missing native lint tools" - # message instead of exiting with a confusing mise error. - eval "$(mise env -E "$_SL_ENV_NAME" 2>/dev/null)" || true + _SL_ENV_OUTPUT=$(mise env -E "$_SL_ENV_NAME") || { + echo "Error: failed to activate mise environment '$_SL_ENV_NAME'." >&2 + echo "Run 'mise run setup:native-lint-tools' to install tools." >&2 + exit 1 + } + eval "$_SL_ENV_OUTPUT" fi # Native mode expects linter configs at the project root (standard tool locations). @@ -168,12 +182,13 @@ if [ "$NATIVE" = "true" ]; then "VALIDATE_MARKDOWN_PRETTIER|prettier|prettier --check {FILE}|prettier --write {FILE}|*.md" "VALIDATE_YAML_PRETTIER|prettier|prettier --check {FILE}|prettier --write {FILE}|*.yaml *.yml" "VALIDATE_JSON_PRETTIER|prettier|prettier --check {FILE}|prettier --write {FILE}|*.json" - "VALIDATE_EDITORCONFIG|editorconfig-checker|editorconfig-checker {FILES}||*" + "VALIDATE_EDITORCONFIG|ec|ec {FILES}||*" "VALIDATE_GITHUB_ACTIONS|actionlint|actionlint {FILE}||.github/workflows/*.yml .github/workflows/*.yaml" "VALIDATE_DOCKERFILE_HADOLINT|hadolint|hadolint {FILE}||Dockerfile Dockerfile.* *.dockerfile" "VALIDATE_GO_GOLANGCI_LINT|golangci-lint|golangci-lint run||SELF" "VALIDATE_PYTHON_RUFF|ruff|ruff check {FILE}|ruff check --fix {FILE}|*.py" "VALIDATE_PYTHON_RUFF_FORMAT|ruff|ruff format --check {FILE}|ruff format {FILE}|*.py" + "VALIDATE_NATURAL_LANGUAGE|textlint|textlint {FILE}||*.md *.txt" "VALIDATE_SPELL_CODESPELL|codespell|codespell {FILES}|codespell --write-changes {FILES}|*" "VALIDATE_JSONC|biome|biome check {FILE}|biome check --fix {FILE}|*.json *.jsonc *.js *.ts *.jsx *.tsx" "VALIDATE_BIOME_FORMAT|biome|biome format {FILE}|biome format --write {FILE}|*.json *.jsonc *.js *.ts *.jsx *.tsx" diff --git a/tasks/setup/update-super-linter-versions.sh b/tasks/setup/update-super-linter-versions.sh index c213b0b..1f56046 100755 --- a/tasks/setup/update-super-linter-versions.sh +++ b/tasks/setup/update-super-linter-versions.sh @@ -60,6 +60,8 @@ golangci_lint=$(_from_version "golangci/golangci-lint") markdownlint=$(_npm_version "markdownlint-cli") prettier=$(_npm_version "prettier") biome=$(_npm_version "@biomejs/biome") +textlint=$(_npm_version "textlint") +textlint_terminology=$(_npm_version "textlint-rule-terminology") ruff=$(_pip_version "ruff") codespell=$(_pip_version "codespell") @@ -83,6 +85,8 @@ hadolint = "${hadolint}" "npm:markdownlint-cli" = "${markdownlint}" "npm:prettier" = "${prettier}" "npm:@biomejs/biome" = "${biome}" +"npm:textlint" = "${textlint}" +"npm:textlint-rule-terminology" = "${textlint_terminology}" "pipx:ruff" = "${ruff}" "pipx:codespell" = "${codespell}" editorconfig-checker = "${editorconfig_checker}"