Zwölf Tage von 'wenn ihr das wollt' bis Tetris
Claude Code Mods sind TypeScript-Module, die innerhalb der Claude-Code-Engine laufen und ihre Events als Funktionen hooken. Boris Cherny, der bei Anthropic Claude Code leitet, kündigte sie mit fünf Worten an: "Claude mods are landing now." Der Post sammelte 2.400 Likes, und jemand hatte bereits Tetris im Terminal gebaut. Tetris, Doom und ein Haustier, das wächst, während Claude eure Tests laufen lässt – alles oberhalb des Prompts gerendert, bei null Tokens.
Die Ankündigung verlinkt keine Doku-Seite. Sie verlinkt ein GitHub-Issue, das 12 Tage zuvor von einem Anthropic-Ingenieur eröffnet wurde, mit einer eingebauten Bedingung. Alice Poteat schrieb, dass die Reaktion der Community wahrscheinlich darüber entscheiden werde, ob das Feature ausgeliefert wird oder nicht. 177 Kommentare später hatten Leute die geflaggte Binary durchgehämmert, ihre Timeouts gemessen und Spiele darauf gebaut.
| Kennzahl | Wert |
|---|---|
| Likes auf die Ankündigung | 2.400 |
| Kommentare zum GitHub-Issue | 177 |
| Erfasste Oberfläche in diesem Wochen-Build | 10.700 Zeilen |
| Events auf Nomen (Issue-Thread-Build) | 84 auf 19 |
| Mods auf GitHub innerhalb von 48 Stunden | 31 |
Die Doku-Seite liefert zum Zeitpunkt dieses Artikels einen 404. Dieser Artikel behandelt die vier Wege, Claude Code zu erweitern, einen nützlichen Mod, der absichtlich gebaut und wieder kaputtgemacht wurde, und was vor dem Ausliefern noch instabil ist.
Ein Mod ist eine Funktion in der Mitte
Der Source-Tree definiert es in einem Satz: Ein Mod ist ein Claude-Code-Plugin, dessen Verhalten in einem Hooks-Modul steckt. Ein einziger Register-Eintrag hookt die Events der Engine als Funktionen. Auf der Festplatte ist das ein Plugin-Ordner, ein Hooks-Manifest, das genau ein Modul benennt, und das Modul selbst.
Jeder Hook ist eine Funktion aus drei Dingen: $, die Tür, durch die jeder Seiteneffekt geht; das Event; und die Continuation, der Rest der Kette unter dir. Hooks verschachteln sich wie Middleware. Wer zuerst registriert wird, besitzt das Event, und nichts weiter unten in der Kette kann es unterbinden. Diese Reihenfolge wird konfiguriert, nicht installiert. In Alice Poteats Worten: Die Reihenfolge ergibt sich aus der Konfiguration, nicht aus dem Zeitpunkt der Installation.
Es gibt keinen Ambient-Zugriff. Alles, was ein Mod tut, läuft über $, sodass ein Admin jedes Event auditieren, erlauben, verweigern oder loggen kann. Ein Kommentator brachte es auf den Punkt: Was ein Plugin getan hat, sind genau die Calls, die es gemacht hat. Ein einzelner Hook auf * sieht jedes Event, ein Audit-Log ist also eine einzige Funktion. Ein Mod kann zeichnen, weil das Interface React ist. Er läuft in-process auf Bun, mit 50 Mikrosekunden beim 99. Perzentil. Eine einzige Umgebungsvariable schaltet ihn ein. Was tatsächlich auf $ liegt, wird noch zusammen mit Early-Access-Partnern entworfen.
Vier Wege, Claude Code zu erweitern – und welcher wofür
Ein Shell-Hook ist ein Skript, das die Engine zu einem festen Zeitpunkt aufruft. Es bekommt JSON auf Standard-Input und antwortet mit einem Exit-Code. Die Antwort hat eine Obergrenze: 8.000 Zeichen Kontext zurück, bei manchen Hooks 2.000. In Prathams Worten: Unter Windows brechen sie oft auf seltsame Weise.
Ein Plugin ist eine Box. Ein Manifest bündelt Skills, Agents, Hooks und MCP-Server. Es wird aus einem Marketplace installiert oder direkt aus einem Ordner auf der Festplatte geladen, und ein einziger Befehl validiert die Box, bevor irgendetwas läuft.
Ein Skill ist Prosa, die das Modell liest, wenn es sie braucht. Der Body lädt nur, wenn ein passender Prompt eintrifft. Es bleibt der günstigste Weg, Verhalten zu ändern.
Ein Mod ist dieselbe Box mit einer Datei mehr: ein Hooks-Manifest, das ein Modul benennt, und dieses Modul ist TypeScript, typisiert, in-process, bei jedem Engine-Event. Das ist der ganze Unterschied.
| Mechanismus | Was es ist | Läuft | Obergrenze |
|---|---|---|---|
| Shell-Hook | Skript, zu festem Zeitpunkt aufgerufen | Subprozess, Exit-Code | 8.000 Zeichen zurück (2.000 bei manchen Hooks) |
| Plugin | Bündel aus Skills, Agents, Hooks, MCP-Servern | Installiert oder von der Festplatte geladen | Vor dem Lauf validiert |
| Skill | Prosa, geladen bei passendem Prompt | Im Kontext des Modells | Günstigste Änderung |
| Mod | Plugin plus TypeScript-Hooks-Modul | In-process, bei jedem Event | Typisiert, Early Access |
Die Types stammen aus einem einzigen Slash-Command, der die vollständige Liste dessen, was $ bietet, direkt ins Projekt schreibt. Die alten Shell-Hooks werden gewrappt, nicht abgeschafft. Bei einem frühen Build beobachtete Spencer Morley, wie der Wrapper nicht lud und trotzdem deklariert blieb. Die Faustregel: Um zu ändern, was Claude weiß, schreib einen Skill; um ein Skript zu einem Zeitpunkt laufen zu lassen, einen Shell-Hook; um ein Bündel auszuliefern, ein Plugin; um in der Engine zu sitzen, einen Mod. Der Shell-Hook funktioniert weiterhin überall dort, wo das Flag aus ist.
Anthropics eigene drei, aus dem Quellcode gelesen
Drei Mods liefern mit der Binary aus, ihr Quellcode liegt auf GitHub: ein Security-Default, ein Diff-Pane und Telemetry.
Der Security-Default sitzt ganz außen. Auf einer Maschine mit Managed Settings oder in einer Team- oder Enterprise-Organisation kommt nichts, was eine Person installiert, über ihn hinaus. Er hookt 12 Events, und jeder Hook trifft eine von drei Entscheidungen: an der User-Tier vorbei fortfahren, einen Aufrufer aus der User-Tier namentlich zurückweisen, oder durchlassen. Er fällt geschlossen aus, und der Doc-Comment sagt das in zwei Worten. Das war der Teil, der den Thread interessierte: Ein Admin nimmt $ eine Fähigkeit weg, und nichts, was darunter registriert ist, kann sie aufrufen. In den Worten eines Kommentators: Das ist etwas kategorial anderes, als ein Plugin zu bitten, etwas nicht zu tun.
Diff ist ein Pane neben dem Transcript, das die uncommitteten Änderungen der Session Datei für Datei zeigt, aktualisiert, während Claude editiert. Es wird beim Session-Start registriert und umfasst 27 Helper-Dateien – kein Spielzeug.
Telemetry fügt $ von innerhalb der Engine-Erstellung ein Nomen hinzu. Es awaited, was darunter liegt, und gibt das plus sich selbst zurück. Es läuft nur in internen Builds.
Die README sagt, man solle eins aus dem Quellcode ausführen und eins aus dem Quellcode testen. Die Hilfe im heutigen Build listet validate, eval und details. Test steht nicht in der Liste, obwohl die Test-Hilfe noch antwortet. Die eingebaute Tier weist auch eure eigene Kopie zurück: Liefert ihr ein Plugin mit einem dieser Namen aus, lädt die Binary ihre eigene.
Zweiundvierzig Zeilen: ein Mod, der Secrets vor dem Modell verbirgt
Der Slash-Command, der die Types schreibt, erzeugt in diesem Build 11.700 Zeilen: 84 Events über 23 Nomen verteilt. Der Tool-Call-Hook antwortet mit einem Ergebnis oder einem Deny, niemals mit dem Text. Dieser Teil ist vom Core fest vorgegeben.
Der Mod besteht aus drei Dateien: dem Plugin-Manifest, dem Hooks-Manifest mit seiner einen Zeile, und dem Modul. Das Modul hat 42 Zeilen. Es awaited, was darunter liegt, bereinigt das Ergebnis und gibt es zurück. Vier Patterns decken zwei Vendor-Key-Formen, ein GitHub-Token und alles ab, was einer Variablen namens key, secret oder token zugewiesen wird.
Validate liest den Quellcode, bevor er läuft. Es nennt das Event, das das Modul hookt, und die eine Sache, die es auf $ aufruft. Die einzige Warnung ist ein fehlender Author. Von der Festplatte geladen, mit gesetztem Flag, enthält die Testdatei zwei Keys, beide konstruktionsbedingt gefälscht, und das Modell liest "redacted". In seinen eigenen Worten: Die Werte kamen als redacted zurück, es kann also nicht sehen, was darin steckt.
| Kennzahl | Wert |
|---|---|
| Modullänge | 42 Zeilen |
| Hop-Latenz inklusive Worker | 28 ms |
| Zur Session hinzugefügte Tokens | 0 |
Die Engine loggt den Hop als von einem Hooks-Modul aufgelöst. Das Inventory zeigt keine Skills, keine Agents, nichts, das dauerhaft läuft. Eine Grenze bleibt: vor dem Modell verborgen heißt nicht vor dem Bildschirm verborgen. Das Transcript zeigt weiterhin, was das Tool ausgegeben hat. Das wäre ein anderer Mod, wie Max von Ship Notes in einer Zeile anmerkte.
Kaputt machen: ein langsamer Guard ist ein umgangener Guard
Derselbe Mod, eine Zeile mehr: ein 15-Sekunden-Sleep vor dem Call an das, was darunter liegt. Zehn Sekunden später gibt die Engine auf, meldet, dass der Hook sein Budget überschritten hat und übersprungen wurde, und das, was darunter liegt, läuft stattdessen. Der Befehl läuft trotzdem und gibt "hi" aus.
Ersetzt man den Sleep durch einen Throw: 574 Millisekunden, gleiches Urteil, übersprungen, und der Befehl läuft.
| Fall | Zeit | Urteil |
|---|---|---|
| Gesunder Hook | 28 ms | Aufgelöst |
| Throw | 574 ms | Übersprungen, Befehl lief |
| Hang | über 10 s | Übersprungen, Befehl lief |
Beide Fehlerfälle enden im selben Wort: übersprungen. Der Thread hatte die Asymmetrie eine Woche zuvor bereits vermessen. Eine beim Laden fehlende Capability versagt geschlossen. Ein Hook über seinem Budget versagt offen: laut, aber umgangen, in Spencer Morleys Worten. Ein Block ohne Begründung schickt das Modell einfach zu einem anderen Tool. Pratham beobachtete, wie es ein anderes Tool wählte und die Datei trotzdem schrieb.
Die Antwort auf dem Tisch ist ein Catch. Alice Poteat schlägt einen Catch auf dem Return des Hooks vor, der läuft, wenn man zu lange braucht oder wirft. Ein umgeschriebenes Write braucht trotzdem eine Notiz ans Modell: Es sieht, was es zu schreiben bat, aus Caching-Gründen, also hängt man eine Kontextzeile an. Das Budget ist zugleich die Isolation. Der Hooks-Worker läuft getrennt, und wenn er abstürzt, startet die Engine ihn neu und schaltet Hooks für die Session ab. Der Fix ist nicht ein längeres Budget, sondern ein deklarierter Catch.
Achtundvierzig Stunden Mods – und was ein Satz kauft
Nach zwei Tagen: Tetris oberhalb des Prompts und sieben weitere Spiele, spielbar während Claude arbeitet, bei null Tokens. Doom, das Original von 1993, läuft in einem eigenen Prozess; der Mod erreicht es über lokales HTTP und zeichnet zehnmal pro Sekunde neu. Es gibt einen atmenden Pacer im Spinner und ein Story-Modell mit 260.000 Parametern, das innerhalb des Hooks-Workers läuft, bei null API-Tokens.
Die Registry scannte 31 Mods mit validate. 14 können Host-Prozesse ausführen. 13 sehen jeden Tool-Call.
Demo 8 des Community-Threads versprach, dass ein einziger Satz ein Plugin schreibt, das Secrets verbirgt, bevor das Modell sie liest. Wir haben um eines gebeten.
| Kennzahl | Wert |
|---|---|
| Zeit | 4 Min. |
| Turns | 34 |
| Kosten | 1,23 $ |
| Zeilen (plus eine Testdatei) | 190, gegenüber unseren 42 |
| Tests | 4 bestanden in einem Drittel einer Sekunde |
Es kennzeichnet, was es versteckt, nach Art, validiert sauber und braucht weder einen API-Key noch einen Modell-Call. Eine Antwort brachte es so auf den Punkt: Allowlists sind das Produkt, Tetris ist die Demo.
Fazit: jetzt bauen, später ausliefern
Die eigenen Zahlen der Registry sind die Warnung. 14 von 31 Mods können Host-Prozesse ausführen, und die einzige Prüfung ist ein statischer Footprint. Die eval-Hilfe sagt es selbst: Eine bestandene Suite ist keine Sicherheitsprüfung.
| Signal | Wert |
|---|---|
| Events am 8. | 20 |
| Events am 15. | 84 |
| CLI-Versionen in zwei Wochen | 14 |
| Hacker-News-Punkte | 2 |
| Antworten auf die Kompatibilitätsfrage | 0 |
Das 10-Sekunden-Budget steckt in der Runtime, nicht in den Types, wie Marat anmerkte. Es gibt keine Changelog-Zeile, keine Doku-Seite, keinen Launch-Post. Ein Konkurrent behauptet, Anthropic habe kopiert: Ahmad Awais verweist auf die Mods von Command Code, und er schreibt deren Beispiel-Mod – das solltet ihr entsprechend gewichten. Der Post "early access, APIs may change" sammelte 357 Likes.
Baut jetzt einen, wenn ihr bereits Hooks schreibt und Audit, Redaction oder ein Pane wollt. Wartet, wenn ihr an ein Team ausliefert, bevor der Contract feststeht. Genau diese Offenheit ist der Grund, warum das offen versagende Budget, der Type-Mismatch beim MCP-Call und der Wrapper-Fehler von Usern binnen Tagen gefunden wurden.
AIDive