Skip to content

chore: Add Husky pre-commit hook for automatic code formatting (Vibe Kanban) - #76

Merged
gabrypavanello merged 2 commits into
mainfrom
vk/d9d6-create-a-pre-com
Jan 9, 2026
Merged

chore: Add Husky pre-commit hook for automatic code formatting (Vibe Kanban)#76
gabrypavanello merged 2 commits into
mainfrom
vk/d9d6-create-a-pre-com

Conversation

@gabe4coding

@gabe4coding gabe4coding commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds a pre-commit hook using Husky and lint-staged to automatically format staged files before each commit, ensuring consistent code style across the project.

Changes

  • Added Husky (^9.1.7) for Git hooks management
  • Added lint-staged (^16.2.7) to run formatters only on staged files
  • Created .husky/pre-commit hook with:
    • Proper shebang (#!/usr/bin/env sh) for cross-platform compatibility
    • Error handling (set -e) to abort commit on formatter errors
    • Runs npx lint-staged to format only staged files
  • Added prepare script to package.json for automatic Husky installation
  • Configured lint-staged to run Prettier on *.{ts,tsx,js,jsx,json,md,yml,yaml} files

Why

Previously, code formatting was a manual step that contributors had to remember to run. This could lead to:

  • Inconsistent formatting across commits
  • CI failures due to formatting issues
  • Extra round-trips to fix formatting after code review

With this pre-commit hook, formatting is now automatic and enforced for staged files only.

Implementation Details

  • Uses lint-staged (industry standard) instead of formatting the entire codebase
  • Only formats files that are being committed, making commits fast
  • Proper error handling ensures commits fail if Prettier encounters errors
  • Developers can bypass with git commit --no-verify if needed

This PR was written using Vibe Kanban

1. **Installed Husky** (`^9.1.7`) as a dev dependency
2. **Created `.husky/pre-commit`** hook that:
   - Runs `pnpm format:write` to auto-format code
   - Runs `git add -u` to stage the formatted changes
3. **Added `prepare` script** to `package.json` so Husky installs automatically after `pnpm install`

Now every commit will automatically format the code with Prettier before committing.
@coderabbitai

coderabbitai Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Summary by CodeRabbit

  • Chores

    • Added Husky pre-commit hook and a prepare script to enable git hook setup.
    • Configured lint-staged to auto-run Prettier on staged files before commits.
  • Documentation

    • Enabled docs generation watch mode for live-reload during documentation development.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds Husky pre-commit hook and lint-staged integration; introduces a prepare script in package.json and updates scripts. A new .husky/pre-commit file runs npx lint-staged. A top-level lint-staged config mapping file patterns to prettier --write was added.

Changes

Cohort / File(s) Change Summary
Husky pre-commit hook
.husky/pre-commit
New hook file added; executes npx lint-staged on commit.
Package manifest & tooling
package.json
Added prepare script (husky), added lint-staged and husky devDependencies, ensured typedoc and typedoc-plugin-markdown present, updated docs:watch script to include --watch, and added top-level lint-staged mapping to prettier --write.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding a Husky pre-commit hook for automatic code formatting.
Description check ✅ Passed The description is directly related to the changeset, providing comprehensive details about the Husky and lint-staged configuration changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@gabe4coding gabe4coding changed the title Create a pre-commit hook to always run pnpm format:write (vibe-kanban) chore: Add Husky pre-commit hook for automatic code formatting (Vibe Kanban) Jan 9, 2026
@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Code Review: Pre-commit Hook for Automatic Formatting

Summary

This PR adds a Husky pre-commit hook to automatically run pnpm format:write before every commit. While the intention is good (ensuring consistent formatting), there are several concerns with the current implementation.


🔴 Critical Issues

1. Missing Shebang in Hook Script

The .husky/pre-commit file is missing a shebang line, which could cause execution issues on some systems.

Current:

pnpm format:write
git add -u

Should be:

#!/usr/bin/env sh
pnpm format:write
git add -u

2. Unsafe git add -u Command

Using git add -u stages all tracked file modifications, not just the ones formatted by prettier. This is dangerous because:

  • It stages unrelated changes the developer may not want to commit
  • It breaks the principle of atomic commits
  • It can lead to accidentally committing work-in-progress code

Recommendation: Only stage files that were actually modified by prettier:

#!/usr/bin/env sh
pnpm format:write
git add -A

Or better yet, use a tool like lint-staged to only format staged files:

{
  "devDependencies": {
    "lint-staged": "^15.0.0"
  },
  "lint-staged": {
    "*.{ts,tsx,js,jsx,json,md}": "prettier --write"
  }
}

Then the hook becomes:

#!/usr/bin/env sh
npx lint-staged

3. No Error Handling

The hook doesn't check if pnpm format:write succeeds. If prettier fails (e.g., syntax errors), the commit will still proceed.

Recommendation:

#!/usr/bin/env sh
set -e  # Exit on any error
pnpm format:write
git add -A

⚠️ Design Concerns

4. Performance Impact

Running pnpm format:write formats the entire codebase on every commit, which:

  • Slows down the commit process significantly in large repos
  • Formats files the developer didn't touch
  • Creates large diffs with unrelated formatting changes

Better approach: Use lint-staged to only format files that are being committed.

5. Developer Experience

Auto-formatting all files can be intrusive:

  • Developers may want to commit code that's intentionally not formatted (e.g., debugging, WIP commits)
  • It prevents quick commits during development
  • No way to bypass without --no-verify (which disables all hooks)

Recommendation: Consider making this opt-in via a flag or using lint-staged for a more surgical approach.

6. Redundancy with CI

The PR check workflow already validates formatting:

- name: Check formatting
  run: pnpm format

Having both a pre-commit hook AND CI check means:

  • The CI check becomes redundant if the hook works
  • If developers bypass the hook (--no-verify), CI will still catch issues
  • This creates confusion about which layer is authoritative

Recommendation: Either rely on the hook OR CI, not both. Most projects use CI as the source of truth and hooks as a developer convenience.


✅ Positive Aspects

  1. Correct Husky Setup: The "prepare": "husky" script is correctly added to initialize Husky on pnpm install
  2. Proper Dependency Management: Husky is added to devDependencies with a specific version
  3. Lock File Update: pnpm-lock.yaml is correctly updated

📋 Recommendations

Option A: Use lint-staged (Recommended)

This is the industry standard approach:

  1. Install lint-staged:
pnpm add -D lint-staged
  1. Update package.json:
{
  "lint-staged": {
    "*.{ts,tsx,js,jsx,json,md,yml,yaml}": "prettier --write"
  }
}
  1. Update .husky/pre-commit:
#!/usr/bin/env sh
npx lint-staged

Option B: Keep Current Approach (Not Recommended)

If you must keep the current approach, fix the critical issues:

#!/usr/bin/env sh
set -e
pnpm format:write
git add -A

And document in the README that developers can use git commit --no-verify to bypass if needed.


🔒 Security Considerations

No security issues identified. The hook only runs local commands and doesn't interact with external services.


🧪 Testing Recommendations

Before merging, test:

  1. ✅ Hook runs on git commit
  2. ✅ Hook properly stages formatted files
  3. ✅ Hook fails commit if formatter finds errors
  4. git commit --no-verify bypasses hook
  5. ✅ Fresh clone + pnpm install initializes hooks correctly

📊 Test Coverage

No new code requiring tests. However, consider adding a test in CI to verify hooks are installed:

- name: Verify hooks are installed
  run: test -f .husky/pre-commit

Final Verdict

Request Changes - The current implementation has unsafe behavior (git add -u) and poor performance (formats entire codebase). I strongly recommend switching to lint-staged for a more robust and developer-friendly solution.

If you have questions about the recommendations, happy to discuss! 🙂

**Changes made:**

1. **Added shebang and error handling** to `.husky/pre-commit`:
   ```sh
   #!/usr/bin/env sh
   set -e
   npx lint-staged
   ```

2. **Installed `lint-staged`** (`^16.2.7`) - the industry standard for running linters on staged files only

3. **Added `lint-staged` configuration** to `package.json`:
   ```json
   "lint-staged": {
     "*.{ts,tsx,js,jsx,json,md,yml,yaml}": "prettier --write"
   }
   ```

**Benefits of this approach:**
- Only formats files that are being committed (not the entire codebase)
- Much faster commits
- No unsafe `git add -u` that could stage unrelated changes
- Proper error handling with `set -e`
- Correct shebang for cross-platform compatibility
@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Code Review - PR #76: Add Husky Pre-commit Hook

Summary

This PR adds automated code formatting via Husky pre-commit hooks using lint-staged. The implementation is solid and follows modern best practices, but there are a few important discrepancies and considerations to address.


🔴 Critical Issue: Implementation vs Description Mismatch

The PR description does NOT match the actual implementation:

Description claims:

  • Runs pnpm format:write to auto-format all files
  • Runs git add -u to stage formatted changes

Actual implementation (.husky/pre-commit:3):

npx lint-staged

What's actually happening:

  • The hook runs lint-staged which only formats staged files matching the pattern in package.json:61-63
  • Pattern: *.{ts,tsx,js,jsx,json,md,yml,yaml}
  • lint-staged automatically stages the formatted files (no manual git add -u needed)

Impact: This is actually better than described because:
✅ Only formats files in the commit (faster, more focused)
✅ Doesn't reformat the entire codebase on every commit
✅ Follows lint-staged best practices

Recommendation: Update the PR description to accurately reflect the lint-staged implementation.


✅ Strengths

  1. Modern tooling: Husky v9 + lint-staged is the industry standard approach
  2. Proper configuration: The lint-staged config in package.json:61-63 has good file coverage
  3. Automatic setup: The prepare script ensures Husky installs on pnpm install
  4. Existing CI integration: The PR check workflow already runs pnpm format (package.json:36-37), so this catches issues pre-commit
  5. Clean dependencies: Both husky (^9.1.7) and lint-staged (^16.2.7) are up-to-date versions

⚠️ Considerations

1. Performance on Large Commits

lint-staged runs Prettier on all staged files. For commits with 50+ files, this could add 5-10 seconds. This is generally acceptable, but worth monitoring.

Mitigation: Already optimal - only formats staged files, not the entire codebase.

2. Contributor Friction

Some developers prefer to commit "dirty" code and clean it up later in the workflow. Pre-commit hooks can be bypassed with:

git commit --no-verify

Recommendation: Document this in CONTRIBUTING.md:37-40 (which already mentions pnpm format:write). Consider adding:

## Code style

- Formatting is automatically enforced via pre-commit hooks
- To bypass hooks (not recommended): `git commit --no-verify`
- Manual formatting: `pnpm format:write`

3. Monorepo Considerations

The hook runs at the repo root, which is correct for this Nx monorepo. The lint-staged config applies uniformly across all packages.

Status: ✅ Correct implementation for the monorepo structure.

4. Windows Compatibility

The shebang #!/usr/bin/env sh (.husky/pre-commit:1) works on Windows with Git Bash, which is standard with Git for Windows.

Status: ✅ Compatible across platforms.


🔒 Security Review

No security concerns. The dependencies are legitimate:

  • husky@^9.1.7: 40M+ weekly downloads, maintained by typicode
  • lint-staged@^16.2.7: 8M+ weekly downloads, well-established tool

The hook only runs local Prettier formatting - no external network calls or dangerous operations.


🧪 Test Coverage

No new tests needed. This is infrastructure code, and the existing CI workflow already validates formatting (pr-check.yml:36-37).

Validation approach:

  1. CI enforces formatting on PR checks
  2. Pre-commit hook catches issues earlier (better DX)
  3. If the hook fails, CI will catch it as a backup

📝 Suggested Improvements (Non-Blocking)

  1. Update PR description to match the actual lint-staged implementation
  2. Update CONTRIBUTING.md to mention the automatic pre-commit hooks
  3. Consider adding a .lintstagedrc.js for more complex configurations if needed in the future (current inline config is fine for now)

🎯 Final Verdict

✅ APPROVE with minor documentation updates

Rationale:

  • Implementation is technically sound and follows best practices
  • Improves code quality and reduces CI failures
  • Low risk, high value addition
  • Only issue is documentation accuracy (PR description)

Action items before merge:

  1. Update PR description to accurately describe the lint-staged implementation
  2. (Optional but recommended) Update CONTRIBUTING.md to document the pre-commit hooks

Overall Assessment: This is a valuable addition that will improve the developer experience and maintain code consistency. The implementation is better than the description suggests! 🚀

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.husky/pre-commit (1)

1-2: Optional: avoid formatting the entire repo on every commit (performance + surprise diffs).

pnpm format:write runs Prettier over .; that can be slow and can stage unrelated formatting changes via git add -u. Consider switching to staged-file formatting (e.g., lint-staged).

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba1ec4c and 08b9a0c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • .husky/pre-commit
  • package.json
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: AndurilCode/mcp-apps-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T14:18:43.501Z
Learning: Run full checks before PR: `pnpm build && pnpm test && pnpm lint && pnpm typecheck`
📚 Learning: 2026-01-09T14:18:43.501Z
Learnt from: CR
Repo: AndurilCode/mcp-apps-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T14:18:43.501Z
Learning: Run full checks before PR: `pnpm build && pnpm test && pnpm lint && pnpm typecheck`

Applied to files:

  • .husky/pre-commit
  • package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test-and-lint
  • GitHub Check: claude-review
🔇 Additional comments (5)
package.json (4)

55-56: Tooling deps look consistent with docs/docs:watch; just ensure versions are intentional.


21-21: typedoc --watch is fully supported in TypeDoc 0.28.15 (the version specified in package.json). The flag is documented in TypeDoc's CLI options and works as expected for watch mode. No issues or caveats detected.


50-50: Husky v9.1.7 bump is safe—repository already has proper pnpm workspace setup.

The repo correctly uses "prepare": "husky" (v9-compatible) with pnpm-workspace.yaml and .npmrc in place, which aligns with Husky v9's requirements for pnpm environments. No additional action needed.


21-22: Husky prepare script is safe in this CI setup.

Husky v9.1.7 automatically detects CI environments and non-git contexts, gracefully skipping the prepare step without requiring HUSKY=0 or --ignore-scripts. Your GitHub Actions workflows have .git directories from full repository clones, so the prepare: "husky" script will execute safely. No guard is needed for the current setup.

Likely an incorrect or invalid review comment.

.husky/pre-commit (1)

1-2: Current hook file is already correct for Husky v9.

The recommendation to add #!/usr/bin/env sh and . "$(dirname -- "$0")/_/husky.sh" is outdated. Husky v9 deprecated this pattern and no longer requires it. For simple hooks like this, the current implementation (plain commands without shebang) is the recommended approach in Husky v9. The repository uses Husky v9.1.7, which handles hook execution without the deprecated bootstrap code. No changes are needed.

Likely an incorrect or invalid review comment.

@gabrypavanello
gabrypavanello merged commit 106218c into main Jan 9, 2026
4 of 5 checks passed
@gabrypavanello
gabrypavanello deleted the vk/d9d6-create-a-pre-com branch January 9, 2026 14:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
package.json (1)

61-63: Configuration looks correct; consider the pre-commit scope trade-off.

The lint-staged configuration is properly structured, and the file patterns appropriately cover common source files. lint-staged will automatically append matched files to the prettier --write command.

Note that the pre-commit hook currently only runs formatting, not the full suite of checks (lint, typecheck, tests). While this is faster and aligns with the PR's stated goals, it means commits may pass formatting but still fail CI checks. Based on learnings, full checks (pnpm build && pnpm test && pnpm lint && pnpm typecheck) should be run before creating a PR. Consider documenting this workflow expectation for contributors, or optionally add eslint --fix to the lint-staged configuration to catch at least some lint issues early.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08b9a0c and 610a26b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • .husky/pre-commit
  • package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • .husky/pre-commit
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: AndurilCode/mcp-apps-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T14:18:43.501Z
Learning: Run full checks before PR: `pnpm build && pnpm test && pnpm lint && pnpm typecheck`
🔇 Additional comments (2)
package.json (2)

22-22: LGTM! Standard Husky v9 initialization.

The prepare script correctly initializes Husky hooks after installation, following the recommended pattern for Husky v9.


50-50: Both package versions are valid and have no known security vulnerabilities. husky@9.1.7 and lint-staged@16.2.7 are available on npm and free from reported CVEs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants