Protokoll #14506

ID14506
Zeitstempel2025-12-25 10:44:33.632369
Clientroot
IP
Warning: Undefined array key "request_ip" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13

Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens4,993 (Input: 0, Output: 0)
Dauer112 ms
Request-Zeit
Warning: Undefined array key "request_timestamp" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 18
Response-Zeit-

Warning: Undefined array key "error_message" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 22

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/full_scan.py",
        "content": "#!\/usr\/bin\/env python3\n\"\"\"\nFull Codebase Quality Scan.\n\nScannt alle PHP-Dateien gegen Pre- und Post-Hook Regeln.\nErstellt optional Tasks für Violations.\n\nUsage:\n    full_scan.py                    # Scan mit Output\n    full_scan.py --json             # JSON-Output\n    full_scan.py --create-tasks     # Tasks für Violations erstellen\n    full_scan.py --path \/src        # Nur bestimmten Pfad scannen\n\"\"\"\n\nimport argparse\nimport json\nimport os\nimport sys\nfrom pathlib import Path\nfrom typing import Dict, List, Any\n\n# Eigene Module laden\nsys.path.insert(0, str(Path(__file__).parent))\nimport pre_rules\nimport post_rules\n\n# =============================================================================\n# CONFIGURATION\n# =============================================================================\n\nDEFAULT_SCAN_PATH = \"\/var\/www\/dev.campus.systemische-tools.de\/src\"\n\nSKIP_DIRS = [\n    \"\/vendor\/\",\n    \"\/node_modules\/\",\n    \"\/.git\/\",\n    \"\/cache\/\",\n    \"\/var\/\",\n]\n\n# =============================================================================\n# SCANNER\n# =============================================================================\n\n\ndef find_php_files(base_path: str) -> List[Path]:\n    \"\"\"Findet alle PHP-Dateien im Pfad.\"\"\"\n    base = Path(base_path)\n    if not base.exists():\n        return []\n\n    files = []\n    for php_file in base.rglob(\"*.php\"):\n        file_str = str(php_file)\n        if not any(skip in file_str for skip in SKIP_DIRS):\n            files.append(php_file)\n\n    return sorted(files)\n\n\ndef scan_file(file_path: Path) -> Dict[str, Any]:\n    \"\"\"Scannt eine einzelne Datei.\"\"\"\n    try:\n        content = file_path.read_text(encoding=\"utf-8\")\n    except (OSError, UnicodeDecodeError) as e:\n        return {\n            \"file\": str(file_path),\n            \"error\": str(e),\n            \"blocks\": [],\n            \"warnings\": [],\n        }\n\n    file_str = str(file_path)\n\n    # Pre-Rules (Blocks)\n    pre_result = pre_rules.check(file_str, content)\n    blocks = []\n    if not pre_result.get(\"allowed\", True):\n        blocks.append(pre_result.get(\"message\", \"Unknown block\"))\n\n    # Post-Rules (Warnings)\n    post_result = post_rules.check(file_str, content)\n    warnings = post_result.get(\"warnings\", [])\n\n    return {\n        \"file\": file_str,\n        \"blocks\": blocks,\n        \"warnings\": warnings,\n    }\n\n\ndef scan_all(base_path: str) -> Dict[str, Any]:\n    \"\"\"Scannt alle PHP-Dateien.\"\"\"\n    files = find_php_files(base_path)\n\n    results = {\n        \"scan_path\": base_path,\n        \"total_files\": len(files),\n        \"files_with_blocks\": 0,\n        \"files_with_warnings\": 0,\n        \"total_blocks\": 0,\n        \"total_warnings\": 0,\n        \"violations\": [],\n    }\n\n    for file_path in files:\n        file_result = scan_file(file_path)\n\n        if file_result.get(\"error\"):\n            results[\"violations\"].append(file_result)\n            continue\n\n        has_issues = False\n\n        if file_result[\"blocks\"]:\n            results[\"files_with_blocks\"] += 1\n            results[\"total_blocks\"] += len(file_result[\"blocks\"])\n            has_issues = True\n\n        if file_result[\"warnings\"]:\n            results[\"files_with_warnings\"] += 1\n            results[\"total_warnings\"] += len(file_result[\"warnings\"])\n            has_issues = True\n\n        if has_issues:\n            results[\"violations\"].append(file_result)\n\n    return results\n\n\n# =============================================================================\n# OUTPUT FORMATTERS\n# =============================================================================\n\n\ndef format_console(results: Dict[str, Any]) -> str:\n    \"\"\"Formatiert Ergebnis für Console-Output.\"\"\"\n    lines = []\n    lines.append(\"=\" * 70)\n    lines.append(\"QUALITY SCAN REPORT\")\n    lines.append(\"=\" * 70)\n    lines.append(f\"Scan Path: {results['scan_path']}\")\n    lines.append(f\"Total Files: {results['total_files']}\")\n    lines.append(\"\")\n    lines.append(f\"Files with BLOCKS: {results['files_with_blocks']}\")\n    lines.append(f\"Files with WARNINGS: {results['files_with_warnings']}\")\n    lines.append(f\"Total BLOCKS: {results['total_blocks']}\")\n    lines.append(f\"Total WARNINGS: {results['total_warnings']}\")\n    lines.append(\"\")\n\n    if results[\"violations\"]:\n        lines.append(\"-\" * 70)\n        lines.append(\"VIOLATIONS:\")\n        lines.append(\"-\" * 70)\n\n        for v in results[\"violations\"]:\n            # Kurzer Pfad\n            short_path = v[\"file\"].replace(\"\/var\/www\/dev.campus.systemische-tools.de\/\", \"\")\n            lines.append(f\"\\n{short_path}\")\n\n            if v.get(\"error\"):\n                lines.append(f\"  ERROR: {v['error']}\")\n\n            for block in v.get(\"blocks\", []):\n                lines.append(f\"  [BLOCK] {block}\")\n\n            for warning in v.get(\"warnings\", []):\n                lines.append(f\"  [WARN]  {warning}\")\n\n    lines.append(\"\")\n    lines.append(\"=\" * 70)\n\n    if results[\"total_blocks\"] > 0:\n        lines.append(\"STATUS: FAILED (has blocking violations)\")\n    elif results[\"total_warnings\"] > 0:\n        lines.append(\"STATUS: PASSED with warnings\")\n    else:\n        lines.append(\"STATUS: PASSED\")\n\n    lines.append(\"=\" * 70)\n\n    return \"\\n\".join(lines)\n\n\ndef format_json(results: Dict[str, Any]) -> str:\n    \"\"\"Formatiert Ergebnis als JSON.\"\"\"\n    return json.dumps(results, indent=2, ensure_ascii=False)\n\n\n# =============================================================================\n# TASK CREATION\n# =============================================================================\n\n\ndef create_tasks_for_violations(results: Dict[str, Any]) -> List[Dict[str, Any]]:\n    \"\"\"Erstellt Tasks für alle Violations.\"\"\"\n    try:\n        import task_creator\n    except ImportError:\n        return [{\"error\": \"task_creator module not found\"}]\n\n    created = []\n\n    for v in results[\"violations\"]:\n        file_path = v[\"file\"]\n\n        for block in v.get(\"blocks\", []):\n            # Parse Rule-ID aus Message\n            rule_id = \"UNKNOWN\"\n            if \"[\" in block and \"]\" in block:\n                rule_id = block.split(\"[\")[1].split(\"]\")[0]\n\n            try:\n                task_id = task_creator.create_violation_task(\n                    file_path, rule_id, block, \"block\"\n                )\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"block\",\n                    \"task_id\": task_id,\n                })\n            except Exception as e:\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"block\",\n                    \"error\": str(e),\n                })\n\n        for warning in v.get(\"warnings\", []):\n            # Parse Rule-ID aus Warning\n            rule_id = \"UNKNOWN\"\n            if warning.startswith(\"W\") and \":\" in warning:\n                rule_id = warning.split(\":\")[0]\n\n            try:\n                task_id = task_creator.create_warning_task(file_path, rule_id, warning)\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"warning\",\n                    \"task_id\": task_id,\n                })\n            except Exception as e:\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"warning\",\n                    \"error\": str(e),\n                })\n\n    return created\n\n\n# =============================================================================\n# MAIN\n# =============================================================================\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Full Codebase Quality Scan\")\n    parser.add_argument(\n        \"--path\",\n        default=DEFAULT_SCAN_PATH,\n        help=f\"Path to scan (default: {DEFAULT_SCAN_PATH})\",\n    )\n    parser.add_argument(\n        \"--json\",\n        action=\"store_true\",\n        help=\"Output as JSON\",\n    )\n    parser.add_argument(\n        \"--create-tasks\",\n        action=\"store_true\",\n        help=\"Create tasks for violations\",\n    )\n    parser.add_argument(\n        \"--blocks-only\",\n        action=\"store_true\",\n        help=\"Only report blocking violations\",\n    )\n\n    args = parser.parse_args()\n\n    # Scan durchführen\n    results = scan_all(args.path)\n\n    # Wenn blocks-only, Warnings entfernen\n    if args.blocks_only:\n        for v in results[\"violations\"]:\n            v[\"warnings\"] = []\n        results[\"violations\"] = [\n            v for v in results[\"violations\"] if v[\"blocks\"]\n        ]\n        results[\"total_warnings\"] = 0\n        results[\"files_with_warnings\"] = 0\n\n    # Tasks erstellen wenn gewünscht\n    if args.create_tasks:\n        created_tasks = create_tasks_for_violations(results)\n        results[\"created_tasks\"] = created_tasks\n\n    # Output\n    if args.json:\n        print(format_json(results))\n    else:\n        print(format_console(results))\n        if args.create_tasks and results.get(\"created_tasks\"):\n            print(f\"\\nCreated {len(results['created_tasks'])} tasks for violations.\")\n\n    # Exit Code\n    if results[\"total_blocks\"] > 0:\n        sys.exit(1)\n    sys.exit(0)\n\n\nif __name__ == \"__main__\":\n    main()\n"
    }
}

