resq-cli 0.3.0

Developer CLI for the ResQ autonomous drone platform
Documentation
#!/usr/bin/env bash
# Copyright 2026 ResQ Software
# SPDX-License-Identifier: Apache-2.0
#
# Canonical ResQ commit-msg shim — source: resq-software/dev.
# Enforces Conventional Commits; blocks fixup/squash/WIP on main/master.

set -euo pipefail

[ -n "${GIT_HOOKS_SKIP:-}" ] && exit 0

INPUT_FILE="${1:-}"
PATTERN="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?(!)?: .+$"

FIRST_LINE=$(head -1 "$INPUT_FILE")
# Ticket-prefix regex matches what prepare-commit-msg prepends ({2,} chars).
SUBJECT=$(sed -E 's/^\[[A-Z]{2,}-[0-9]+\][[:space:]]*//' <<<"$FIRST_LINE")

# WIP / fixup! / squash! guard runs *before* the format check so users get
# a branch-specific error message on main/master instead of the generic
# "Invalid commit message format".
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
case "$BRANCH" in
    main|master)
        if grep -qiE "^(\[[A-Z]{2,}-[0-9]+\] )?(fixup!|squash!|wip[: ])" <<<"$FIRST_LINE"; then
            echo "Error: fixup!/squash!/WIP commits are not allowed on $BRANCH."
            echo "Create a feature branch instead."
            exit 1
        fi
        ;;
esac

if ! grep -qE "$PATTERN" <<<"$SUBJECT"; then
    echo "Error: Invalid commit message format."
    echo "Expected: type(scope)(!): subject"
    echo "Examples:"
    echo "  feat(core): add new feature"
    echo "  feat!: remove deprecated API  (breaking change marker)"
    echo "  fix(ui): fix button color"
    exit 1
fi

LOCAL_HOOK="$(git rev-parse --show-toplevel)/.git-hooks/local-commit-msg"
if [ -x "$LOCAL_HOOK" ]; then
    exec "$LOCAL_HOOK" "$@"
fi