Communitygithub.com

windows-desktop-e2e

E2E-Tests für Windows-Desktop-Apps (WPF, WinForms, Win32/MFC, Qt) mit pywinauto und Windows UI Automation.

Was ist windows-desktop-e2e?

Diese Fertigkeit ermöglicht das Schreiben und Ausführen von End-to-End-Tests für native Windows-Desktopanwendungen (WPF, WinForms, Win32/MFC, Qt) unter Verwendung von pywinauto mit dem Windows UI Automation (UIA) Backend. Sie enthält eine vollständige Projektstruktur nach dem Page-Object-Modell (POM), eine durchgängige Locator-Strategie (AutomationId > Name > ClassName > XPath), erweiterte Warte- und Screenshot-Funktionen, ein optionales Schritt-für-Schritt-Tracing zur Diagnose flaky Tests sowie CI/CD-Integration (GitHub Actions). Der Skill deckt die Unterschiede der UIA-Qualität zwischen den Frameworks ab und gibt gezielte Hinweise zur Testbarkeit (AutomationId-Vergabe). Er ist ideal für Entwickler, die Desktop-GUI-Tests automatisieren oder bestehende Test-Suiten stabilisieren möchten.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/windows-desktop-e2e

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Windows Desktop-E2E-Testing

End-to-End-Tests für native Windows-Desktopanwendungen mit pywinauto und dem Windows UI Automation (UIA) Backend. Unterstützt WPF, WinForms, Win32/MFC und Qt (5.x / 6.x) — mit einem eigenen Abschnitt für Qt-spezifische Anleitungen.

Wann aktivieren

  • Schreiben oder Ausführen von E2E-Tests für eine native Windows-Desktopanwendung
  • Einrichten einer Desktop-GUI-Testsuite von Grund auf
  • Diagnose flaky oder fehlschlagender Desktop-Automatisierungstests
  • Hinzufügen von Testbarkeit (AutomationId, barrierefreie Namen) zu einer bestehenden App
  • Integration von Desktop-E2E in eine CI/CD-Pipeline (GitHub Actions windows-latest)

Wann NICHT verwenden

  • Webanwendungen → Fertigkeit e2e-testing (Playwright) verwenden
  • Electron / CEF / WebView2-Apps → die HTML-Schicht benötigt Browser-Automation, nicht UIA
  • Mobile Apps → plattformspezifische Tools verwenden (UIAutomator, XCUITest)
  • Reine Unit- oder Integrationstests, die keine laufende GUI benötigen

Grundlegende Konzepte

Jede Windows-Desktop-Automation basiert auf UI Automation (UIA), einer in Windows integrierten barrierefreien API. Jedes unterstützte Framework stellt einen Baum von UIA-Elementen mit Eigenschaften bereit, die Claude lesen und darauf reagieren kann:

Ihr Test (Python)
    └── pywinauto (UIA-Backend)
        └── Windows-UI-Automation-API   ← in Windows integriert, framework-unabhängig
            └── UIA-Anbieter der App     ← jedes Framework liefert seinen eigenen
                └── Ausführbare .exe

UIA-Qualität nach Framework:

FrameworkAutomationIdZuverlässigkeitHinweise
WPF5/5Hervorragendx:Name wird direkt auf AutomationId abgebildet
WinForms4/5GutAccessibleName = AutomationId
UWP / WinUI 35/5HervorragendVolle Microsoft-Unterstützung
Qt 6.x5/5HervorragendBarrierefreiheit standardmäßig aktiviert; Klassennamen ändern sich zu Qt6*
Qt 5.15+4/5GutVerbessertes Accessibility-Modul
Qt 5.7–5.143/5MittelBenötigt QT_ACCESSIBILITY=1; objectName manuell
Win32 / MFC3/5MittelSteuerelement-IDs zugänglich; Textabgleich üblich

Einrichtung und Voraussetzungen

# Python 3.8+, nur Windows
pip install pywinauto pytest pytest-html Pillow pytest-timeout
# Optional: Bildschirmaufzeichnung
# ffmpeg installieren und zum PATH hinzufügen: https://ffmpeg.org/download.html