Response

{
    "tool_response": {
        "type": "create",
        "filePath": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/full_scan.py",
        "content": "#!\/usr\/bin\/env python3\n\"\"\"\nFull Codebase Quality Scan.\n\nScannt alle PHP-Dateien gegen Pre- und Post-Hook Regeln.\nErstellt optional Tasks für Violations.\n\nUsage:\n    full_scan.py                    # Scan mit Output\n    full_scan.py --json             # JSON-Output\n    full_scan.py --create-tasks     # Tasks für Violations erstellen\n    full_scan.py --path \/src        # Nur bestimmten Pfad scannen\n\"\"\"\n\nimport argparse\nimport json\nimport os\nimport sys\nfrom pathlib import Path\nfrom typing import Dict, List, Any\n\n# Eigene Module laden\nsys.path.insert(0, str(Path(__file__).parent))\nimport pre_rules\nimport post_rules\n\n# =============================================================================\n# CONFIGURATION\n# =============================================================================\n\nDEFAULT_SCAN_PATH = \"\/var\/www\/dev.campus.systemische-tools.de\/src\"\n\nSKIP_DIRS = [\n    \"\/vendor\/\",\n    \"\/node_modules\/\",\n    \"\/.git\/\",\n    \"\/cache\/\",\n    \"\/var\/\",\n]\n\n# =============================================================================\n# SCANNER\n# =============================================================================\n\n\ndef find_php_files(base_path: str) -> List[Path]:\n    \"\"\"Findet alle PHP-Dateien im Pfad.\"\"\"\n    base = Path(base_path)\n    if not base.exists():\n        return []\n\n    files = []\n    for php_file in base.rglob(\"*.php\"):\n        file_str = str(php_file)\n        if not any(skip in file_str for skip in SKIP_DIRS):\n            files.append(php_file)\n\n    return sorted(files)\n\n\ndef scan_file(file_path: Path) -> Dict[str, Any]:\n    \"\"\"Scannt eine einzelne Datei.\"\"\"\n    try:\n        content = file_path.read_text(encoding=\"utf-8\")\n    except (OSError, UnicodeDecodeError) as e:\n        return {\n            \"file\": str(file_path),\n            \"error\": str(e),\n            \"blocks\": [],\n            \"warnings\": [],\n        }\n\n    file_str = str(file_path)\n\n    # Pre-Rules (Blocks)\n    pre_result = pre_rules.check(file_str, content)\n    blocks = []\n    if not pre_result.get(\"allowed\", True):\n        blocks.append(pre_result.get(\"message\", \"Unknown block\"))\n\n    # Post-Rules (Warnings)\n    post_result = post_rules.check(file_str, content)\n    warnings = post_result.get(\"warnings\", [])\n\n    return {\n        \"file\": file_str,\n        \"blocks\": blocks,\n        \"warnings\": warnings,\n    }\n\n\ndef scan_all(base_path: str) -> Dict[str, Any]:\n    \"\"\"Scannt alle PHP-Dateien.\"\"\"\n    files = find_php_files(base_path)\n\n    results = {\n        \"scan_path\": base_path,\n        \"total_files\": len(files),\n        \"files_with_blocks\": 0,\n        \"files_with_warnings\": 0,\n        \"total_blocks\": 0,\n        \"total_warnings\": 0,\n        \"violations\": [],\n    }\n\n    for file_path in files:\n        file_result = scan_file(file_path)\n\n        if file_result.get(\"error\"):\n            results[\"violations\"].append(file_result)\n            continue\n\n        has_issues = False\n\n        if file_result[\"blocks\"]:\n            results[\"files_with_blocks\"] += 1\n            results[\"total_blocks\"] += len(file_result[\"blocks\"])\n            has_issues = True\n\n        if file_result[\"warnings\"]:\n            results[\"files_with_warnings\"] += 1\n            results[\"total_warnings\"] += len(file_result[\"warnings\"])\n            has_issues = True\n\n        if has_issues:\n            results[\"violations\"].append(file_result)\n\n    return results\n\n\n# =============================================================================\n# OUTPUT FORMATTERS\n# =============================================================================\n\n\ndef format_console(results: Dict[str, Any]) -> str:\n    \"\"\"Formatiert Ergebnis für Console-Output.\"\"\"\n    lines = []\n    lines.append(\"=\" * 70)\n    lines.append(\"QUALITY SCAN REPORT\")\n    lines.append(\"=\" * 70)\n    lines.append(f\"Scan Path: {results['scan_path']}\")\n    lines.append(f\"Total Files: {results['total_files']}\")\n    lines.append(\"\")\n    lines.append(f\"Files with BLOCKS: {results['files_with_blocks']}\")\n    lines.append(f\"Files with WARNINGS: {results['files_with_warnings']}\")\n    lines.append(f\"Total BLOCKS: {results['total_blocks']}\")\n    lines.append(f\"Total WARNINGS: {results['total_warnings']}\")\n    lines.append(\"\")\n\n    if results[\"violations\"]:\n        lines.append(\"-\" * 70)\n        lines.append(\"VIOLATIONS:\")\n        lines.append(\"-\" * 70)\n\n        for v in results[\"violations\"]:\n            # Kurzer Pfad\n            short_path = v[\"file\"].replace(\"\/var\/www\/dev.campus.systemische-tools.de\/\", \"\")\n            lines.append(f\"\\n{short_path}\")\n\n            if v.get(\"error\"):\n                lines.append(f\"  ERROR: {v['error']}\")\n\n            for block in v.get(\"blocks\", []):\n                lines.append(f\"  [BLOCK] {block}\")\n\n            for warning in v.get(\"warnings\", []):\n                lines.append(f\"  [WARN]  {warning}\")\n\n    lines.append(\"\")\n    lines.append(\"=\" * 70)\n\n    if results[\"total_blocks\"] > 0:\n        lines.append(\"STATUS: FAILED (has blocking violations)\")\n    elif results[\"total_warnings\"] > 0:\n        lines.append(\"STATUS: PASSED with warnings\")\n    else:\n        lines.append(\"STATUS: PASSED\")\n\n    lines.append(\"=\" * 70)\n\n    return \"\\n\".join(lines)\n\n\ndef format_json(results: Dict[str, Any]) -> str:\n    \"\"\"Formatiert Ergebnis als JSON.\"\"\"\n    return json.dumps(results, indent=2, ensure_ascii=False)\n\n\n# =============================================================================\n# TASK CREATION\n# =============================================================================\n\n\ndef create_tasks_for_violations(results: Dict[str, Any]) -> List[Dict[str, Any]]:\n    \"\"\"Erstellt Tasks für alle Violations.\"\"\"\n    try:\n        import task_creator\n    except ImportError:\n        return [{\"error\": \"task_creator module not found\"}]\n\n    created = []\n\n    for v in results[\"violations\"]:\n        file_path = v[\"file\"]\n\n        for block in v.get(\"blocks\", []):\n            # Parse Rule-ID aus Message\n            rule_id = \"UNKNOWN\"\n            if \"[\" in block and \"]\" in block:\n                rule_id = block.split(\"[\")[1].split(\"]\")[0]\n\n            try:\n                task_id = task_creator.create_violation_task(\n                    file_path, rule_id, block, \"block\"\n                )\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"block\",\n                    \"task_id\": task_id,\n                })\n            except Exception as e:\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"block\",\n                    \"error\": str(e),\n                })\n\n        for warning in v.get(\"warnings\", []):\n            # Parse Rule-ID aus Warning\n            rule_id = \"UNKNOWN\"\n            if warning.startswith(\"W\") and \":\" in warning:\n                rule_id = warning.split(\":\")[0]\n\n            try:\n                task_id = task_creator.create_warning_task(file_path, rule_id, warning)\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"warning\",\n                    \"task_id\": task_id,\n                })\n            except Exception as e:\n                created.append({\n                    \"file\": file_path,\n                    \"rule\": rule_id,\n                    \"type\": \"warning\",\n                    \"error\": str(e),\n                })\n\n    return created\n\n\n# =============================================================================\n# MAIN\n# =============================================================================\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"Full Codebase Quality Scan\")\n    parser.add_argument(\n        \"--path\",\n        default=DEFAULT_SCAN_PATH,\n        help=f\"Path to scan (default: {DEFAULT_SCAN_PATH})\",\n    )\n    parser.add_argument(\n        \"--json\",\n        action=\"store_true\",\n        help=\"Output as JSON\",\n    )\n    parser.add_argument(\n        \"--create-tasks\",\n        action=\"store_true\",\n        help=\"Create tasks for violations\",\n    )\n    parser.add_argument(\n        \"--blocks-only\",\n        action=\"store_true\",\n        help=\"Only report blocking violations\",\n    )\n\n    args = parser.parse_args()\n\n    # Scan durchführen\n    results = scan_all(args.path)\n\n    # Wenn blocks-only, Warnings entfernen\n    if args.blocks_only:\n        for v in results[\"violations\"]:\n            v[\"warnings\"] = []\n        results[\"violations\"] = [\n            v for v in results[\"violations\"] if v[\"blocks\"]\n        ]\n        results[\"total_warnings\"] = 0\n        results[\"files_with_warnings\"] = 0\n\n    # Tasks erstellen wenn gewünscht\n    if args.create_tasks:\n        created_tasks = create_tasks_for_violations(results)\n        results[\"created_tasks\"] = created_tasks\n\n    # Output\n    if args.json:\n        print(format_json(results))\n    else:\n        print(format_console(results))\n        if args.create_tasks and results.get(\"created_tasks\"):\n            print(f\"\\nCreated {len(results['created_tasks'])} tasks for violations.\")\n\n    # Exit Code\n    if results[\"total_blocks\"] > 0:\n        sys.exit(1)\n    sys.exit(0)\n\n\nif __name__ == \"__main__\":\n    main()\n",
        "structuredPatch": [],
        "originalFile": null
    }
}
← Vorheriger Zur Liste Nächster →