lefthook.yml
Rama main · réplica de lectura del repositorio original.
pre-commit:
commands:
lint:
run: make lint
ui-eslint:
root: "ui/"
glob:
- "ui/*.{ts,tsx,js,jsx}"
- "ui/**/*.{ts,tsx,js,jsx}"
# Hard-fail (never skip) so problems surface here, not in CI. Auto-install
# pinned deps if missing; run the project-local eslint binary so the
# version always matches the lockfile, never a global/network version.
run: |
command -v node >/dev/null 2>&1 || { echo "✖ node not found. UI hooks require Node.js. Run 'make install' (or install Node) before committing UI changes."; exit 1; }
[ -x node_modules/.bin/eslint ] || npm ci || { echo "✖ npm ci failed — cannot run ui-eslint. Fix UI deps and retry."; exit 1; }
./node_modules/.bin/eslint --fix {staged_files}
stage_fixed: true
ui-format:
root: "ui/"
glob:
- "ui/*.{ts,tsx,js,jsx,css,json,md,html}"
- "ui/**/*.{ts,tsx,js,jsx,css,json,md,html}"
run: |
command -v node >/dev/null 2>&1 || { echo "✖ node not found. UI hooks require Node.js. Run 'make install' (or install Node) before committing UI changes."; exit 1; }
[ -x node_modules/.bin/prettier ] || npm ci || { echo "✖ npm ci failed — cannot run ui-format. Fix UI deps and retry."; exit 1; }
./node_modules/.bin/prettier --write {staged_files}
stage_fixed: true
detect-secrets:
# No glob: scan every staged file type, matching the CI gate
# (`make detect-secrets`). The wrapper also trims entries for staged
# deletions ({staged_files} omits them) and keeps the baseline slim.
run: uv run python -m tools.secrets_baseline hook {staged_files}
commit-msg:
commands:
commitlint:
# Enforce conventional commits locally (type(scope): subject) so messages
# are correct at commit time — never deferred to CI. Pure Python via uv,
# so this fires for every contributor with no Node dependency.
# --allow-abort lets an empty/aborted message cancel the commit cleanly
# instead of erroring.
run: uv run cz check --allow-abort --commit-msg-file {1}