#!/usr/bin/env bash # Pre-commit hook for agent-desktop. # Mirrors the CI quality gates so a failing commit never reaches origin. # # Setup (once per clone): # git config core.hooksPath .githooks # # Bypass for a single commit (only when truly necessary): # git commit --no-verify set -euo pipefail if [ -n "${SKIP_PRECOMMIT:-}" ]; then echo "pre-commit: SKIP_PRECOMMIT set, skipping" exit 0 fi if ! command -v cargo >/dev/null 2>&1; then echo "pre-commit: cargo not found in PATH, skipping (install Rust to enable)" exit 0 fi cd "$(git rev-parse --show-toplevel)" if git diff --cached --name-only --diff-filter=ACMR | grep -qE '\.(rs|toml)$'; then HAS_RUST_CHANGES=1 else HAS_RUST_CHANGES=0 fi if git diff --cached --name-only --diff-filter=ACMR | grep -q '^crates/ffi/'; then HAS_FFI_CHANGES=1 else HAS_FFI_CHANGES=0 fi if [ "$HAS_RUST_CHANGES" -eq 0 ] && [ "$HAS_FFI_CHANGES" -eq 0 ]; then echo "pre-commit: no Rust or FFI changes staged, skipping cargo checks" exit 0 fi run() { local label="$1" shift printf '\033[1;34m▶ %s\033[0m\n' "$label" if ! "$@"; then printf '\033[1;31m✗ %s failed\033[0m\n' "$label" >&2 echo "" >&2 echo "pre-commit: refusing the commit. Fix the issues above or rerun with SKIP_PRECOMMIT=1 to bypass." >&2 exit 1 fi } run "Rust source rules" scripts/check-rust-file-size.sh run "cargo fmt --all -- --check" cargo fmt --all -- --check run "cargo clippy --all-targets -- -D warnings" cargo clippy --all-targets -- -D warnings run "cargo test --lib --workspace" scripts/cargo-test-isolated-home.sh test --lib --workspace # FFI-specific gates are skipped when no FFI files are staged. Runtime panic # and Python smoke proofs remain CI-only to keep commits fast. if [ "$HAS_FFI_CHANGES" -eq 1 ]; then run "FFI stub passthrough" cargo test --locked -p agent-desktop-ffi --features stub-adapter --test c_abi_passthrough export PATH="${HOME}/.cargo/bin:${PATH}" _cbindgen_cmd="" if command -v cbindgen >/dev/null 2>&1; then _cbindgen_cmd="cbindgen" fi if [ -n "${_cbindgen_cmd}" ]; then _cbindgen_ver=$("${_cbindgen_cmd}" --version 2>&1 | head -1) if [[ "${_cbindgen_ver}" == "cbindgen 0.29.4" ]]; then run "FFI header drift (cbindgen --verify)" \ "${_cbindgen_cmd}" crates/ffi --config crates/ffi/cbindgen.toml \ --output crates/ffi/include/agent_desktop.h --verify else printf 'pre-commit: cbindgen version mismatch (want 0.29.4, got: %s) — skipping header drift check (CI gate)\n' "${_cbindgen_ver}" fi else printf 'pre-commit: cbindgen not found in PATH or ~/.cargo/bin — skipping header drift check (CI gate)\n' fi fi printf '\033[1;32m✓ pre-commit checks passed\033[0m\n'