Überprüfen, ob UIA erreichbar ist:

from pywinauto import Desktop
Desktop(backend="uia").windows()  # listet alle Top-Level-Fenster

Accessibility Insights for Windows installieren (kostenlos, von Microsoft) — Ihr DevTools-Äquivalent zum Inspizieren des UIA-Elementbaums, bevor Sie einen Test schreiben.

Einrichtung der Testbarkeit (nach Framework)

Das Wichtigste, was Sie tun können, ist, jedem interaktiven Steuerelement vor dem Schreiben von Tests eine stabile AutomationId zu geben.

WPF

<!-- XAML: x:Name wird automatisch zur AutomationId -->
<TextBox x:Name="usernameInput" />
<PasswordBox x:Name="passwordInput" />
<Button x:Name="btnLogin" Content="Anmelden" />
<TextBlock x:Name="lblError" />

WinForms

// Im Designer oder Code festlegen
usernameInput.AccessibleName = "usernameInput";
passwordInput.AccessibleName = "passwordInput";
btnLogin.AccessibleName = "btnLogin";
lblError.AccessibleName = "lblError";

Win32 / MFC

// Steuerelement-Ressourcen-IDs in der .rc-Datei werden als AutomationId-Strings bereitgestellt
// IDC_EDIT_USERNAME -> AutomationId "1001"
// SetWindowText für Name bevorzugen; IAccessible für umfangreichere Unterstützung hinzufügen

Qt — siehe dedizierten Abschnitt unten


Page-Object-Modell

tests/
├── conftest.py          # App-Start-Fixture, Fehler-Screenshot
├── pytest.ini
├── config.py
├── pages/
│   ├── __init__.py      # für Importe erforderlich
│   ├── base_page.py     # Locators, Warten, Screenshot-Helfer
│   ├── login_page.py
│   └── main_page.py
├── tests/
│   ├── __init__.py
│   ├── test_login.py
│   └── test_main_flow.py
└── artifacts/           # Screenshots, Videos, Logs

base_page.py

import os, time
from pywinauto import Desktop
from config import ACTION_TIMEOUT, ARTIFACT_DIR

class BasePage:
    def __init__(self, window):
        self.window = window

    # --- Locators (Prioritätsreihenfolge) ---

    def by_id(self, auto_id, **kw):
        """AutomationId — am stabilsten. Als erste Wahl verwenden."""
        return self.window.child_window(auto_id=auto_id, **kw)

    def by_name(self, name, **kw):
        """Sichtbarer Text / barrierefreier Name."""
        return self.window.child_window(title=name, **kw)

    def by_class(self, cls, index=0, **kw):
        """Steuerelementklasse + Index — instabil, wenn möglich vermeiden."""
        return self.window.child_window(class_name=cls, found_index=index, **kw)

    # --- Warten ---

    def wait_visible(self, spec, timeout=ACTION_TIMEOUT):
        spec.wait("visible", timeout=timeout)
        return spec

    def wait_gone(self, spec, timeout=ACTION_TIMEOUT):
        spec.wait_not("visible", timeout=timeout)
        return spec

    def wait_window(self, title, timeout=ACTION_TIMEOUT):
        """Auf ein neues Top-Level-Fenster warten (Dialoge, Unterfenster)."""
        dlg = Desktop(backend="uia").window(title=title)
        dlg.wait("visible", timeout=timeout)
        return dlg

    def wait_until(self, fn, timeout=ACTION_TIMEOUT, interval=0.3):
        """Auf eine beliebige Bedingung warten — verwenden, wenn UIA-Ereignisse unzuverlässig sind."""
        deadline = time.time() + timeout
        while time.time() < deadline:
            try:
                if fn():
                    return True
            except Exception:
                pass
            time.sleep(interval)
        raise TimeoutError(f"Bedingung nicht innerhalb von {timeout}s erfüllt")

    # --- Aktionen ---

    def click(self, spec):
        self.wait_visible(spec)
        spec.click_input()

    def type_text(self, spec, text):
        self.wait_visible(spec)
        ctrl = spec.wrapper_object()
        try:
            ctrl.set_edit_text(text)
        except Exception as e:
            # Qt 5.x Fallback: UIA-Wertmuster kann unvollständig sein
            import sys, pywinauto.keyboard as kb
            print(f"[windows-desktop-e2e] set_edit_text fehlgeschlagen ({e}), verwende Tastatur-Fallback", file=sys.stderr)
            ctrl.click_input()
            kb.send_keys("^a")
            kb.send_keys(text, with_spaces=True)

    def get_text(self, spec):
        ctrl = spec.wrapper_object()
        for attr in ("window_text", "get_value"):
            try:
                v = getattr(ctrl, attr)()
                if v:
                    return v
            except Exception:
                pass
        return ""

    # --- Artefakte ---

    def screenshot(self, name):
        os.makedirs(ARTIFACT_DIR, exist_ok=True)
        path = os.path.join(ARTIFACT_DIR, f"{name}.png")
        self.window.capture_as_image().save(path)
        return path

