{
"event": "PreToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/rules_style.py",
"content": "#!\/usr\/bin\/env python3\n\"\"\"\nStyle & DRY Rules (W5) - Don't Repeat Yourself.\n\nRegeln gegen Code-Duplikation: wiederholte Strings und Magic Numbers.\n\"\"\"\n\nimport re\nfrom collections import Counter\nfrom typing import List\nfrom .rule_base import Rule, COMMON_NUMBERS, MIGRATION_ALLOWLIST\n\n\n# =============================================================================\n# W5: DRY - Don't Repeat Yourself\n# =============================================================================\n\nclass W5_1_RepeatedStrings(Rule):\n \"\"\"W5.1: Wiederholte String-Literale (> 3x).\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=MIGRATION_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n # Finde Strings > 20 Zeichen\n string_literals = re.findall(r'\"([^\"]{20,})\"', content)\n counts = Counter(string_literals)\n\n warnings = []\n for s, count in counts.items():\n if count > 3:\n truncated = s[:40] + \"...\" if len(s) > 40 else s\n warnings.append(f\"W5.1: String repeated {count}x: '{truncated}' - consider constant.\")\n\n return warnings\n\n\nclass W5_2_MagicNumbers(Rule):\n \"\"\"W5.2: Wiederholte Magic Numbers (> 2x).\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=MIGRATION_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n # Finde Zahlen (2+ Ziffern, nicht in Konstanten)\n numbers = re.findall(r'(?<![A-Z_])(\\d{2,})(?![A-Z_])', content)\n\n warnings = []\n for num in set(numbers):\n if num not in COMMON_NUMBERS and numbers.count(num) > 2:\n warnings.append(f\"W5.2: Magic number {num} repeated {numbers.count(num)}x - consider constant.\")\n\n return warnings\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n W5_1_RepeatedStrings(),\n W5_2_MagicNumbers(),\n]\n"
}
}
{
"tool_response": {
"type": "create",
"filePath": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/rules_style.py",
"content": "#!\/usr\/bin\/env python3\n\"\"\"\nStyle & DRY Rules (W5) - Don't Repeat Yourself.\n\nRegeln gegen Code-Duplikation: wiederholte Strings und Magic Numbers.\n\"\"\"\n\nimport re\nfrom collections import Counter\nfrom typing import List\nfrom .rule_base import Rule, COMMON_NUMBERS, MIGRATION_ALLOWLIST\n\n\n# =============================================================================\n# W5: DRY - Don't Repeat Yourself\n# =============================================================================\n\nclass W5_1_RepeatedStrings(Rule):\n \"\"\"W5.1: Wiederholte String-Literale (> 3x).\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=MIGRATION_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n # Finde Strings > 20 Zeichen\n string_literals = re.findall(r'\"([^\"]{20,})\"', content)\n counts = Counter(string_literals)\n\n warnings = []\n for s, count in counts.items():\n if count > 3:\n truncated = s[:40] + \"...\" if len(s) > 40 else s\n warnings.append(f\"W5.1: String repeated {count}x: '{truncated}' - consider constant.\")\n\n return warnings\n\n\nclass W5_2_MagicNumbers(Rule):\n \"\"\"W5.2: Wiederholte Magic Numbers (> 2x).\"\"\"\n\n def __init__(self):\n super().__init__(allowlist=MIGRATION_ALLOWLIST)\n\n def check(self, file_path: str, content: str) -> List[str]:\n # Finde Zahlen (2+ Ziffern, nicht in Konstanten)\n numbers = re.findall(r'(?<![A-Z_])(\\d{2,})(?![A-Z_])', content)\n\n warnings = []\n for num in set(numbers):\n if num not in COMMON_NUMBERS and numbers.count(num) > 2:\n warnings.append(f\"W5.2: Magic number {num} repeated {numbers.count(num)}x - consider constant.\")\n\n return warnings\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n W5_1_RepeatedStrings(),\n W5_2_MagicNumbers(),\n]\n",
"structuredPatch": [],
"originalFile": null
}
}