TL;DR
- Ein Claude Code Mod besteht aus drei Dateien:
.claude-plugin/plugin.json,hooks/hooks.jsonmit{"modules":["./index.ts"]}und einem TypeScript-Modul, dasregister(on)exportiert. Mehr braucht es nicht, damit er geladen wird. - Im Build 2.1.272 umfasst die von
/plugin-typesgeschriebene Typoberfläche 11,783 Zeilenclaude-code.d.ts: 84 Event- oder Call-Namen über 23 Nomen.fs.readFilegibt es nicht mehr, das Nomen heißtfs.readundfs.write. - Ein
tool.call-Hook mit 42 Zeilen sorgte dafür, dass das Modell sowohl beim Read- als auch beim Bash-ToolAPI_KEY=[REDACTED]statt des echten Schlüssels las, bei 27.9 ms pro gesundem Hop und etwa 0 zusätzlichen Tokens in der Session. - Ein Hook, der das 10-s-Budget überschreitet oder eine Exception wirft, wird übersprungen, und der Befehl darunter läuft. Das Log meldet es, die Wirkung ist ein Bypass: Ein Guard-Mod schlägt offen fehl (fail open).
- Der generierte Weg funktioniert: Ein Satz erzeugte in etwa 4 Minuten und für $1.23 einen Mod mit 190 Zeilen plus 53 Zeilen Tests, der
claude plugin validateohne Warnungen undclaude plugin testmit 4 pass / 0 fail bestand. - Eines ließ sich nicht reproduzieren: Der Mod lud unter
claude -p, blieb aber in einer per pty gesteuerten interaktiven REPL in zwei Versuchen stumm. Betrachte das Laden in der REPL als unbestätigt, bis du es in einem echten Terminal getestet hast.
Was die Messungen zeigen
Alles Folgende lief auf Claude Code 2.1.272 mit gesetztem CLAUDE_CODE_ENABLE_FUNCTION_HOOKS, mit einem handgeschriebenen Mod namens redact-secrets und drei Wegwerf-Mods, die ihn kaputtmachen sollten. Das Feature selbst wird im Issue zum Function-Hooks-Vorschlag verfolgt, das nach wie vor das Nächste an einer offiziellen Spezifikation ist s3.
Das Tooling existiert vor der Doku. Build 2.1.272 liefert claude plugin validate, test, eval und details; test funktioniert, obwohl plugin --help es nicht im Befehlsblock aufführt s3. /plugin-types in einer Session schrieb 11,783 Zeilen nach .claude/types/claude-code.d.ts, dazu eine claude-code-mcp.d.ts mit 3,438 Zeilen für 150 MCP-Tools von 7 Servern s3. Zählt man die generierten Typen, ergeben sich 84 Event- oder Call-Namen über 23 Nomen, und die Datei benennt eine Sache um, die du vielleicht aus Posts vom September kennst: fs.readFile existiert nicht mehr, die Oberfläche ist fs.read und fs.write s9. Laut denselben Typen liefert ein tool.call-Hook { result, context? } oder { deny } zurück; text und ref kommen aus dem Core und gehören nicht zur eigenen Antwort eines Hooks, du überschreibst also result, nicht text s3.
claude plugin validate gibt einen Footprint aus, bevor der Mod überhaupt läuft: ./index.ts hooks: tool.call und ./index.ts calls: $.ui.toast, oder calls: nothing on $, wenn das Modul keine Host-Fähigkeit berührt s4. Diese statische Zeile ist die einzige Prüfung, die ein Verzeichnis wie awesome-claude-code-mods heute automatisieren kann, was beim nächsten Absatz wichtig ist.
Die Schwärzung funktioniert im -p-Modus. Der 42-Zeilen-Hook fing tool.call ab, und das Modell erhielt API_KEY=[REDACTED], wo Datei und Shell-Ausgabe sk-test1234567890abcdef enthielten, sowohl beim Read- als auch beim Bash-Tool s3. Das Debug-Log maß einen gesunden Hop mit 27.9 ms Roundtrip, Worker-Hop und next() eingeschlossen s3. claude plugin details bezifferte den Mod auf etwa 0 zusätzliche Tokens pro Session: Ein Mod ist Code im Prozess, kein Prompt-Text, und das ist das Hauptargument seiner Befürworter gegen Shell-Hooks und Skills s7.
Der Guard schlägt offen fehl. Ein slow-guard-Mod, der 15 s schläft, wurde beim 10-s-Budget abgebrochen mit hook failed: slow-guard: exceeded 10000ms budget (tool.call; skipped; what is below it ran in its place), und echo hi lief trotzdem s3. Ein throw-guard-Mod, der eine Exception wirft, wurde genauso übersprungen, hook failed: throw-guard: boom (tool.call; skipped; what is below it ran in its place), gemeldet nach 574.2 ms s3. Laut im Log, umgangen in der Wirkung. Jeder Mod, dessen Aufgabe es ist, etwas zu blockieren, muss mit diesem Wissen gelesen werden: Ein Bug im Guard ist ein Loch, kein Absturz.
Die Generierung ist billig. Aus einem Satz schrieb das Modell einen funktionierenden Mod mit 190 Zeilen plus 53 Zeilen Tests in etwa 4 Minuten, 34 Turns und $1.23 (19,053 Output-Tokens, 497,282 Cache-Reads, 8,357 Thinking) s3. Dieser Mod bestand claude plugin validate ohne Warnungen und claude plugin test mit 4 pass / 0 fail in 0.31 s und versteckte die Schlüssel live s3. Beim handgeschriebenen Mod lief claude plugin test ohne API-Key und ohne Modellaufruf: 1 pass in 0.25 s s3. Ein Skill, der Agenten das Schreiben von Mods beibringt, existiert bereits, falls du das mit einer Vorlage wiederholen willst s12.
Was sich nicht reproduzieren ließ: $.ui.toast wurde nie gerendert, weil der Mod in der per pty gesteuerten REPL in 2 Versuchen nicht geladen wurde; unter -p tauchte das Äquivalent nur als Debug-Zeile auf. Das Gegenteil der auf X kursierenden Behauptung "nur REPL" wurde beobachtet, die Ursache wurde nicht isoliert s8. Auch der 5-s-Heartbeat bei hängendem Worker wurde nicht getestet; gemessen wurden nur das 10-s-Await-Budget und der Throw-Pfad.
Messungen
| Fall | Was der Mod tut | Ergebnis | Zeit |
|---|---|---|---|
| redact-secrets, Read-Tool | Überschreibt result bei tool.call |
Modell sieht API_KEY=[REDACTED] |
27.9 ms pro Hop |
| redact-secrets, Bash-Tool | Derselbe Hook, Shell-Ausgabe | Modell sieht API_KEY=[REDACTED] |
27.9 ms pro Hop |
| slow-guard | Schläft 15 s in tool.call |
Übersprungen, echo hi lief |
abgebrochen bei 10000 ms |
| throw-guard | Wirft boom in tool.call |
Übersprungen, Befehl lief | 574.2 ms |
| generierter Mod | 190 Zeilen + 53 Zeilen Tests aus einem Satz | validate: keine Warnungen; test: 4 pass / 0 fail | ~4 min, 34 Turns, $1.23 |
claude plugin test auf redact-secrets |
Kein API-Key, kein Modellaufruf | 1 pass | 0.25 s |
claude plugin details |
Session-Kosten des Mods | ~0 Tokens zusätzlich | n/a |
Protokoll: Claude Code 2.1.272, Function Hooks per Umgebungsvariable aktiviert. Jeder Mod ist ein Plugin-Verzeichnis mit plugin.json, hooks/hooks.json und einer index.ts. Die Läufe gingen über claude -p mit aktiviertem Debug-Logging; eine präparierte Datei und ein Shell-Befehl enthielten beide sk-test1234567890abcdef. Die Fail-open-Fälle wurden mit einem Mod getrieben, der 15 s schläft, und einem Mod, der eine Exception wirft, mit echo hi als abgesichertem Befehl. Die interaktive REPL wurde über ein pty gesteuert und lud den Mod in zwei Versuchen nicht.
Das machst du am Montag
- Führe
/plugin-typesin einer Session aus und öffne.claude/types/claude-code.d.ts: Suche nachfs.readundtool.call, bevor du einem Snippet aus einem Post vom September traust. - Schreibe das Drei-Dateien-Skelett des Mods (
plugin.json,hooks/hooks.jsonmit{"modules":["./index.ts"]},index.tsmit Export vonregister(on)) und führeclaude plugin validatedarauf aus: Lies die Footprint-Zeilenhooks:undcalls:. - Portiere deinen meistgenutzten Shell-Hook auf einen
tool.call-Handler, derresultüberschreibt, und vergleiche dann die Hop-Zeit im Debug-Log mit der Shell-Version. - Lege neben dem Mod eine
claude plugin test-Datei an, damit der Guard in der CI ohne API-Key läuft. - Packe jeden Guard-Handler in ein try/catch, das bei einem Fehler
{ deny }zurückgibt: In diesem Build überspringt dich eine Exception oder ein 10-s-Stillstand und lässt den Befehl durch. - Teste den Mod getrennt unter
claude -pund in deinem echten interaktiven Terminal und notiere, welcher ihn geladen hat. - Führe vor der Installation eines Drittanbieter-Mods
claude plugin validatedarauf aus und lehne alles ab, dessencalls:-Zeile Host-Fähigkeiten nennt, die der Mod nicht braucht.
Weiterlesen
- Lies das Vorschlags-Issue ganz, einschließlich des Architektur-PDFs in den Kommentaren: Es ist der einzige schriftliche Vertrag für
register(on), Budgets und den Worker-Hop s3. - Vergleiche mit dem Design der Command Code Mods, das TypeScript gegen eine
ModApiim Host-Prozess ausführt: Beide Systeme haben dieselbe Form und dieselbe Early-Access-Beschränkung s2. - Die Vorschau von claudefa.st entstand, als das Feature noch ein Vorschlag war: nützlich, um zu sehen, was sich zwischen dem Text vom 3. Sep und dem Binary 2.1.272 geändert hat s9.
- Prathkums Note-Tweet ist die klarste Kurzfassung, warum In-Process-Hooks Shell-Hooks bei Tokens und Latenz schlagen s7.
- cc-mod-waitwhat ist ein guter erster Mod zum Lesen: UI über dem Prompt, nichts wird ins Transkript geschrieben s11.
- cc-arcade zeigt, wie weit
$.uireicht: Spiele, die von einem Mod über dem Prompt gerendert werden s5. - Die Hooks-Referenz beschreibt weiterhin das Shell-Modell; halte sie offen, um jedes alte Event auf seinen neuen Namen
noun.eventabzubilden s1. - Skeptiker auf X argumentieren, Plugins deckten das schon ab und die Oberfläche breche mit jedem Release; das umbenannte Nomen
fsist ein Datenpunkt für sie s23.
Quellen
- Function Hooks proposal (issue #91870), GitHub, anthropics/claude-code. Warum lesen: der einzige spezifikationsartige Text zu Mods, mit dem Architektur-PDF und der Release-Spur in den Kommentaren.
- Hooks reference, Claude Code docs. Warum lesen: das Shell-Hook-Modell, von dem du migrierst, Event für Event.
- Command Code Mods documentation, Command Code. Warum lesen: Vorbild mit derselben TypeScript-im-Prozess-Form, nützlich, um zu erkennen, was Anthropic übernommen oder vermieden hat.
- awesome-claude-code-mods, GitHub, karanb192. Warum lesen: automatisch gescanntes Verzeichnis öffentlicher Mods, mit dem validate-Footprint als einziger Prüfung.
- cc-arcade, GitHub, sezaakgun. Warum lesen: die Demo, die das Feature sichtbar machte, und eine Tour durch
$.ui. - Boris Cherny announcement tweet, X, Boris Cherny. Warum lesen: die Launch-Aussage eines Anthropic-Entwicklers, da es keinen Blogpost gibt.
- Prathkum: Function Hooks explained, X, Prathkum. Warum lesen: die beste kurze Erklärung von Hooks vs. Mods für alle, die schon Shell-Hooks schreiben.
- shipnotesai reaction thread, X, shipnotesai. Warum lesen: wo die Behauptung "nur REPL" kursierte, die unser Lauf widerlegt hat.
- Claude Code Function Hooks: Preview Behind a Flag, claudefa.st. Warum lesen: Erklärer vor dem Release, gut, um den Vorschlag mit dem Binary abzugleichen.
- cc-mod-waitwhat, GitHub, GGGODLIN. Warum lesen: ein kleiner, gut lesbarer Mod, der in die UI schreibt und nicht ins Transkript.
- claude-mods-skill, GitHub, BeLazy167. Warum lesen: ein Skill zum Generieren von Mods, falls du das Ein-Satz-Experiment wiederholen willst.
- AxialisSoftware reaction, X, AxialisSoftware. Warum lesen: der skeptische Standpunkt in einem Tweet.
FAQ
Ersetzt ein Mod heute meine Shell-Hooks?
Noch nicht für alles, was blockieren muss. In 2.1.272 wird ein Hook, der eine Exception wirft oder länger als 10 s hängt, übersprungen, und der Befehl läuft. Shell-Hooks funktionieren weiter, behalte also die blockierenden dort, bis ein deklariertes Catch oder eine Fail-closed-Option kommt.
Warum ist validate wichtig, wenn der Mod problemlos läuft?
Weil seine Zeilen hooks: und calls: die einzige statische Sicht darauf sind, was ein Mod auf $ berührt. Bei deinem eigenen Mod bestätigt sie den Footprint; bei einem Drittanbieter-Mod ist sie die gesamte Prüfung, die du bekommst, bevor der Code in deinem Prozess läuft.
Was kostet ein Mod pro Session?
claude plugin details meldete etwa 0 zusätzliche Tokens. Der Mod ist Code, der in der Engine läuft, kein Text im Prompt, und das ist der Hauptvorteil gegenüber einem Skill oder einer CLAUDE.md-Regel.
Warum lud der Mod unter -p, aber nicht in der REPL?
Unbekannt. Zwei per pty gesteuerte Versuche blieben stumm, während claude -p den Hook lud und anwandte. Wahrscheinlich liegt die Ursache in der pty-Umgebung und nicht im Feature, teste also in deinem eigenen Terminal, bevor du dich in die eine oder andere Richtung verlässt.
AIDive