Protokoll #27883

ID27883
Zeitstempel2025-12-28 12:32:53.358138
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuspending
Tokens1,522 (Input: 1,522, Output: 0)
Dauer-
Request-Zeit2025-12-28 12:32:53.358138
Response-Zeit-

Request

{
    "event": "PostToolUse",
    "tool_name": "Read",
    "tool_response": {
        "type": "text",
        "file": {
            "filePath": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/task_hook.py",
            "content": "#!\/usr\/bin\/env python3\n\"\"\"\nTask Hook für Claude Code\nErstellt automatisch Tasks aus bestimmten Patterns in User-Prompts\n\nErkannte Patterns:\n- TODO: <text>\n- TASK: <text>\n- @task <text>\n- #task <text>\n\"\"\"\n\nimport json\nimport os\nimport sys\nimport re\nimport uuid\nimport pymysql\nfrom pathlib import Path\nfrom datetime import datetime\nfrom typing import Dict, Any, Optional, List\n\n# .env aus Hook-Verzeichnis laden\nfrom dotenv import load_dotenv\nload_dotenv(Path(__file__).parent \/ '.env')\n\n# Konfiguration aus Environment-Variablen\nDB_CONFIG = {\n    'host': os.environ.get('CLAUDE_DB_HOST', 'localhost'),\n    'port': int(os.environ.get('CLAUDE_DB_PORT', '3306')),\n    'user': os.environ.get('CLAUDE_DB_USER', 'root'),\n    'password': os.environ.get('CLAUDE_DB_PASSWORD', ''),\n    'database': os.environ.get('CLAUDE_DB_NAME', 'ki_dev'),\n    'charset': 'utf8mb4'\n}\n\n# Task-Erkennungsmuster\nTASK_PATTERNS = [\n    (re.compile(r'TODO:\\s*(.+?)(?:\\n|$)', re.IGNORECASE), 'todo'),\n    (re.compile(r'TASK:\\s*(.+?)(?:\\n|$)', re.IGNORECASE), 'task'),\n    (re.compile(r'@task\\s+(.+?)(?:\\n|$)', re.IGNORECASE), 'mention'),\n    (re.compile(r'#task\\s+(.+?)(?:\\n|$)', re.IGNORECASE), 'hashtag'),\n]\n\n\ndef get_connection():\n    \"\"\"Erstellt Datenbankverbindung\"\"\"\n    return pymysql.connect(**DB_CONFIG)\n\n\ndef generate_uuid() -> str:\n    \"\"\"Generiert eine UUID\"\"\"\n    return str(uuid.uuid4())\n\n\ndef extract_tasks(text: str) -> List[Dict[str, str]]:\n    \"\"\"Extrahiert Tasks aus Text\"\"\"\n    tasks = []\n\n    for pattern, source in TASK_PATTERNS:\n        matches = pattern.findall(text)\n        for match in matches:\n            title = match.strip()\n            if title and len(title) >= 3:  # Mindestlänge\n                tasks.append({\n                    'title': title[:255],  # Max 255 Zeichen\n                    'source': source\n                })\n\n    return tasks\n\n\ndef create_task(title: str, description: str, created_by: str) -> Optional[int]:\n    \"\"\"Erstellt einen neuen Task in der Datenbank\"\"\"\n    try:\n        connection = get_connection()\n\n        with connection.cursor() as cursor:\n            task_uuid = generate_uuid()\n            now = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')\n\n            sql = \"\"\"\n                INSERT INTO tasks (\n                    uuid, title, description, type, priority, status,\n                    created_by, created_by_type, created_at, updated_at\n                ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n            \"\"\"\n\n            cursor.execute(sql, (\n                task_uuid,\n                title,\n                description,\n                'ai_task',\n                'medium',\n                'pending',\n                created_by,\n                'ai',\n                now,\n                now\n            ))\n\n            task_id = cursor.lastrowid\n\n            # Kommentar hinzufügen\n            comment_sql = \"\"\"\n                INSERT INTO task_comments (\n                    task_id, author, author_type, comment_type, content, metadata, created_at\n                ) VALUES (%s, %s, %s, %s, %s, %s, %s)\n            \"\"\"\n\n            cursor.execute(comment_sql, (\n                task_id,\n                'claude-code-hook',\n                'system',\n                'note',\n                'Task automatisch aus User-Prompt erstellt',\n                json.dumps({'source': 'task_hook', 'pattern': 'auto-detect'}),\n                now\n            ))\n\n            connection.commit()\n            return task_id\n\n    except Exception as e:\n        print(f\"Task creation error: {e}\", file=sys.stderr)\n        return None\n    finally:\n        if 'connection' in locals():\n            connection.close()\n\n\ndef process_event(data: Dict[str, Any]) -> None:\n    \"\"\"Verarbeitet ein Claude Code Event\"\"\"\n    event_name = data.get('hook_event_name', '')\n\n    # Nur UserPromptSubmit verarbeiten\n    if event_name != 'UserPromptSubmit':\n        return\n\n    # Prompt aus verschiedenen Stellen extrahieren\n    prompt = ''\n\n    if 'prompt' in data:\n        prompt = data['prompt']\n    elif 'tool_input' in data and isinstance(data['tool_input'], dict):\n        prompt = data['tool_input'].get('prompt', '')\n        prompt += ' ' + data['tool_input'].get('message', '')\n\n    if not prompt:\n        return\n\n    # Tasks extrahieren\n    tasks = extract_tasks(prompt)\n\n    if not tasks:\n        return\n\n    # User ermitteln\n    created_by = os.environ.get('USER', 'claude-code-hook')\n\n    # Tasks erstellen\n    created_count = 0\n    for task in tasks:\n        task_id = create_task(\n            title=task['title'],\n            description=f\"Auto-created from {task['source']} pattern in Claude Code prompt\",\n            created_by=created_by\n        )\n        if task_id:\n            created_count += 1\n            print(f\"Task #{task_id} created: {task['title'][:50]}...\", file=sys.stderr)\n\n    if created_count > 0:\n        print(f\"Created {created_count} task(s) from prompt\", file=sys.stderr)\n\n\ndef main():\n    \"\"\"Hauptfunktion\"\"\"\n    try:\n        # Input von stdin lesen\n        input_data = json.load(sys.stdin)\n\n        # Event verarbeiten\n        process_event(input_data)\n\n        # Immer continue zurückgeben (non-blocking)\n        print(json.dumps({\"continue\": True}))\n        sys.exit(0)\n\n    except json.JSONDecodeError as e:\n        print(f\"JSON decode error: {e}\", file=sys.stderr)\n        print(json.dumps({\"continue\": True}))\n        sys.exit(0)\n    except Exception as e:\n        print(f\"Hook error: {e}\", file=sys.stderr)\n        print(json.dumps({\"continue\": True}))\n        sys.exit(0)\n\n\nif __name__ == '__main__':\n    main()\n",
            "numLines": 202,
            "startLine": 1,
            "totalLines": 202
        }
    }
}

Response

-
← Vorheriger Zur Liste Nächster →