> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Erstelle einen Mod

> Lasse Claude einen Claude Code Mod aus einer Beschreibung schreiben, oder schreibe selbst einen, der Werkzeugaufrufe zählt und einen Befehl hinzufügt. Lerne die Reload- und Validierungsschleife.

Ein Mod ist ein Claude Code [Plugin](/docs/de/plugins/overview) mit einer Eingabedatei, genannt das Hooks-Modul: eine JavaScript- oder TypeScript-Datei, deren Funktionen Claude Code aufruft, wenn Ereignisse auftreten. Es gibt zwei Möglichkeiten, einen zu erstellen:

* **Claude bitten, ihn zu schreiben**: [beschreibe, was du möchtest](#ask-claude-for-a-mod) in einer Claude Code Sitzung
* **Schreibe ihn selbst**: [folge dem Tutorial](#write-a-mod-yourself), um zu lernen, wie der Code eines Mods funktioniert. Du brauchst Node.js, einen Bundler oder einen Build-Schritt nicht, da Claude Code `.js` und `.ts` Dateien direkt lädt.

Wenn du dich noch nicht entschieden hast, ob ein Mod das richtige Werkzeug ist, lies zuerst den [Vergleich in der Übersicht](/docs/de/plugins/mods/overview#compare-mods-settings-hooks-skills-and-mcp-servers).

<Note>
  Mods erfordern Claude Code v2.1.287 oder später. Führe in deiner Shell `claude --version` aus, um dies zu überprüfen. Um zu sehen, ob Mods für dich geladen werden können, siehe [Überprüfe, ob Mods geladen werden können](/docs/de/plugins/mods/troubleshoot#check-whether-mods-can-load).
</Note>

<h2 id="ask-claude-for-a-mod">
  Claude um einen Mod bitten
</h2>

Beschreibe den Mod, den du möchtest, in einer interaktiven Claude Code Sitzung, und Claude schreibt ihn. Claude arbeitet von einer integrierten [Skill](/docs/de/skills) namens `plugin-authoring`, die ihm sagt, wo der Mod geschrieben werden soll, welche Ereignisse und Methoden deine Version hat, und wie der Mod geladen wird. Claude kann die Skill laden, wenn du um einen Mod bittest, oder du kannst sie selbst laden, indem du `/plugin-authoring` an der Claude Code Eingabeaufforderung ausführst.

Der Mod wird ausgeführt, sobald du ihn genehmigst, außer in [Sitzungen, in denen ein von Claude geschriebener Mod nicht geladen werden kann](#sessions-that-skip-the-approval).

<Steps>
  <Step title="Beschreibe den Mod">
    Bitte um den Mod in deinen eigenen Worten, zum Beispiel `make a mod that shows the current git branch above the prompt`. Claude schreibt den Mod in einem eigenen Verzeichnis im Mods-Ordner der Sitzung, das `~/.claude/dev-mods/` gefolgt von der Sitzungs-ID ist. Der vollständige Pfad eines Mods sieht wie `~/.claude/dev-mods/3f2a9c1e-5b7d-4e8a-9c21-6d0f4b8a7e13/git-branch/` aus.

    <Note>
      In den [Berechtigungsmodi](/docs/de/permission-modes#protected-paths) `default` und `acceptEdits` fragt Claude Code, bevor Claude jede der Dateien des Mods erstellt, da `~/.claude` ein geschützter Pfad ist. Genehmige jede Datei, wenn sie auftaucht.
    </Note>
  </Step>

  <Step title="Genehmige den Mod">
    Wenn Claude die erste Datei speichert, fragt Claude Code, ob Hot Reloading für die Sitzung aktiviert werden soll. Hot Reloading führt die Mods aus, die Claude in dieser Sitzung schreibt, und nimmt jede spätere Änderung auf.

    Wähle eine dieser Antworten:

    * **Für diese Sitzung aktivieren**: Die Mods im Mods-Ordner der Sitzung werden geladen, wenn die Runde endet, und werden am Ende jeder Runde neu geladen, die sie ändert. Deine Antwort gilt für die Sitzung, auch nachdem du sie fortgesetzt hast.
    * **Nicht jetzt**: Nichts wird jetzt geladen. Die Dateien bleiben dort, wo Claude sie geschrieben hat, und die Mods werden beim nächsten Start dieser Sitzung geladen. Um zu verhindern, dass ein Mod jemals geladen wird, lösche sein Verzeichnis.
  </Step>

  <Step title="Überprüfe, dass der Mod geladen wurde">
    Führe `/plugin` an der Claude Code Eingabeaufforderung aus und drücke Tab, bis die Registerkarte **Installed** ausgewählt ist. Sie listet den Mod auf, und du kannst ihn dort ausschalten.
  </Step>

  <Step title="Probiere den Mod aus">
    Nutze das, worum du gebeten hast. Für die Beispiel-Eingabeaufforderung erscheint der aktuelle Branchname über dem Eingabefeld. Wenn der Mod nicht das tut, was du wolltest, sag Claude, was geändert werden soll. Der Mod wird am Ende jeder Runde neu geladen, die seine Dateien ändert, sodass du die Änderung ausprobieren kannst, sobald Claude fertig ist.
  </Step>
</Steps>

<h3 id="use-the-mod-in-other-sessions">
  Verwende den Mod in anderen Sitzungen
</h3>

Ein Mod, den Claude geschrieben hat, wird nur in der Sitzung geladen, die ihn erstellt hat, und Claude Code löscht den Mods-Ordner dieser Sitzung, sobald er älter als [`cleanupPeriodDays`](/docs/de/settings-reference#cleanupperioddays) ist. Um den Mod zu behalten, kopiere sein Verzeichnis aus dem Mods-Ordner an einen Ort deiner Wahl, z. B. `~/mods/git-branch`. Wähle dann, wie du ihn laden möchtest:

* **In einer Sitzung, die du startest**: Führe in deiner Shell `claude --plugin-dir ~/mods/git-branch` aus
* **Für andere Personen**: [Füge ihn zu einem Marketplace hinzu](#share-your-mod), damit sie ihn installieren können

<h3 id="sessions-that-skip-the-approval">
  Sitzungen, in denen ein von Claude geschriebener Mod nicht geladen werden kann
</h3>

Ein Mod, den Claude schreibt, wird nur geladen, nachdem du ihn genehmigt hast, in einem vertrauenswürdigen Arbeitsbereich, in dem Mods ausgeführt werden dürfen. In diesen Sitzungen wird er nicht geladen:

* **Niemand ist da, um zu genehmigen**: Die Sitzung kann dir keine Eingabeaufforderung anzeigen, wie in einem `claude -p` Lauf oder im [`dontAsk` Modus](/docs/de/permission-modes)
* **Der Arbeitsbereich ist nicht vertrauenswürdig**: Du hast die Vertrauensaufforderung für das Verzeichnis nicht akzeptiert
* **Mods sind gestoppt**: Du hast mit `--safe-mode` oder `--bare` gestartet, du hast `disableAllHooks` gesetzt, oder die [verwalteten Einstellungen](/docs/de/plugins/mods/admin#choose-how-much-to-allow) deiner Organisation blockieren es

<h2 id="write-a-mod-yourself">
  Schreibe einen Mod selbst
</h2>

In diesem Tutorial erstellst du einen Mod namens `first-mod`, der die Werkzeugaufrufe zählt, die Claude macht, die Anzahl neben dem Spinner anzeigt, während Claude arbeitet, und einen `/tally` Befehl hinzufügt, der sie ausdruckt. Dann liest du die Typdeklarationen, die Claude Code neben deinem Mod schreibt, und führst `claude plugin validate` aus. Zusammen zeigen sie dir die Ereignisse und Methoden, die deine Version bietet, und was Claude Code aus deinem Code liest.

Diese Aufzeichnung zeigt den fertigen Mod. Der Spinner zählt Werkzeugaufrufe, `/tally` druckt die Anzahl, und eine Bearbeitung des Codes wird wirksam, während die Sitzung läuft:

<Frame>
  <video autoPlay muted loop playsInline controls className="w-full dark:hidden" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-first-mod-light.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=eb561134afa90375777408453ba51c77" aria-label="In a Claude Code session, the prompt 'list the files here and read the README' is typed and sent. The spinner reads 'Thinking · tool calls: 1' and the count rises as Claude works. The /tally command prints 'first-mod: Claude has made 3 tool calls since this mod loaded'. A line says first-mod reloaded and lists its four hooks. On the next prompt the spinner reads 'Thinking · tools used: 1'." data-path="images/mods-first-mod-light.mp4" />

  <video autoPlay muted loop playsInline controls className="w-full hidden dark:block" src="https://mintcdn.com/claude-code/dgiVO_Od1X1faduV/images/mods-first-mod-dark.mp4?fit=max&auto=format&n=dgiVO_Od1X1faduV&q=85&s=09779dadc7ef66c2b1e2da0c2e31ac72" aria-label="In a Claude Code session, the prompt 'list the files here and read the README' is typed and sent. The spinner reads 'Thinking · tool calls: 1' and the count rises as Claude works. The /tally command prints 'first-mod: Claude has made 3 tool calls since this mod loaded'. A line says first-mod reloaded and lists its four hooks. On the next prompt the spinner reads 'Thinking · tools used: 1'." data-path="images/mods-first-mod-dark.mp4" />
</Frame>

Du schreibst drei Dateien:

```text theme={null}
first-mod/
├── .claude-plugin/
│   └── plugin.json
└── hooks/
    ├── hooks.json
    └── register.js
```

* **`plugin.json`**: das [Manifest](/docs/de/plugins/manifest-reference) des Plugins
* **`hooks.json`**: [verweist auf deine Codedatei](/docs/de/plugins/mods/reference#files)
* **`register.js`**: dein Code, genannt das Hooks-Modul

<Steps>
  <Step title="Erstelle das Plugin-Verzeichnis">
    Erstelle die zwei Verzeichnisse, die die Dateien enthalten:

    <Tabs>
      <Tab title="Bash oder Zsh">
        ```bash theme={null}
        mkdir -p first-mod/.claude-plugin first-mod/hooks
        ```
      </Tab>

      <Tab title="PowerShell">
        ```powershell theme={null}
        New-Item -ItemType Directory -Force first-mod\.claude-plugin, first-mod\hooks
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Schreibe das Manifest">
    Ein Mod ist ein Plugin, und ein Mod braucht ein [Manifest](/docs/de/plugins/manifest-reference). Das Manifest dieses Mods hat keine speziellen Felder. Speichere dies als `first-mod/.claude-plugin/plugin.json`:

    ```json first-mod/.claude-plugin/plugin.json theme={null}
    {
      "name": "first-mod",
      "version": "0.1.0",
      "description": "Counts Claude's tool calls, shows the count beside the spinner, and adds a /tally command",
      "author": { "name": "Your Name" }
    }
    ```
  </Step>

  <Step title="Sag Claude Code, wo dein Code ist">
    Wenn Claude Code ein Plugin lädt, liest es die `hooks/hooks.json` des Plugins. Der `modules` Schlüssel in dieser Datei gibt den Pfad zu deinem Code an, und ihn zu haben ist das, was das Plugin zu einem Mod macht. Liste einen Pfad auf, relativ zu `hooks.json`. Hier verweist es auf `register.js`, das du im nächsten Schritt schreibst.

    Speichere dies als `first-mod/hooks/hooks.json`:

    ```json first-mod/hooks/hooks.json theme={null}
    {
      "description": "The first-mod hooks module",
      "modules": ["./register.js"]
    }
    ```
  </Step>

  <Step title="Schreibe den Code">
    Diese Datei ist der Code des Mods, genannt das Hooks-Modul. Wenn der Mod geladen wird, ruft Claude Code die `register` Funktion auf, die die Datei exportiert, und übergibt ihr eine Funktion namens [`on`](/docs/de/plugins/mods/reference#the-hook-function). Jeder Aufruf zu `on` registriert einen Ereignishandler, genannt ein Hook, für das Ereignis, das er benennt.

    Speichere dies als `first-mod/hooks/register.js`:

    ```javascript first-mod/hooks/register.js theme={null}
    // The count, shared by the hooks below
    let calls = 0

    // Claude Code calls this once when the mod loads
    export function register(on) {
      // Runs when the session starts, before your first prompt
      on('session.start', async ($, e, next) => {
        // Add the /tally command
        await $.command.register({
          name: 'tally',
          description: 'Show how many tool calls Claude has made',
        })
        // Let the session start as usual
        return next(e)
      })

      // Runs each time Claude is about to use a tool
      on('tool.call', async ($, e, next) => {
        calls += 1
        // Ask Claude Code to draw the interface again, so the new count shows
        $.ui.invalidate('ui.render')
        // Let the tool run as usual
        return next(e)
      })

      // Runs when you type /tally, and only then, because of the matcher
      on('command.run', { command: 'tally' }, async () => {
        // The text to print in the transcript
        return { text: 'Claude has made ' + calls + ' tool calls since this mod loaded' }
      })

      // Runs each time Claude Code draws the spinner
      on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
        // Keep Claude Code's spinner, with the count added after its word
        return next({ ...e, props: { ...e.props, suffix: ' · tool calls: ' + calls + '…' } })
      })
    }
    ```

    Die Datei behält eine Anzahl in `calls` und registriert vier Hooks:

    * **[`session.start`](/docs/de/plugins/mods/reference#session)** wird ausgeführt, wenn die Sitzung startet, vor deiner ersten Eingabeaufforderung, und jedes Mal, wenn der Mod neu geladen wird. Es fügt den `/tally` Befehl zu Claude Code hinzu.
    * **[`tool.call`](/docs/de/plugins/mods/reference#tools)** wird jedes Mal ausgeführt, wenn Claude ein Werkzeug verwenden wird. Es addiert eins zu `calls` und bittet Claude Code, die Schnittstelle erneut zu zeichnen.
    * **[`command.run`](/docs/de/plugins/mods/reference#commands-and-configuration)** wird ausgeführt, wenn du `/tally` eingibst. Es gibt den Text zurück, der gedruckt werden soll.
    * **[`ui.render`](/docs/de/plugins/mods/reference#interface)** wird jedes Mal ausgeführt, wenn Claude Code den Spinner zeichnet. Es fügt die Anzahl nach dem Wort des Spinners hinzu.

    [Wie der Beispiel-Mod funktioniert](#how-the-example-mod-works) erklärt die drei Argumente, die jeder Hook nimmt, und was jeder zurückgibt.
  </Step>

  <Step title="Lade den Mod">
    Starte Claude Code mit dem `--plugin-dir` Flag, das ein Plugin-Verzeichnis für eine Sitzung lädt, ohne es zu installieren:

    ```bash theme={null}
    claude --plugin-dir ./first-mod
    ```
  </Step>

  <Step title="Probiere den Mod aus">
    Bitte Claude, etwas zu tun, das ein paar Werkzeugaufrufe dauert, wie `list the files here and read the README`. Während Claude arbeitet, wird das Wort des Spinners gefolgt von einer Anzahl, die steigt, wie in `Thinking · tool calls: 2…`. Wenn Claude fertig ist, gib `/tally` ein und drücke Enter. Das Transkript zeigt `first-mod: Claude has made 2 tool calls since this mod loaded`, mit deiner eigenen Anzahl. Claude Code stellt den Namen des Plugins vor den Text des Befehls.

    Um den Befehl ohne eine interaktive Sitzung zu überprüfen, führe ihn im nicht-interaktiven Modus aus:

    ```bash theme={null}
    claude -p "/tally" --plugin-dir ./first-mod
    ```

    ```text theme={null}
    first-mod: Claude has made 0 tool calls since this mod loaded
    ```

    Wenn `/tally` nicht in der Befehlsliste ist, wurde das Modul nicht geladen. Siehe [Finde heraus, warum ein Mod nichts tut](/docs/de/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing).
  </Step>

  <Step title="Ändere den Code, während die Sitzung läuft">
    Lasse die Sitzung offen. In `register.js`, ändere `' · tool calls: '` zu `' · tools used: '` im `ui.render` Hook und speichere. Die hervorgehobene Zeile ist die, die sich ändert:

    ```javascript first-mod/hooks/register.js {4} theme={null}
      // Runs each time Claude Code draws the spinner
      on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
        // Keep Claude Code's spinner, with the count added after its word
        return next({ ...e, props: { ...e.props, suffix: ' · tools used: ' + calls + '…' } })
      })
    ```

    Eine Zeile im Transkript sagt, dass `first-mod` neu geladen wurde und listet seine Hooks auf, und der nächste Spinner verwendet den neuen Text, wie in `Thinking · tools used: 1…`.
  </Step>
</Steps>

<h3 id="how-the-example-mod-works">
  Wie der Beispiel-Mod funktioniert
</h3>

Jede Funktion, die du an `on` übergibst, ist ein Hook, der ein Ereignishandler ist. Claude Code übergibt jedem Hook die gleichen drei Argumente:

* **Die Mods API**, genannt `$`: jede Methode, die ein Mod aufrufen kann, um sich selbst zu erreichen, in [Namespaces](/docs/de/plugins/mods/reference#mods-api-methods) wie `$.ui` und `$.command`
* **Das Ereignis**, genannt `e`: die [Eingabe des Ereignisses](/docs/de/plugins/mods/reference#events) als einfache Daten, wie der Name und die Argumente eines Werkzeugaufrufs
* **Der nächste Handler**, genannt [`next`](/docs/de/plugins/mods/events#how-a-hook-handles-an-event): eine Funktion, die das Ereignis an die anderen Mods und dann an Claude Codes eigenes Verhalten weiterleitet und das Ergebnis zurückgibt

Die Hooks in `first-mod` handhaben ihre Ereignisse auf die drei Arten, auf die ein Hook kann:

* **Beobachten**: Der `session.start` Hook registriert den Befehl, und der `tool.call` Hook zählt den Aufruf und bittet um eine Neuzeichnung. Beide geben `next(e)` zurück, sodass die Sitzung startet und das Werkzeug wie gewohnt läuft.
* **Antworten**: Der `command.run` Hook gibt sein eigenes Ergebnis zurück und ruft niemals `next` auf. Das zweite Argument zu `on`, `{ command: 'tally' }`, ist ein Filter, genannt ein [Matcher](/docs/de/plugins/mods/events#filter-which-events-a-hook-handles), sodass der Hook nur für `/tally` läuft.
* **Umschreiben**: Der `ui.render` Hook ruft `next` mit einer Kopie von `e` auf, deren `suffix` die Anzahl hält, sodass Claude Code seinen üblichen Spinner mit deinem Text nach dem Wort zeichnet

Claude Code beobachtet ein Verzeichnis, das mit `--plugin-dir` geladen wird, und lädt das Hooks-Modul neu, wenn sich eine Datei darin ändert. Jedes Neuladen führt `register` erneut aus, sodass `calls` auf `0` zurückgeht und `/tally` wieder zu zählen beginnt. Um einen Wert über Neuladen hinweg zu behalten, siehe [Behalte den Status](/docs/de/plugins/mods/interface#keep-state).

<h2 id="keep-working-on-a-mod">
  Arbeite weiter an einem Mod
</h2>

Sobald ein Mod geladen ist, kannst du Claude ihn ändern lassen, deinen Code gegen die Typdefinitionen für deine Version überprüfen, die Ereignisse und Aufrufe auflisten, die Claude Code darin findet, und ihn testen.

<h3 id="change-a-mod-with-claude">
  Ändere einen Mod mit Claude
</h3>

Um einen Mod zu ändern, den du bereits hast, starte die Sitzung mit `--plugin-dir` auf das Verzeichnis des Mods gerichtet, sodass das, was Claude schreibt, in der gleichen Sitzung geladen wird:

```bash theme={null}
claude --plugin-dir ./first-mod
```

Dann bitte um die Änderung, zum Beispiel `add a /tally-reset command to this mod that sets the tally back to zero`. Claude bearbeitet das Hooks-Modul, führt `claude plugin validate` aus und behebt, was es meldet. Ein Verzeichnis, das du mit `--plugin-dir` lädst, ist ein [geschützter Pfad](/docs/de/permission-modes#protected-paths), sodass du in den Modi `default` und `acceptEdits` aufgefordert wirst, jede von Claudes Bearbeitungen des Mods zu genehmigen. Die Tabelle der geschützten Pfade gibt das Ergebnis für die anderen Berechtigungsmodi.

Dateien, die Claude während seiner Runde speichert, werden neu geladen, wenn die Runde endet, sodass du `/tally-reset` ausprobieren kannst, sobald Claude fertig ist.

<h3 id="get-the-types-for-your-build">
  Erhalte Typdeklarationen für deine Version
</h3>

Jedes Mal, wenn Claude Code einen Mod aus einem Verzeichnis lädt oder neu lädt, das du an `--plugin-dir` übergibst, oder einen Mod [Claude für dich geschrieben hat](#ask-claude-for-a-mod), schreibt es TypeScript-Deklarationsdateien, die auf `.d.ts` enden, in `.claude-plugin/types/` im Verzeichnis des Mods. Sie beschreiben die genauen Ereignisse, Mods API Methoden und Elemente in der Claude Code Version, die du ausführst, sodass dein Editor Autovervollständigung und Typprüfung für deine Hooks durchführen kann. Um die Deklarationen online zu durchsuchen, lies [`mods/types/claude-code.d.ts`](https://github.com/anthropics/claude-code/blob/main/mods/types/claude-code.d.ts) im Claude Code Repository, dessen erste Zeile die Version benennt, die es geschrieben hat. Das Verzeichnis enthält diese Dateien:

| Pfad | Was es deklariert |
| :- | :- |
| `claude-code/index.d.ts` | Jedes Ereignis und seine Eingabe und sein Ergebnis, jeder Mods API Namespace und Methode, und die Elemente, die jede Oberfläche zeichnen kann |
| `claude-code-tools/index.d.ts` | Die Eingaben der integrierten Werkzeuge, sodass die Überprüfung von `e.tool === 'Bash'` `e` einengt |
| `claude-code-mcp/index.d.ts` | Die Eingaben der MCP Werkzeuge, die das letzte Mal verbunden waren, als du eine Datei im Mod gespeichert hast |
| `index.d.ts` in einem Verzeichnis, das nach einem Plugin benannt ist | Was dieses Plugin zur Mods API hinzufügt. Es gibt ein Verzeichnis für jedes Plugin, das deine `plugin.json` unter `dependencies` auflistet. |
| `tsconfig.json` | Compiler-Optionen, die zu einem Hooks-Modul passen |

Wenn dein Mod keine eigene `tsconfig.json` hat, fügt Claude Code eine an der Wurzel des Mods hinzu, die die generierte erweitert, sodass dein Editor und `tsc -p ./first-mod` den Mod ohne weitere Einrichtung typprüfen.

Die Ereignisse und Methoden können sich zwischen Versionen ändern, daher vertraue diesen Dateien über jede Seite, einschließlich dieser, wenn sie nicht übereinstimmen.

`claude-code/index.d.ts` ist die vollständigste Referenz für deinen Build, mit einem Kommentar und einem Beispiel für jede Mods API Methode. Um etwas nachzuschlagen, durchsuche die Datei nach seinem Namen, wie `'tool.call'`.

<h3 id="check-what-claude-code-reads-from-your-mod">
  Überprüfe, was Claude Code aus deinem Mod liest
</h3>

Um deinen Mod so zu sehen, wie Claude Code ihn sieht, ohne deinen Code auszuführen oder eine Sitzung zu starten, verwende `claude plugin validate`. Es überprüft das Manifest und führt die gleiche statische Analyse auf der Quelle des Hooks-Moduls durch, die Claude Code durchführt, wenn es einen Mod lädt. Führe es in deiner Shell auf dem Verzeichnis des Mods aus:

```bash theme={null}
claude plugin validate ./first-mod
```

Für `first-mod` enthält die Ausgabe diese Zeilen.

```text theme={null}
  ❯ ./register.js hooks: session.start, tool.call, command.run{command=tally}, ui.render{component=Spinner}
  ❯ ./register.js calls: $.command.register, $.ui.invalidate

✔ Validation passed
```

Die `hooks:` Zeile listet die Ereignisse auf, die dein Modul hookt, jeweils mit seinem Filter in Klammern. Die `calls:` Zeile listet jede Mods API Methode auf, die es aufruft. Ein Modul, das Umgebungsvariablen liest oder setzt, erhält auch `env reads:` und `env writes:` Zeilen, und eines, das [`$.state`](/docs/de/plugins/mods/interface#keep-state) verwendet, erhält `state reads:` und `state writes:`.

Wenn ein Ereignis, das du hooken wolltest, in der ersten Zeile fehlt, wird Claude Code diesen Hook auch nicht aufrufen. Die übliche Ursache ist ein falsch geschriebener Ereignisname, den der Befehl als Fehler meldet, wie `"tool.calls" is not an event`.

Befolge diese Regeln, damit statische Analyse jeden Hook und Aufruf finden kann:

* Schreibe jeden Mods API Aufruf vollständig: `$`, den Namespace, dann die Methode, wie in `$.store.get('notes')`. Du kannst `$` an eine Funktion übergeben, die auf der obersten Ebene der gleichen Datei deklariert ist, und für eine Funktion von dir namens `loadNotes`, liest die `calls:` Zeile dann `$.store.get (via loadNotes)`. Das Übergeben von `$` an eine Methode, eine Funktion, die im Hook definiert ist, oder eine Funktion, die du aus einer anderen deiner Dateien importierst, schlägt die Validierung fehl. Die `read` und `update` Funktionen, die [`$.state`](/docs/de/plugins/mods/interface#keep-state) verwendet, sind die Importe, die es nehmen können. Weise `$` oder einen seiner Namespaces nicht einer Variablen zu, destrukturiere ihn nicht, und indexiere ihn nicht mit einem berechneten Namen. `const ui = $.ui` schlägt mit `$.ui is used as a value` fehl.
* Schreibe den Ereignisnamen in jedem `on` Aufruf als String-Literal, wie `'tool.call'`. Eine Variable oder eine Schleife über eine Liste von Namen schlägt mit `the event name passed to on() is not a string literal` fehl.
* Deklariere innerhalb von `register` keine zweite Variable oder keinen Parameter namens `on`. Die Validierung schlägt mit `"on" is declared again (shadowed)` fehl.
* Importiere nur aus Dateien im Plugin-Verzeichnis, nach relativem Pfad. Der einzige erlaubte bloße Import ist `claude-code`, für Typen und ein paar Helfer.
* Verwende `import` Deklarationen am Anfang der Datei, wie in `import { name } from './file.js'`. Ein dynamischer `import()` schlägt mit `a dynamic import(); a hooks module imports its own files with an import declaration` fehl.
* Schreibe jede Datei als ES-Modul, mit `import` und nicht `require`. Die [Referenz](/docs/de/plugins/mods/reference#files) listet die Dateierweiterungen auf, die Claude Code lädt.

<h3 id="test-the-mod">
  Teste den Mod
</h3>

Du kannst automatisierte Tests für einen Mod schreiben und sie von deiner Shell mit `claude plugin test` ausführen, ohne Sitzung, Anmeldung oder Netzwerk. Ein Test löst die Ereignisse aus, die deine Hooks handhaben, und überprüft, was die Hooks taten.

Dieser Test löst zwei Werkzeugaufrufe aus, führt `/tally` aus und überprüft, dass die Antwort beide zählt. Speichere ihn als `first-mod/tests/first-mod.test.ts`:

```typescript first-mod/tests/first-mod.test.ts theme={null}
import { expect, test } from 'claude-code/testing'

test('/tally reports the tool calls the mod has seen', async ($, on) => {
  // Answer each tool call in Claude Code's place, so no tool runs
  on('tool.call', () => ({ result: 'ok' }))

  // Raise two tool calls, which the mod's tool.call hook counts
  await $.tool.call({ tool: 'Bash', command: 'ls' })
  await $.tool.call({ tool: 'Read', file_path: 'README.md' })

  // Run /tally and check the text its hook returns
  const answer = await $.command.run({ command: 'tally', args: '' })
  expect(answer.text).toBe('Claude has made 2 tool calls since this mod loaded')
})
```

Führe die Tests von deiner Shell aus dem `first-mod` Verzeichnis aus:

```bash theme={null}
claude plugin test
```

Die Ausgabe benennt jeden Test und ob er bestanden hat, mit Timings, die von Lauf zu Lauf variieren:

```text theme={null}
tests/first-mod.test.ts:
(pass) /tally reports the tool calls the mod has seen [22.87ms]

 1 pass
 0 fail
Ran 1 test across 1 file. [0.19s]
```

[Teste einen Mod](/docs/de/plugins/mods/test) behandelt das Stubben eines Modellaufrufs oder des Speichers, und das Testen von Timern und Zeichnungen.

<h2 id="share-your-mod">
  Teile deinen Mod
</h2>

Ein Mod ist ein Plugin, daher versionierst du ihn im Manifest und Personen installieren und aktualisieren ihn mit den `/plugin` Befehlen. Um ihn anderen Personen zu geben, [füge ihn zu einem Marketplace hinzu](/docs/de/plugins/publish).

Bevor du das tust, überprüfe den Namen des Plugins: `claude plugin validate` schlägt einen Namen fehl, der [wie einer von Anthropics eigenen aussieht](/docs/de/plugins/manifest-reference#name), wie einer, der mit `claude-` beginnt. Die Ereignisse und Methoden können sich zwischen Versionen ändern, daher ist deine README der Ort, um zu sagen, welche Claude Code Version du getestet hast.

Entwickle weiter gegen das Verzeichnis mit `--plugin-dir`, nicht gegen eine installierte Kopie. Claude Code speichert ein installiertes Plugin nach Version, sodass deine Bearbeitungen die installierte Kopie nicht erreichen, bis du die Version erhöhst und erneut installierst.

<h2 id="next-steps">
  Nächste Schritte
</h2>

* [Zeichne in der Schnittstelle](/docs/de/plugins/mods/interface): öffne einen Bereich, zeichne über der Eingabeaufforderung, und füge Schaltflächen und Textfelder hinzu
* [Reagiere auf Ereignisse](/docs/de/plugins/mods/events): hook Werkzeugaufrufe, Eingabeaufforderungen und Runden
* [Verwende die Mods API](/docs/de/plugins/mods/api): füge Befehle und Werkzeuge hinzu, rufe ein Modell auf, und führe Arbeit auf einem Timer aus
* [Teste einen Mod](/docs/de/plugins/mods/test): stub, was Claude Code antworten würde, und teste Timer und Zeichnungen
* [Behebe einen Mod](/docs/de/plugins/mods/troubleshoot): die Gründe, warum ein Mod nichts tut, und das Debug-Protokoll
* [Lese die Quelle von integrierten Mods](/docs/de/plugins/mods/overview#read-the-source-of-built-in-mods): vollständige Plugins, jeweils mit seinem Hooks-Modul und Tests
