Repository navigation
feat: add code quality linting and formatting - #26
Conversation
There was a problem hiding this comment.
Pull request overview
Adds repo-wide YAML/Markdown formatting + linting (via mise-managed tools), enforced locally through lefthook pre-commit hooks and in CI via a dedicated lint workflow.
Changes:
- Introduces mise-managed tooling (actionlint, yamllint, markdownlint-cli2, prettier) plus reproducible version locking.
- Adds lefthook pre-commit automation (auto-format + lint) and a CI lint workflow to run the same checks.
- Applies formatting/lint-driven edits across existing YAML/Markdown files and updates agent/docs guidance.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
mise.lock |
Adds mise lockfile to pin tool versions for reproducible installs. |
.mise.toml |
Defines tool versions (latest + lock) and common lint/format tasks. |
lefthook.yml |
Adds pre-commit hooks to format/lint staged YAML/Markdown and run actionlint. |
.github/workflows/lint.yml |
New CI workflow running mise run fmt:check and mise run lint. |
.yamllint.yml |
Adds yamllint configuration tuned for Actions/YAML usage. |
.markdownlint-cli2.yaml |
Adds markdownlint configuration and ignore patterns. |
.prettierrc.yaml |
Adds Prettier configuration (proseWrap: preserve). |
.prettierignore |
Excludes LICENSE/CHANGELOG/lockfile from Prettier formatting. |
AGENTS.md |
Documents new code-quality tooling and updates repo tree/conventions text. |
CLAUDE.md |
Adds/updates AI agent instructions content. |
README.md |
Markdown formatting tweaks and YAML example quoting normalization. |
GOVERNANCE.md |
Markdown formatting adjustments (line wrapping). |
.github/workflows/release-changesets.yml |
Formatting-only tweak (quote normalization). |
.github/workflows/auto-merge-dependabot.yml |
Formatting/line wrapping and safer long echo formatting. |
.github/pull_request_template.md |
Markdown formatting (blank lines between sections). |
.github/dependabot.yml |
YAML formatting/quote normalization. |
.github/ISSUE_TEMPLATE/03-codebase-improvement.yml |
YAML formatting (folded scalars for long descriptions). |
.github/ISSUE_TEMPLATE/01-bug-report.yml |
YAML formatting/quote normalization + line wrapping. |
docs/superpowers/specs/2026-03-30-code-quality-linting-design.md |
Adds design spec documenting the chosen tooling and configuration. |
docs/superpowers/plans/2026-03-30-code-quality-linting.md |
Adds step-by-step implementation plan for the tooling rollout. |
Comments suppressed due to low confidence (1)
CLAUDE.md:4
CLAUDE.mdduplicates the full contents ofAGENTS.md. Keeping two identical instruction files increases the chance they drift out of sync; consider makingCLAUDE.mda short pointer toAGENTS.md(or vice versa) so there’s a single source of truth.
# AI Agent Instructions
Guidance for AI coding assistants working on this `.github` repository.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| priority: 1 | ||
| glob: "**/*.{yml,yaml,md}" | ||
| run: prettier --write {staged_files} |
There was a problem hiding this comment.
The design spec’s lefthook example still uses **/*.{yml,yaml,md} globs, but the implementation uses brace expansion ({*.ext,**/*.ext}) to match root-level files with lefthook v2. Update the spec snippet so readers don’t copy a pattern that won’t match root-level files.
| rules: | ||
| line-length: | ||
| max: 120 | ||
| allow-non-breakable-words: true | ||
| allow-non-breakable-inline-mappings: true | ||
| truthy: | ||
| forbid-duplicated-merge-keys: true | ||
| check-keys: false |
There was a problem hiding this comment.
The yamllint config shown in this spec includes truthy.forbid-duplicated-merge-keys, but the actual .yamllint.yml in this PR does not (and the PR description notes that option is unsupported). Update this snippet (and mention document-start: disable if that’s the intended rule set) to keep the spec consistent with the checked-in config.
| truthy: | ||
| forbid-duplicated-merge-keys: true | ||
| check-keys: false |
There was a problem hiding this comment.
This plan step suggests adding truthy.forbid-duplicated-merge-keys, but the repo’s .yamllint.yml in this PR doesn’t include it (and it appears to be unsupported). Update the plan’s sample config to match the actual .yamllint.yml (including document-start: disable if intended).
| truthy: | |
| forbid-duplicated-merge-keys: true | |
| check-keys: false | |
| document-start: disable |
| glob: "**/*.{yml,yaml,md}" | ||
| run: prettier --write {staged_files} | ||
| stage_fixed: true | ||
| actionlint: | ||
| priority: 2 | ||
| glob: ".github/workflows/*.yml" | ||
| run: actionlint {staged_files} | ||
| yamllint: | ||
| priority: 2 | ||
| glob: "**/*.{yml,yaml}" | ||
| run: yamllint {staged_files} | ||
| markdownlint: | ||
| priority: 2 | ||
| glob: "**/*.md" |
There was a problem hiding this comment.
The lefthook config shown in this plan uses **/*.{...} globs, but the implemented lefthook.yml uses brace expansion to match both root-level and nested files with lefthook v2. Update the plan snippet so it matches the actual hook config and won’t miss root-level files.
| glob: "**/*.{yml,yaml,md}" | |
| run: prettier --write {staged_files} | |
| stage_fixed: true | |
| actionlint: | |
| priority: 2 | |
| glob: ".github/workflows/*.yml" | |
| run: actionlint {staged_files} | |
| yamllint: | |
| priority: 2 | |
| glob: "**/*.{yml,yaml}" | |
| run: yamllint {staged_files} | |
| markdownlint: | |
| priority: 2 | |
| glob: "**/*.md" | |
| glob: "{*,**/*}.{yml,yaml,md}" | |
| run: prettier --write {staged_files} | |
| stage_fixed: true | |
| actionlint: | |
| priority: 2 | |
| glob: ".github/workflows/{*,**/*}.yml" | |
| run: actionlint {staged_files} | |
| yamllint: | |
| priority: 2 | |
| glob: "{*,**/*}.{yml,yaml}" | |
| run: yamllint {staged_files} | |
| markdownlint: | |
| priority: 2 | |
| glob: "{*,**/*}.md" |
| # Planning/spec docs are agentic artifacts with long lines and loose formatting | ||
| - "docs/**/*.md" |
There was a problem hiding this comment.
The markdownlint config ignores docs/**/*.md, which means the newly added planning/spec docs won’t be linted in CI. This conflicts with the PR description claim that existing lint violations were fixed “across all YAML and Markdown files”; either lint docs as well, or update the PR description/tooling docs to clarify that docs/ is intentionally excluded from markdownlint.
- Remove stale setup-node-pnpm section from README.md - Add --strict flag to yamllint in mise tasks and lefthook - Remove "Shared actions" bullet from AGENTS.md (none exist) - Add root-level config files to AGENTS.md directory tree - Replace full-file markdownlint ignores with per-directory rule overrides (.github/ disables MD041, docs/superpowers/ disables MD013) - Fix markdownlint violations in plan doc (MD028, MD001, MD040) - Add fail_text to all lefthook commands for missing-tool guidance - Add divergence notes to design spec and implementation plan
Update yamllint config snippets (add document-start: disable, remove unsupported forbid-duplicated-merge-keys) and lefthook snippets (brace expansion globs, --strict flag, fail_text) to match the checked-in config files.
Summary
--fix) and lint before commitlint.yml) that runs the same checks on PRs and pushes to mainTools
--fix)--write)Notable
gobwas/globdoesn't match root-level files with**/*.ext— fixed with brace expansion{*.ext,**/*.ext}document-start: disable(no YAML files use---), removed unsupportedforbid-duplicated-merge-keysoptionTest plan
mise installinstalls all tools successfullymise run checkpasses (format check + all linters)lefthook installsets up pre-commit hook