TL;DR
- Un Mod di Claude Code è fatto di tre file:
.claude-plugin/plugin.json,hooks/hooks.jsoncon{"modules":["./index.ts"]}e un modulo TypeScript che esportaregister(on). Non serve altro perché venga caricato. - Nella build 2.1.272 la superficie tipizzata scritta da
/plugin-typesè di 11,783 righe diclaude-code.d.ts: 84 nomi di evento o di chiamata su 23 sostantivi.fs.readFilenon esiste più, il sostantivo èfs.readefs.write. - Un hook
tool.calldi 42 righe ha fatto leggere al modelloAPI_KEY=[REDACTED]al posto della chiave vera, sia con il tool Read sia con il tool Bash, a 27.9 ms per hop sano e circa 0 token aggiunti alla sessione. - Un hook che dorme oltre il budget di 10 s o che lancia un'eccezione viene saltato e il comando sotto di lui viene eseguito. Il log lo segnala, l'effetto è un bypass: un Mod di guardia fallisce in modo aperto (fail open).
- Il percorso generato funziona: una frase ha prodotto in circa 4 minuti e $1.23 un Mod di 190 righe più 53 righe di test, che ha superato
claude plugin validatesenza avvisi eclaude plugin testcon 4 pass / 0 fail. - Una cosa non si è riprodotta: il Mod si caricava con
claude -pma restava muto in una REPL interattiva pilotata via pty, in due tentativi. Considera il caricamento in REPL non verificato finché non lo provi su un terminale reale.
Cosa dicono le misure
Tutto quanto segue è stato eseguito su Claude Code 2.1.272 con CLAUDE_CODE_ENABLE_FUNCTION_HOOKS impostato, su un Mod scritto a mano chiamato redact-secrets e su tre Mod usa e getta costruiti per romperlo. La funzione è tracciata nell'issue della proposta Function Hooks, che resta la cosa più vicina a una specifica ufficiale s3.
Gli strumenti esistono prima della documentazione. La build 2.1.272 include claude plugin validate, test, eval e details; test funziona anche se plugin --help non lo elenca nel suo blocco di comandi s3. Eseguire /plugin-types in una sessione ha scritto 11,783 righe in .claude/types/claude-code.d.ts, più un claude-code-mcp.d.ts di 3,438 righe che copre 150 tool MCP di 7 server s3. Contando i tipi generati si ottengono 84 nomi di evento o di chiamata distribuiti su 23 sostantivi, e il file rinomina una cosa di cui hai forse letto nei post di settembre: fs.readFile non esiste più, la superficie è fs.read e fs.write s9. Gli stessi tipi dicono che un hook tool.call restituisce { result, context? } oppure { deny }; text e ref vengono dal core e non fanno parte della risposta propria di un hook, quindi si riscrive result, non text s3.
claude plugin validate stampa un'impronta prima ancora che il Mod giri: ./index.ts hooks: tool.call e ./index.ts calls: $.ui.toast, oppure calls: nothing on $ quando il modulo non tocca nessuna capacità dell'host s4. Questa riga statica è l'unica verifica che una directory come awesome-claude-code-mods può automatizzare oggi, il che conta per il paragrafo successivo.
La redazione funziona in modalità -p. L'hook di 42 righe intercettava tool.call e il modello riceveva API_KEY=[REDACTED] dove il file e l'output della shell contenevano sk-test1234567890abcdef, sia con il tool Read sia con il tool Bash s3. Il log di debug ha misurato un hop sano a 27.9 ms di andata e ritorno, hop del worker e next() inclusi s3. claude plugin details ha valutato il Mod a circa 0 token aggiunti a ogni sessione: un Mod è codice nel processo, non testo di prompt, ed è l'argomento principale dei suoi promotori contro gli hook shell e le skill s7.
La guardia fallisce in modo aperto. Un Mod slow-guard che dorme 15 s è stato interrotto al budget di 10 s con hook failed: slow-guard: exceeded 10000ms budget (tool.call; skipped; what is below it ran in its place), ed echo hi è stato eseguito comunque s3. Un Mod throw-guard che lancia un'eccezione è stato saltato allo stesso modo, hook failed: throw-guard: boom (tool.call; skipped; what is below it ran in its place), segnalato a 574.2 ms s3. Rumoroso nel log, aggirato nell'effetto. Ogni Mod il cui compito è bloccare qualcosa va letto tenendolo presente: un bug nella guardia è un buco, non un crash.
Generare costa poco. Da una sola frase, il modello ha scritto un Mod funzionante di 190 righe più 53 righe di test in circa 4 minuti, 34 turni e $1.23 (19,053 token di output, 497,282 cache-read, 8,357 di thinking) s3. Quel Mod ha superato claude plugin validate senza avvisi e claude plugin test con 4 pass / 0 fail in 0.31 s, e nascondeva le chiavi in diretta s3. Sul Mod scritto a mano, claude plugin test è girato senza chiave API e senza chiamate al modello: 1 pass in 0.25 s s3. Esiste già una skill che insegna agli agenti a scrivere Mod, se vuoi ripetere l'esperimento con un template s12.
Cosa non si è riprodotto: $.ui.toast non è mai stato mostrato perché il Mod non si è caricato nella REPL pilotata via pty in 2 tentativi; con -p l'equivalente è comparso solo come riga di debug. È stato osservato l'opposto dell'affermazione "solo REPL" che circola su X, e la causa non è stata isolata s8. Anche l'heartbeat di 5 s per il worker bloccato non è stato testato; sono stati misurati solo il budget di attesa di 10 s e il percorso dell'eccezione.
Misure
| Caso | Cosa fa il Mod | Esito | Tempo |
|---|---|---|---|
| redact-secrets, tool Read | Riscrive result su tool.call |
Il modello vede API_KEY=[REDACTED] |
27.9 ms per hop |
| redact-secrets, tool Bash | Stesso hook, output della shell | Il modello vede API_KEY=[REDACTED] |
27.9 ms per hop |
| slow-guard | Dorme 15 s dentro tool.call |
Saltato, echo hi eseguito |
interrotto a 10000 ms |
| throw-guard | Lancia boom dentro tool.call |
Saltato, comando eseguito | 574.2 ms |
| Mod generato | 190 righe + 53 righe di test da una frase | validate: nessun avviso; test: 4 pass / 0 fail | ~4 min, 34 turni, $1.23 |
claude plugin test su redact-secrets |
Nessuna chiave API, nessuna chiamata al modello | 1 pass | 0.25 s |
claude plugin details |
Costo di sessione del Mod | ~0 token aggiunti | n/a |
Protocollo: Claude Code 2.1.272, function hooks abilitati da variabile d'ambiente. Ogni Mod è una directory di plugin con plugin.json, hooks/hooks.json e un solo index.ts. Le esecuzioni sono passate da claude -p con il logging di debug attivo; un file preparato e un comando shell contenevano entrambi sk-test1234567890abcdef. I casi fail-open sono stati guidati da un Mod che dorme 15 s e da un Mod che lancia un'eccezione, con echo hi come comando sotto guardia. La REPL interattiva è stata pilotata via pty e non ha caricato il Mod in due tentativi.
Da fare lunedì
- Esegui
/plugin-typesin una sessione e apri.claude/types/claude-code.d.ts: cercafs.readetool.callprima di fidarti di qualsiasi snippet di un post di settembre. - Scrivi lo scheletro del Mod in tre file (
plugin.json,hooks/hooks.jsoncon{"modules":["./index.ts"]},index.tsche esportaregister(on)) e lanciaclaude plugin validate: leggi le righe di improntahooks:ecalls:. - Porta il tuo hook shell più usato su un handler
tool.callche riscriveresult, poi confronta il tempo di hop nel log di debug con la versione shell. - Aggiungi un file
claude plugin testaccanto al Mod, così la guardia gira senza chiave API in CI. - Avvolgi ogni handler di guardia in un try/catch che restituisce
{ deny }in caso di errore: in questa build un'eccezione o uno stallo di 10 s ti fa saltare e lascia passare il comando. - Testa il Mod sotto
claude -pe nel tuo terminale interattivo reale separatamente, e annota quale lo ha caricato. - Prima di installare un Mod di terzi, esegui
claude plugin validatee scarta tutto ciò la cui rigacalls:nomina capacità dell'host che il Mod non ha motivo di usare.
Per approfondire
- Leggi per intero l'issue della proposta, compreso il PDF dell'architettura allegato nei commenti: è l'unico contratto scritto per
register(on), i budget e l'hop del worker s3. - Confrontalo con il design dei Command Code Mods, che esegue TypeScript contro una
ModApinel processo host: i due sistemi condividono la forma e l'accesso anticipato su invito s2. - L'anteprima di claudefa.st è stata scritta quando la funzione era ancora una proposta: utile per vedere cosa è cambiato tra il testo del 3 set e il binario 2.1.272 s9.
- La note tweet di Prathkum è l'enunciato breve più chiaro del perché gli hook in-process battano gli hook shell su token e latenza s7.
- cc-mod-waitwhat è un buon primo Mod da leggere: UI sopra il prompt, niente scritto nella trascrizione s11.
- cc-arcade mostra fin dove arriva
$.ui: giochi renderizzati sopra il prompt da un Mod s5. - La reference degli hook descrive ancora il modello shell; tienila aperta per mappare ogni vecchio evento sul nuovo nome
noun.events1. - Gli scettici su X sostengono che i plugin coprono già tutto questo e che la superficie si romperà a ogni release; il sostantivo
fsrinominato è un dato a loro favore s23.
Fonti
- Function Hooks proposal (issue #91870), GitHub, anthropics/claude-code. Perché leggerlo: l'unico testo simile a una specifica per i Mod, con il PDF dell'architettura e la traccia del rilascio nei commenti.
- Hooks reference, Claude Code docs. Perché leggerlo: il modello degli hook shell da cui stai migrando, evento per evento.
- Command Code Mods documentation, Command Code. Perché leggerlo: un precedente con la stessa forma TypeScript in-process, utile per capire cosa Anthropic ha copiato o evitato.
- awesome-claude-code-mods, GitHub, karanb192. Perché leggerlo: directory di Mod pubblici scansionata in automatico, con l'impronta di validate come unica verifica.
- cc-arcade, GitHub, sezaakgun. Perché leggerlo: la demo che ha reso visibile la funzione e un giro di
$.ui. - Boris Cherny announcement tweet, X, Boris Cherny. Perché leggerlo: l'annuncio di lancio di un ingegnere di Anthropic, dato che non esiste un post sul blog.
- Prathkum: Function Hooks explained, X, Prathkum. Perché leggerlo: la migliore spiegazione breve di hook contro Mod per chi scrive già hook shell.
- shipnotesai reaction thread, X, shipnotesai. Perché leggerlo: dove circolava l'affermazione "solo REPL", contraddetta dalla nostra prova.
- Claude Code Function Hooks: Preview Behind a Flag, claudefa.st. Perché leggerlo: spiegazione prima del rilascio, utile per confrontare la proposta con il binario.
- cc-mod-waitwhat, GitHub, GGGODLIN. Perché leggerlo: un Mod piccolo e leggibile che scrive nella UI e non nella trascrizione.
- claude-mods-skill, GitHub, BeLazy167. Perché leggerlo: una skill per generare Mod, se vuoi ripetere l'esperimento di una frase.
- AxialisSoftware reaction, X, AxialisSoftware. Perché leggerlo: il caso scettico, in un tweet.
FAQ
Un Mod sostituisce oggi i miei hook shell?
Non ancora per tutto ciò che deve bloccare. Su 2.1.272 un hook che lancia un'eccezione o si blocca oltre 10 s viene saltato e il comando viene eseguito. Gli hook shell continuano a funzionare, quindi tieni lì quelli bloccanti finché non arriva un catch dichiarato o un'opzione fail-closed.
Perché validate è importante se il Mod gira bene?
Perché le sue righe hooks: e calls: sono l'unica vista statica di ciò che un Mod tocca su $. Per il tuo Mod conferma l'impronta; per un Mod di terzi è tutta la revisione che ottieni prima che il codice giri nel tuo processo.
Quanto costa un Mod per sessione?
claude plugin details ha riportato circa 0 token aggiunti. Il Mod è codice che gira nel motore, non testo nel prompt, ed è il vantaggio principale rispetto a una skill o a una regola in CLAUDE.md.
Perché il Mod si è caricato con -p ma non nella REPL?
Non si sa. Due tentativi pilotati via pty sono rimasti muti mentre claude -p ha caricato e applicato l'hook. È probabile che la causa sia l'ambiente pty e non la funzione, quindi prova sul tuo terminale prima di fare affidamento su una delle due direzioni.
AIDive