login_page.py

from pages.base_page import BasePage

class LoginPage(BasePage):
    @property
    def username(self): return self.by_id("usernameInput")

    @property
    def password(self): return self.by_id("passwordInput")

    @property
    def btn_login(self): return self.by_id("btnLogin")

    @property
    def error_label(self): return self.by_id("lblError")

    def login(self, user, pwd):
        self.type_text(self.username, user)
        self.type_text(self.password, pwd)
        self.click(self.btn_login)

    def login_ok(self, user, pwd, main_title="Hauptfenster"):
        self.login(user, pwd)
        return self.wait_window(main_title)

    def login_fail(self, user, pwd):
        self.login(user, pwd)
        self.wait_visible(self.error_label)
        return self.get_text(self.error_label)

conftest.py

Für neue Projekte bevorzugen Sie die Tier-1-Sandbox-Fixture (siehe unten) — sie fügt Dateisystemisolierung ohne zusätzliche Kosten hinzu. Diese grundlegende Fixture ist nur für minimale/ Legacy-Einrichtungen gedacht.

import os, pytest
os.environ["QT_ACCESSIBILITY"] = "1"  # Erforderlich für Qt 5.x UIA-Unterstützung

from pywinauto import Application
from config import APP_PATH, MAIN_WINDOW_TITLE, LAUNCH_TIMEOUT, ARTIFACT_DIR

@pytest.fixture
def app(request):
    if not APP_PATH:
        pytest.exit("APP_PATH-Umgebungsvariable ist nicht gesetzt", returncode=1)
    proc = Application(backend="uia").start(APP_PATH, timeout=LAUNCH_TIMEOUT)
    win  = proc.window(title=MAIN_WINDOW_TITLE)
    win.wait("visible", timeout=LAUNCH_TIMEOUT)
    yield win
    # Screenshot bei Fehler
    if getattr(getattr(request.node, "rep_call", None), "failed", False):
        os.makedirs(ARTIFACT_DIR, exist_ok=True)
        try:
            win.capture_as_image().save(
                os.path.join(ARTIFACT_DIR, f"FAIL_{request.node.name}.png")
            )
        except Exception:
            pass
    # Zuerst sauber beenden, dann notfalls killen
    # proc ist eine pywinauto Application — wait_for_process_exit() verwenden, nicht wait_for_process()
    try:
        win.close()
        proc.wait_for_process_exit(timeout=5)
    except Exception:
        proc.kill()

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    outcome = yield
    setattr(item, f"rep_{outcome.get_result().when}", outcome.get_result())

config.py

import os
APP_PATH          = os.environ.get("APP_PATH", "")           # über env setzen — kein Standardpfad
MAIN_WINDOW_TITLE = os.environ.get("APP_TITLE", "")
LAUNCH_TIMEOUT    = int(os.environ.get("LAUNCH_TIMEOUT", "15"))
ACTION_TIMEOUT    = int(os.environ.get("ACTION_TIMEOUT", "10"))
ARTIFACT_DIR      = os.path.join(os.path.dirname(__file__), "artifacts")

