#!/bin/bash # spec-gate.sh - PreToolUse hook for Write/Edit # Avisa quando se tenta editar ficheiros sem SPEC.md aprovado # Modo: HARD (bloqueia sem SPEC.md aprovado) # Autor: Descomplicar® | 2026-02-07 INPUT=$(cat) TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null) # So intercepta Write e Edit if [ "$TOOL_NAME" != "Write" ] && [ "$TOOL_NAME" != "Edit" ]; then exit 0 fi # Extrair file path FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null) # ========== BYPASSES ========== # Sem file path if [ -z "$FILE_PATH" ]; then exit 0 fi # Ficheiros de sistema if echo "$FILE_PATH" | grep -qE '(\.claude/|CLAUDE\.md|settings\.json|\.env|\.claude-work/)'; then exit 0 fi # O proprio SPEC.md ou SPRINT.md if echo "$FILE_PATH" | grep -qE '(SPEC\.md|SPRINT\.md)$'; then exit 0 fi # Ficheiros fora de pastas de projecto if ! echo "$FILE_PATH" | grep -qE '^/media/ealmeida/Dados/(Dev|Arquivo_de_Clientes)/'; then exit 0 fi # Bypass temporario (30 min) BYPASS_FILE="/tmp/claude-spec-gate-bypass" if [ -f "$BYPASS_FILE" ]; then BYPASS_AGE=$(( $(date +%s) - $(stat -c %Y "$BYPASS_FILE" 2>/dev/null || echo 0) )) if [ "$BYPASS_AGE" -lt 1800 ]; then exit 0 else rm -f "$BYPASS_FILE" fi fi # Docs e configs (CHANGELOG, README, .txt, docs/) if echo "$FILE_PATH" | grep -qiE '(CHANGELOG|README|\.txt$|\.json$|docs/|\.desk-project)'; then exit 0 fi # Plan files if echo "$FILE_PATH" | grep -qE '\.claude/plans/'; then exit 0 fi # ========== SPEC CHECK ========== DIR=$(dirname "$FILE_PATH") SPEC_FOUND="" # Procurar SPEC.md subindo ate 5 niveis for i in 1 2 3 4 5; do if [ -f "$DIR/SPEC.md" ]; then SPEC_FOUND="$DIR/SPEC.md" break fi PARENT=$(dirname "$DIR") # Parar em raizes conhecidas if [ "$PARENT" = "$DIR" ] || [ "$DIR" = "/media/ealmeida/Dados/Dev" ] || [ "$DIR" = "/media/ealmeida/Dados" ]; then break fi DIR="$PARENT" done # Sem SPEC.md - aviso suave if [ -z "$SPEC_FOUND" ]; then echo "SPEC-GATE: Sem SPEC.md neste projecto. Considere /spec create antes de comecar." exit 2 # hard mode: bloqueia fi # SPEC.md existe - verificar aprovacao if grep -q '