Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Ensure hook files use LF line endings on all platforms (Windows compatibility)
examples/**/*.sh text eol=lf
.husky/* text eol=lf
lefthook.yml text eol=lf

# Git hooks should always use LF
*.hook text eol=lf
Expand Down
69 changes: 69 additions & 0 deletions .husky/_/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/sh

if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi

if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi

call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"

elif go tool lefthook -h >/dev/null 2>&1
then
go tool lefthook "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package lefthook >/dev/null 2>&1
then
swift package --build-path .build/lefthook --disable-sandbox lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif uv run lefthook -h >/dev/null 2>&1
then
uv run lefthook "$@"
elif mise exec -- lefthook -h >/dev/null 2>&1
then
mise exec -- lefthook "$@"
elif devbox run lefthook -h >/dev/null 2>&1
then
devbox run lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}

call_lefthook run "pre-commit" "$@"
69 changes: 69 additions & 0 deletions .husky/_/prepare-commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/sh

if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi

if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi

call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"

elif go tool lefthook -h >/dev/null 2>&1
then
go tool lefthook "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package lefthook >/dev/null 2>&1
then
swift package --build-path .build/lefthook --disable-sandbox lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif uv run lefthook -h >/dev/null 2>&1
then
uv run lefthook "$@"
elif mise exec -- lefthook -h >/dev/null 2>&1
then
mise exec -- lefthook "$@"
elif devbox run lefthook -h >/dev/null 2>&1
then
devbox run lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}

call_lefthook run "prepare-commit-msg" "$@"
18 changes: 0 additions & 18 deletions .husky/pre-commit

This file was deleted.

6 changes: 0 additions & 6 deletions .husky/prepare-commit-msg

This file was deleted.

14 changes: 8 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -990,12 +990,12 @@ Add your agent to the help text in `src/cli.ts`:

## Self-Dogfooding

commitment uses itself for its own commit messages via git hooks:
commitment uses itself for its own commit messages via lefthook:

- **pre-commit**: Runs linting and builds dist/
- **pre-commit**: Runs linting and builds dist/ (configured in `lefthook.yml`)
- **prepare-commit-msg**: Calls `./dist/cli.js --message-only` to generate commit message

This ensures commitment is battle-tested on itself and provides a real-world example.
This ensures commitment is battle-tested on itself and provides a real-world example. See `lefthook.yml` in the project root.

## CLI Architecture

Expand Down Expand Up @@ -1036,7 +1036,7 @@ npx commitment init [options]
- `--cwd <path>` - Working directory (default: current directory)

**Init Command Flags:**
- `--hook-manager <type>` - Hook manager: husky, simple-git-hooks, plain
- `--hook-manager <type>` - Hook manager: lefthook, husky, simple-git-hooks, plain
- `--cwd <path>` - Working directory (default: current directory)

### ESLint Configuration for CLI
Expand Down Expand Up @@ -1202,9 +1202,11 @@ src/

examples/
├── git-hooks/ # Plain git hooks examples
├── husky/ # Husky integration examples
├── lefthook/ # Lefthook integration examples
├── husky/ # Husky integration examples (legacy)
├── simple-git-hooks/ # simple-git-hooks integration examples
└── lint-staged/ # lint-staged integration examples
├── lint-staged/ # lint-staged with lefthook examples
└── global-install/ # Global install examples for non-TS repos

docs/
└── constitutions/
Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ We all know we should write better commit messages. But we don't.
- 📊 **Code analysis** detects functions, tests, types, and patterns in your changes
- ✨ **Conventional Commits** for a standard format (feat:, fix:, docs:, etc.)
- 🚀 **One-command setup** with `commitment init` for automatic hook installation
- 🪝 **Hook integration** with husky, simple-git-hooks, or plain git hooks
- 🪝 **Hook integration** with lefthook, husky, simple-git-hooks, or plain git hooks
- 🌍 **Cross-platform** support for macOS, Linux, and Windows
- 📦 **Zero config** works out of the box with sensible defaults
- 🔕 **Quiet mode** for suppressing progress messages in scripts
Expand Down Expand Up @@ -173,8 +173,9 @@ commitment supports multiple hook managers:
| Manager | Command | Best For |
|---------|---------|----------|
| **Auto-detect** | `npx commitment init` | Most projects |
| **Lefthook** | `npx commitment init --hook-manager lefthook` | Fast, parallel execution, YAML config (recommended) |
| **Husky** | `npx commitment init --hook-manager husky` | Teams with existing husky setup |
| **simple-git-hooks** | `npx commitment init --hook-manager simple-git-hooks` | Lightweight alternative to husky |
| **simple-git-hooks** | `npx commitment init --hook-manager simple-git-hooks` | Lightweight alternative |
| **Plain Git Hooks** | `npx commitment init --hook-manager plain` | No dependencies |

**Configure default agent:**
Expand All @@ -191,6 +192,9 @@ See [docs/HOOKS.md](./docs/HOOKS.md) for detailed hook integration guide.

**Check installation:**
```bash
# For lefthook
cat lefthook.yml

# For husky
ls -la .husky/prepare-commit-msg

Expand All @@ -205,8 +209,13 @@ npx commitment init

**Check permissions (Unix-like systems):**
```bash
# For lefthook, run:
npx lefthook install

# For husky
chmod +x .husky/prepare-commit-msg
# or

# For plain git hooks
chmod +x .git/hooks/prepare-commit-msg
```

Expand Down
10 changes: 10 additions & 0 deletions biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@
}
}
},
{
"includes": ["src/utils/logger.ts"],
"linter": {
"rules": {
"suspicious": {
"noConsole": "off"
}
}
}
},
{
"includes": [
"src/**/__tests__/**",
Expand Down
6 changes: 3 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/constitutions/v3/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ See `testing.md` for detailed requirements.
```gitattributes
# Ensure hook files use LF line endings on all platforms
examples/**/*.sh text eol=lf
.husky/* text eol=lf
lefthook.yml text eol=lf
*.hook text eol=lf
```

Expand All @@ -618,7 +618,7 @@ examples/**/*.sh text eol=lf

**Init Command Workflow:**
1. Detect git repository
2. Auto-detect existing hook manager (husky, simple-git-hooks)
2. Auto-detect existing hook manager (lefthook, husky, simple-git-hooks)
3. Install appropriate hooks based on detection or `--hook-manager` flag
4. Configure hooks to check `$2` parameter (preserve user messages)

Expand Down
Loading