pytest.ini

[pytest]
testpaths = tests
markers =
    smoke: schnelle Smoke-Tests für kritische Pfade
    flaky: bekannte instabile Tests
addopts = -v --tb=short --html=artifacts/report.html --self-contained-html

Locator-Strategie

AutomationId  >  Name (Text)  >  ClassName + Index  >  XPath
  (stabil)         (lesbar)         (instabil)          (letzter Ausweg)

Mit Accessibility Insights inspizieren → Bereich Eigenschaften → zuerst nach AutomationId suchen.

# Zur Laufzeit inspizieren — in ein REPL einfügen, um den Baum zu erkunden
win.print_control_identifiers()
# oder den Bereich eingrenzen:
win.child_window(auto_id="groupBox1").print_control_identifiers()

Wartemuster

# Auf ein Steuerelement warten
page.wait_visible(page.by_id("statusLabel"))

# Warten, bis ein Steuerelement verschwindet (z. B. Lade-Spinner)
page.wait_gone(page.by_id("spinnerOverlay"))

# Auf ein Dialogfenster warten
dlg = page.wait_window("Löschen bestätigen")

# Benutzerdefinierte Bedingung (z. B. Textänderungen)
page.wait_until(lambda: page.get_text(page.by_id("lblStatus")) == "Bereit")

Verwenden Sie niemals time.sleep() als primäre Synchronisation — verwenden Sie wait() oder wait_until().

Artefaktverwaltung

# Screenshot bei Bedarf
page.screenshot("after_login")

# Vollbildaufnahme (wenn das Fenster außerhalb des Bildschirms oder minimiert ist)
import pyautogui
pyautogui.screenshot("artifacts/fullscreen.png")

# Bildschirmaufzeichnung mit ffmpeg (vor dem Test starten, nach dem Test stoppen)
import subprocess

