mirror of
https://github.com/C4illin/ConvertX.git
synced 2026-11-11 16:50:57 +01:00
Add AI indicator pre-commit guard
This commit is contained in:
1 parent
3cc5c5371e
commit
6f7cb19373
5 files changed
+479
No files matched your search
Executable
+171
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Block commits when staged files contain explicit AI usage indicators.
|
||||
# Mirrors the onboarding guidance so reviewers remain blinded to AI tooling.
|
||||
# Markdown (.md) files are explicitly scanned to prevent AI flag text in docs.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
declare -a PATTERNS=(
|
||||
"generated by cursor"
|
||||
"cursor ai"
|
||||
"cursor wrote this"
|
||||
"cursor suggestion"
|
||||
"generated by claude"
|
||||
"claude wrote this"
|
||||
"claude ai"
|
||||
"claude opus"
|
||||
"claude sonnet"
|
||||
"claude haiku"
|
||||
"claude code"
|
||||
"generated with claude code"
|
||||
"generated with \\[claude code\\]"
|
||||
"co-authored-by: claude"
|
||||
"noreply@anthropic\\.com"
|
||||
"generated by gemini"
|
||||
"gemini wrote this"
|
||||
"google gemini"
|
||||
"gemini ultra"
|
||||
"gemini pro"
|
||||
"gemini nano"
|
||||
"generated by bard"
|
||||
"bard wrote this"
|
||||
"google bard"
|
||||
"as an ai assistant"
|
||||
"as an ai"
|
||||
"ai assistant"
|
||||
"ai suggestion"
|
||||
"ai suggestions"
|
||||
"ai-generated"
|
||||
"ai generated"
|
||||
"ai-assisted"
|
||||
"ai assisted"
|
||||
"ai-powered"
|
||||
"ai powered"
|
||||
"powered by ai"
|
||||
"with ai assistance"
|
||||
"with the help of ai"
|
||||
"assisted by ai"
|
||||
"written with ai"
|
||||
"written by ai"
|
||||
"generated with ai"
|
||||
"generated via ai"
|
||||
"created with ai"
|
||||
"created by ai"
|
||||
"authored by ai"
|
||||
"co-authored by ai"
|
||||
"ai help"
|
||||
"ai helped"
|
||||
"ai copilot"
|
||||
"ai co-pilot"
|
||||
"chatgpt"
|
||||
"gpt-4"
|
||||
"gpt4"
|
||||
"gpt-3"
|
||||
"gpt3"
|
||||
"openai"
|
||||
"anthropic"
|
||||
"google ai"
|
||||
"google deepmind"
|
||||
"deepmind"
|
||||
"perplexity"
|
||||
"perplexity ai"
|
||||
"tabnine"
|
||||
"tabnine ai"
|
||||
"replit ghostwriter"
|
||||
"ghostwriter ai"
|
||||
"aws codewhisperer"
|
||||
"amazon codewhisperer"
|
||||
"code whisperer"
|
||||
"codewhisperer"
|
||||
"github copilot"
|
||||
"copilot"
|
||||
"amazon q"
|
||||
"amazon q developer"
|
||||
"meta ai"
|
||||
"deepseek"
|
||||
"phind"
|
||||
"blackbox ai"
|
||||
"magic ai"
|
||||
"ai model"
|
||||
"llm"
|
||||
"large language model"
|
||||
"language model"
|
||||
"\\[ai\\]"
|
||||
"\\[ai-generated\\]"
|
||||
"\\[cursor\\]"
|
||||
"\\[claude\\]"
|
||||
"\\[gemini\\]"
|
||||
"\\[copilot\\]"
|
||||
"\\[chatgpt\\]"
|
||||
"\\[llm\\]"
|
||||
)
|
||||
|
||||
PATTERN_REGEX=$(printf '%s|' "${PATTERNS[@]}")
|
||||
PATTERN_REGEX=${PATTERN_REGEX%|}
|
||||
|
||||
# Build a newline-separated list of binary file paths (bash 3.2 compatible)
|
||||
BINARY_PATHS=""
|
||||
while IFS=$'\t' read -r added deleted path; do
|
||||
[[ -z "${path:-}" ]] && continue
|
||||
if [[ "$path" == *" -> "* ]]; then
|
||||
path=${path##* -> }
|
||||
fi
|
||||
if [[ "$added" == "-" || "$deleted" == "-" ]]; then
|
||||
BINARY_PATHS="${BINARY_PATHS}${path}"$'\n'
|
||||
fi
|
||||
done < <(git diff --cached --numstat --diff-filter=ACMRT || true)
|
||||
|
||||
report=""
|
||||
current_file=""
|
||||
last_report_file=""
|
||||
violations=0
|
||||
|
||||
while IFS= read -r line; do
|
||||
case "$line" in
|
||||
"diff --git "*)
|
||||
current_file=""
|
||||
;;
|
||||
"+++ "*)
|
||||
current_file=${line#+++ }
|
||||
if [[ "$current_file" == b/* ]]; then
|
||||
current_file=${current_file#b/}
|
||||
elif [[ "$current_file" == a/* ]]; then
|
||||
current_file=${current_file#a/}
|
||||
fi
|
||||
if [[ "$current_file" == "/dev/null" ]]; then
|
||||
current_file=""
|
||||
fi
|
||||
;;
|
||||
"Binary files "*)
|
||||
current_file=""
|
||||
;;
|
||||
*)
|
||||
if [[ "$line" == +* && "$line" != "+++"* ]]; then
|
||||
[[ -z "$current_file" ]] && continue
|
||||
if [[ -n "$BINARY_PATHS" ]] && echo "$BINARY_PATHS" | grep -qxF "$current_file"; then
|
||||
continue
|
||||
fi
|
||||
content=${line:1}
|
||||
if [[ -n "$content" ]] && LC_ALL=C grep -qiE "$PATTERN_REGEX" <<<"$content"; then
|
||||
if [[ "$current_file" != "$last_report_file" ]]; then
|
||||
report+=$'\n'"• $current_file"
|
||||
last_report_file="$current_file"
|
||||
fi
|
||||
report+=$'\n'" ${line}"
|
||||
violations=1
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done < <(git diff --cached --diff-filter=ACMRT --unified=0 --no-color)
|
||||
|
||||
if [[ $violations -eq 1 ]]; then
|
||||
cat >&2 <<EOF
|
||||
✖ Commit blocked: staged changes contain AI usage indicators in the current diff.
|
||||
Please remove or rephrase the highlighted additions before committing:$report
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in new issue
Block a user