def start_recording(name):
    return subprocess.Popen([
        "ffmpeg", "-f", "gdigrab", "-framerate", "10",
        "-i", "desktop", "-y", f"artifacts/videos/{name}.mp4"
    ], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def stop_recording(proc):
    proc.stdin.write(b"q"); proc.stdin.flush(); proc.wait(timeout=10)

Schritt-für-Schritt-Ablaufverfolgung (opt-in)

Der Standard-Fehler-Screenshot ist oft zu dünn, um flaky Tests zu diagnostizieren. Die untenstehende Schritt-für-Schritt-Ablaufverfolgung ist standardmäßig deaktiviert — aktivieren Sie sie nur, wenn Sie einen flaky Fall reproduzieren möchten.

Aktivieren

E2E_TRACE=1 pytest tests/test_login.py -v
# Getippten Text in das JSONL-Log aufnehmen (NICHT bei Tests verwenden, die Anmeldedaten/PII eingeben):
E2E_TRACE=1 E2E_TRACE_INCLUDE_TEXT=1 pytest ...

In BasePage einfügen

import os, json, time
TRACE_ENABLED      = os.environ.get("E2E_TRACE") == "1"
TRACE_INCLUDE_TEXT = os.environ.get("E2E_TRACE_INCLUDE_TEXT") == "1"

class BasePage:
    _step = 0

    def _trace(self, action, spec=None, text=None):
        if not TRACE_ENABLED:
            return
        BasePage._step += 1
        idx = f"{BasePage._step:03d}"
        os.makedirs(ARTIFACT_DIR, exist_ok=True)
        try:
            self.window.capture_as_image().save(
                os.path.join(ARTIFACT_DIR, f"step_{idx}_{action}.png"))
        except Exception:
            pass  # Fehler bei der Aufnahme darf den Test nicht unterbrechen
        rec = {
            "ts": time.time(), "step": BasePage._step, "action": action,
            "locator": getattr(spec, "criteria", None),
            "text": text if TRACE_INCLUDE_TEXT else ("<redacted>" if text else None),
        }
        with open(os.path.join(ARTIFACT_DIR, "trace.jsonl"), "a") as f:
            f.write(json.dumps(rec) + "\n")

    def click(self, spec):
        self.wait_visible(spec); self._trace("click_before", spec)
        spec.click_input();      self._trace("click_after",  spec)

    def type_text(self, spec, text):
        self.wait_visible(spec); self._trace("type_before", spec, text)
        # ... bestehender set_edit_text / Tastatur-Fallback ...
        self._trace("type_after", spec)

Einschränkungen

  • PII / Anmeldedaten: Der Inhalt von type_text ist standardmäßig <redacted>. Setzen Sie E2E_TRACE_INCLUDE_TEXT=1 niemals bei Anmelde- oder Zahlungsvorgängen.
  • Overhead: ~50–200ms pro Aktion + ein PNG pro Schritt auf der Festplatte. Nicht in der standardmäßigen CI-Matrix aktivieren — nur in einem dedizierten Job zur Flaky-Reproduktion.
  • Artefaktaufblähung: Ein langer Ablauf produziert dutzende MB; passen Sie retention-days entsprechend an.
  • Parallel-/Wiederholungshygiene: Dieses einfache Beispiel hängt an trace.jsonl an und verwendet einen Klassen-Zähler. Leeren Sie das Artefaktverzeichnis vor Wiederholungen und verwenden Sie für parallele Tests pro-Worker-Artefaktverzeichnisse.
  • Abdeckungslücke: Aktionen, die außerhalb von BasePage ausgeführt werden (reine pywinauto-Aufrufe im Testcode), werden nicht verfolgt.

Umgang mit flaky Tests

# Quarantäne — entspricht Playwrights test.fixme()
@pytest.mark.skip(reason="Flaky: Animationswettlauf auf langsamer CI. Issue #42")
def test_animated_transition(self, app): ...

# Überspringen, wenn eine Bedingung nicht erfüllt ist
@pytest.mark.skipif("os.environ.get('CI') == 'true' and os.environ.get('RUNNER_DEBUG') != '1'", reason="Nicht reproduzierbar im CI ohne Debug-Modus")
def test_unstable_feature(self, app): ...

Wenn alles andere fehlschlägt: starten Sie die App mit der Tier-1-Sandbox-Fixture (siehe separates Hilfsblatt), die eine vollständige Dateisystem-, Registrierungs- und Prozessisolierung mit Sandboxie Plus hinzufügt.


Qt-spezifische Anleitung

Qt 6.x

// CMakeLists.txt — Qt6 ist standardmäßig barrierefrei
find_package(Qt6 REQUIRED COMPONENTS Widgets)

// Die QAccessible-Schnittstelle ist standardmäßig aktiviert.
// QWidget::setObjectName() wird zu AutomationId.
ui->usernameEdit->setObjectName("usernameEdit");
ui->passwordEdit->setObjectName("passwordEdit");
ui->loginButton->setObjectName("loginButton");
ui->statusLabel->setObjectName("statusLabel");

Verwenden Sie Accessible Rich Internet Applications (ARIA)-Attribute, wenn Sie QML für Qt Quick / Qt Quick Controls 2 haben.

Qt 5.x (5.15+ empfohlen)

# Python-Testcode — zuerst aktivieren
os.environ["QT_ACCESSIBILITY"] = "1"
// C++-Anwendungscode
#include <QAccessible>
// Stellen Sie sicher, dass das Qt5-Plug-in accessiblebridge geladen ist
// (standardmäßig auf Windows enthalten)

Wichtige Kompromisse bei Qt 5:

  • QComboBox-Dropdowns öffnen sich möglicherweise als untergeordnete Fenster; verwenden Sie wait_window("Name", um sie zu erfassen.
  • Klassenname ändert sich zwischen Qt5 und Qt6: QLineEdit → Qt5QLineEdit oder Qt6QLineEdit. Verlassen Sie sich nicht auf Klassennamen.
  • ValuePattern für QLineEdit: pywinautos set_edit_text() kann fehlschlagen; der oben gezeigte Tastatur-Fallback in BasePage.type_text() funktioniert zuverlässig.
  • set_edit_text() funktioniert korrekt mit QPlainTextEdit und QTextEdit, aber für QLineEdit kann das Value Pattern fehlen, wenn das Qt-Plug-in nicht richtig geladen ist.

CI/CD: GitHub Actions

name: Desktop E2E
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
          cache: "pip"
          cache-dependency-path: "**/requirements*.txt"

      - run: pip install pywinauto pytest pytest-html Pillow

      - name: E2E-Tests ausführen
        env:
          APP_PATH: ./MyApp/bin/Release/MyApp.exe
          APP_TITLE: MyApp
          LAUNCH_TIMEOUT: 30
          ACTION_TIMEOUT: 15
        run: pytest tests/ -v --tb=short --html=artifacts/report.html --self-contained-html

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: e2e-artifacts
          path: artifacts/
          retention-days: 7

Wichtige CI-Hinweise:

  1. Windows-Image: windows-latest enthält .NET Desktop Runtime, C++ Redistributables und Qt-Runtime (falls Teil der Abhängigkeiten).
  2. GPU vs CPU: Standard-GitHub-Runner haben keine GPU; wenn Ihre App GPU-Rendering benötigt (z. B. DirectX), verwenden Sie windows-latest (CPU) oder selbst gehostete Runner. Software-Rendering-Flags (z. B. QT_QUICK_BACKEND=software) können helfen.
  3. Dienste: Wenn Ihre App einen SQL Server/Lokal-/Cloud-Dienst benötigt, starten Sie ihn in einem vorherigen Schritt. pywinauto interagiert nur mit sichtbaren Fenstern — planen Sie getrennte Tests für die Dienstlogik.
  4. Timeout: Erhöhen Sie LAUNCH_TIMEOUT in CI auf 30 s (kann bei kaltem Cache länger dauern).
  5. Bildschirmauflösung: Standard-Runner verwenden 1024×768; Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name 'ScreenSaveActive' -Value '0' kann helfen, Bildschirmschoner zu verhindern. Verwenden Sie pyautogui.size(), um die Auflösung vor dem Ausführen von Vollbildaktionen zu überprüfen.

Fehlerbehebung

SymptomWahrscheinliche UrsacheLösung
ElementNotFoundException für AutoIdAutomationId in der App nicht gesetztTestbarkeit einrichten (siehe Abschnitt oben). Mit Accessibility Insights prüfen.
set_edit_text() wirft AusnahmeQt 5.x / unvollständiges UIA-ValuePatternDer Tastatur-Fallback in BasePage.type_text() wird automatisch ausgelöst. Wenn nicht, App-Code prüfen.
Fenstertitel wird nicht abgeglichenUnicode-Zeichen / unsichtbare Steuerzeichenrepr(win.window_text()) drucken, um den genauen String zu sehen. Verwenden Sie Teilübereinstimmungen: window(title_re=".*Anmeldung.*").
Zeitüberschreitung beim Start in CIApp stürzt ab / hängt / benötigt AdminPrüfen Sie die Ereignisanzeige auf Abstürze. Verwenden Sie start(…), wait(„visible“) — nicht run(…). Wenn die App Admin benötigt, starten Sie den Runner als Administrator.
Klassennamen ändern sich zwischen Qt5/Qt6Qt benennt interne Klassen umVerwenden Sie AutomationId statt Klassennamen. Wenn Sie Klassennamen verwenden müssen, prüfen Sie beide Varianten.

Leistung: UIA-Tipps

  • Geschwindigkeit: UIA ist langsamer als WinForms Backend (~5–20ms vs ~1ms), aber viel zuverlässiger. Der Kompromiss lohnt sich.
  • Reduzieren Sie die Anzahl der Elemente: Wenn Ihr Fenster Tausende von UIA-Knoten hat (z. B. ein Datenraster), verwenden Sie found_index=0 + Klassenname, um die erste Übereinstimmung zu erhalten, anstatt den gesamten Baum zu durchsuchen.
  • Desktop-Objekt zwischen den Tests zwischenspeichern: Wenn Sie viele Tests haben, weisen Sie `Desktop(backend=

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Verwandte Skills