C'è un file in ~/.claude.json che non avevo mai aperto di proposito. In mezzo a parecchia telemetria, tiene un contatore per ogni plugin e ogni skill che Claude Code ha mai caricato sulla mia macchina: quante volte è scattato ciascuno, e quando. L'ho aperto mentre scrivevo questo post, per controllare un numero che stavo per citare a memoria.
Mostrava un setup con un nucleo chiaro. Le cinque skill che uso ogni giorno vengono tutte da un solo plugin, con conteggi nell'ordine delle decine. Il language server di Swift è scattato più di mille volte, il plugin del browser qualche centinaio. Attorno a quel nucleo c'è una lunga coda che avevo smesso di notare: un pacchetto di plugin installati per il giorno in cui potrebbero servirmi, la maggior parte ancora a zero, e un pacchetto di 84 skill per i framework Apple di cui otto sono mai scattate. Niente di tutto questo è rotto o costoso di per sé, ma ogni voce costa una riga in ogni prompt, e il file lo ha reso visibile in un modo in cui la mia memoria non riusciva.
Questo post parla quindi del nucleo: cosa configurerei per primo su una macchina nuova, perché ogni pezzo è lì, e come puoi costruire lo stesso setup in un pomeriggio. Il mio ultimo side project è un'app per iPhone, quindi molti esempi riguardano Swift, simulatori e Xcode. La maggior parte della mia vita lavorativa è fatta di Go, Terraform, configurazioni Kubernetes e altri tipi di YAML, e niente di quello che segue dipende dallo stack; dove aiuta, dico com'è quella versione. Una sessione intera, dall'inizio alla fine, è in cima alla sezione sulle skill. Se leggi una sola sezione, leggi l'ultima.
Il modello che uso per ragionarci
Quello che voglio da Claude Code non è codice. È codice che farei il merge, in una codebase con cui devo convivere, senza leggere ogni riga due volte. Far scrivere codice a un LLM è facile da un paio d'anni. Ottenere la seconda cosa è un problema di sistema, e lo tratto come tale: vincolare gli input, automatizzare i controlli, e rendere il ciclo di feedback abbastanza veloce da far costare poco gli errori.
Divido il setup in prosa e macchinario perché la documentazione di Anthropic è schietta su cosa può fare la prosa. I file CLAUDE.md sono "contesto, non configurazione applicata", con "nessuna garanzia di rispetto rigoroso". Per bloccare un'azione qualunque cosa decida il modello, si usa un hook o una regola di permessi. Ogni "mai" nel tuo file di istruzioni è una richiesta che il modello rispetta il più delle volte, e il più delle volte non è sempre.
La prosa quindi forma il giudizio: cos'è il progetto, cosa è fuori scope, quale pattern copiare, cosa ti ha già fregato in passato. Il macchinario garantisce i risultati: warning come errori, il linter in modalità strict, la suite di test su un checkout pulito, uno script che fa fallire la build quando un layer importa qualcosa che non dovrebbe. Quando il modello continua a ignorare una regola, non gridare più forte nel markdown. Se un controllo può esprimere la regola, mettila lì. Se non può, e molti non possono, la risposta è un tooling migliore attorno al modello, non un file di istruzioni più lungo.
Il ciclo decide quanto puoi delegare. Su un progetto web il modello scopre di aver sbagliato in pochi secondi, da un lint e da un giro di unit test. Su un progetto iOS è xcodebuild ... build test su un simulatore fissato, e sono minuti. Un ciclo lento significa pianificare di più prima di costruire, raggruppare i push perché ognuno costa un runner di CI, e lasciare il modello lavorare senza supervisione solo quando i controlli sono abbastanza buoni da non doverlo guardare.
La mia configurazione di Claude Code, e a cosa serve ogni pezzo
Ecco cosa c'è sulla mia macchina e perché, così puoi scegliere cosa si applica a te.
Piano e modello. Voglio sessioni lunghe e senza supervisione senza pensare alla quota, quindi sono sul piano Max 20x finché costruisco nel tempo libero; scenderò a 5x o Pro quando non lo farò. Il modello è la variante con contesto da 1M del modello top attuale, e il contesto lungo è la funzionalità che mi mancherebbe di più. Su 20x non ho mai raggiunto un limite. Su 5x l'ho raggiunto una volta, nel mezzo di un'esecuzione con subagent in parallelo, e l'ho fermata con "Così in parallelo costa troppo. Fai i task uno alla volta." Pro sarebbe un problema di limiti ogni giorno. Per dare una scala, la stima di Claude Code stesso per una sessione di due ore su un'app iOS è di circa 54 dollari in costo API equivalente, un quarto d'ora di bug fixing circa 6; l'abbonamento lo copre. Su un livello più piccolo, pianifica di più in un solo contesto, lancia meno subagent, e sorveglia le esecuzioni lunghe.
Permessi. Voglio approvare quasi niente a mano e avere comunque una lista corta di cose che non vengono mai toccate, quindi i permessi girano in modalità auto. Un classificatore decide, in base a una descrizione del mio ambiente nelle impostazioni: quale repository è fidato, che non c'è nessun cloud provider da proteggere, che qualunque cosa con prod nel nome è sensibile, e quali comandi di build e lint sono routine. I progetti aggiungono piccole allowlist e qualche regola di deny; un repo di utilità ne ha esattamente due, entrambe a proteggere un file di dati dal venire mai scritto dal modello. Scrivi la descrizione del tuo ambiente una volta, onestamente, e metti i percorsi davvero pericolosi nelle regole di deny, dove nessun prompt può arrivare.
Istruzioni globali. Non c'è nessun ~/.claude/CLAUDE.md, perché ogni regola dovrebbe vivere accanto al codice che governa. L'unica regola a livello utente dice al modello di cercare la documentazione delle librerie tramite Context7 prima di rispondere a memoria, anche per i framework che pensa di conoscere. Quella vale ovunque; nient'altro lo fa.
Skill e plugin. Quelli che contano: un plugin di processo (superpowers), un language server per lo stack in cui sto di più in questo momento (Swift, per via del progetto iOS; anche quello di Go è installato), automazione del browser (Playwright), consultazione della documentazione (Context7), ricerca nel codice consapevole dei simboli (Serena), un agente revisore (feature-dev), un controllo di sicurezza a ogni modifica, e humanizer per qualunque cosa una persona leggerà. Sul lato MCP, due server globali, Kubernetes in modalità sola lettura e XcodeBuildMCP, altri due limitati a un solo progetto, e il resto arriva con i plugin. Lo stile di output è Concise, perché leggo il risultato, non la narrazione. Tutto il resto è la lunga coda; la sezione sulla potatura se ne occupa.
Memoria e notifiche. La memoria automatica è attiva, così le correzioni restano. Il plugin del terminale Warp manda una notifica nativa quando una sessione si ferma o ha bisogno di input, anche le notifiche push su mobile sono attive, e quindi posso allontanarmi da una sessione in corso. ~/.claude vive nel mio repo di dotfiles, così posso vedere cosa ho cambiato.
CLAUDE.md è un contratto, non documentazione
Il file per progetto è la cosa che salverei da un incendio, perché è dove il modello impara cos'è il progetto e cosa non deve mai fargli. I miei due file più sviluppati vengono da un unico template, che ho fatto progettare a Claude. Il brief chiedeva un CLAUDE.md definitivo: ricercare cosa raccomanda Anthropic, estrarre dal mio file di progetto esistente ciò che era universale, e smistare ogni requisito in prosa, hook, controllo in CI, skill, o scartato. Aveva un vincolo che ti direi di rubare:
Budget the rule surface, not the line count: context lines (commands,
vocabulary, maps, budgets) are cheap and prevent mistakes; rule lines
(prohibitions, rituals) are expensive and dilute each other.La documentazione di Anthropic dice di puntare a meno di 200 righe per file. Penso che conti la cosa sbagliata. Una mappa del repository, il comando esatto dei test con l'UDID del simulatore, una tabella dei termini di dominio: quelle righe prevengono una modifica sbagliata. "Tieni il codice pulito" costa gli stessi token, non cambia nessun diff, e diluisce le regole accanto a sé. Il mio template limita le regole sempre attive a quaranta-sessanta righe e lascia correre i fatti. Entrambe le mie app iOS si assestano attorno alle 520 righe, per lo più fatti.
La sezione che si guadagna il posto è "Things that will bite you", perché impedisce al modello di cadere in una trappola che ho già pagato. Da Qroda, l'app per iPhone che sto costruendo (di più nella pagina dei progetti), alcune voci sulla toolchain:
- **Two simulators named "iPhone 17"** (iOS 26.4 + 26.5) — always pin
`-destination` by UDID; a name-based erase+test pair can hit different devices.
- **Swift Testing prints a fake XCTest summary** ("Executed 0 tests") — grep
`Test run with N tests`, never the XCTest line.
- When grepping xcodebuild output, match `": error:"` — a bare `error` matches
unrelated tool paths in the environment dump.
- **Every plain push to `main` runs macOS CI** unless it only touches
`docs/**`, `site/**`, or `**.md`. Batch accordingly.Il file di questo sito ha la stessa sezione: il plugin Tailwind di Prettier si mangia lo spazio iniziale in un frammento condizionale di class name, quindi scrivi stringhe complete per ogni ramo; cancellare .next mentre il dev server gira lo corrompe; un 404 in dev avvelena la sessione fino al riavvio. Ogni voce mi è costata un pomeriggio e salva una sessione con regolarità. Inizia questa sezione dal primo giorno e aggiungici nello stesso commit del fix. Non sopravvive mai a un passaggio "tienilo sotto le 200 righe", ed è la parte che ti mancherebbe di più.
L'altra cosa da decidere una volta sola è l'architettura, perché un modello addestrato su un decennio di post di blog usa come default quello che faceva il post medio. Per iOS è un ViewModel per schermata e un refetch manuale dopo ogni scrittura. Il blocco sullo stack di Qroda dice che la view è il layer view-model, che il framework di persistenza è l'unica fonte di verità e non viene mai rifetchato a mano, e che le view non importano mai direttamente un framework di sistema. Senza quelle regole ottengo MVVM. Con quelle ottengo l'architettura che ho scelto. Scrivi la tua prima della prima feature, non dopo la terza riscrittura.
Il template ha sedici sezioni, riassunte verso la fine di questo post: i fatti del progetto in cima, le regole universali in mezzo, la manutenzione alla fine. Per iniziare ti servono il blocco dei fatti, un workflow, e una regola di manutenzione. Tre sezioni meritano uno sguardo adesso.
La sezione sul workflow adatta la cerimonia alla dimensione della modifica:
- **Direct:** the diff can be described in one sentence and has no behavioural
effect a user or caller would notice (a typo, a rename, a comment, a config
value). Do it.
- **Plan only:** a behavioural change whose approach is obvious and whose blast
radius is one module — a well-understood bug fix, a small addition matching
an existing pattern. Skip Phase 1; write the Phase 2 plan, get approval,
implement.
- **Full:** anything multi-file, unfamiliar, ambiguous, architectural, or
touching a §1 security-critical path. All three phases.Le fasi sono brainstorm, piano, implementazione, ognuna con il nome della skill che la esegue. "Fatto" è definito una volta sola: comando di check e test verdi con i risultati nel report, test a ogni livello applicabile, documentazione nello stesso diff, e, sopra il livello direct, una revisione a contesto fresco e un percorso di rollback dichiarato. Una volta sola, di proposito: ripetere "esegui sempre i test" porta il modello a verificare troppo.
Il piano è un documento sotto docs/superpowers/plans/, così posso approvarlo e i subagent possono eseguirlo senza di me. Si legge come un ordine di lavoro. Uno recente si apre con una lista di "Global Constraints" di questo tenore:
- Approachable Concurrency is on: blocking leaves need `@concurrent`;
clustering is microsecond arithmetic and deliberately stays on the caller's
actor — do NOT mark it `@concurrent`.
- No `try!`, no force unwraps outside tests, no `fatalError`; warnings are
errors; strings `String(localized:)`.
- If a launch test stops passing because the first tab changed, changing
that test is a DELIBERATE test change: its own commit, message explaining
the launch surface.e si chiude con "Done-bar verification": build e test su ogni destinazione, un report onesto per destinazione, i fallback usati, cosa non è stato fatto, e il rollback ("revert della PR"). I subagent spuntano le caselle man mano.
La mia regola preferita fa sì che il modello mi dica quando un hook o un file di regole ci avrebbe fatto risparmiare tempo, invece che accorgermene io tre correzioni dopo:
- **Propose the harness feature, not just the code.** When a request, a
repeated correction, or a mistake you just made would have been prevented or
made cheaper by a Claude Code capability this repo does not use yet — a hook
for "every time X", a `.claude/rules/` file for a path-scoped constraint, an
isolated worktree or subagent for parallel or risky work, a scheduled or
looped run for a recurring check — say so in one line with the concrete
config, and let the user decide.Il modello suggerisce dove dovrebbe andare il suo stesso guinzaglio, e io posso dire di no. Aggiungila al tuo file. È un paragrafo, ed è così che il kill switch della sessione qui sotto è finito nel mio.
La sezione di manutenzione fa sì che il file si restringa oltre che crescere:
This file is code. When Claude misbehaves, find the rule that allowed it and
patch that rule — or, if the rule is one it keeps ignoring, move it into CI,
pre-commit, or a hook where it cannot be ignored. When Claude already does
something correctly without a rule, delete the rule.Quell'ultima frase è quella che la gente dimentica. Una regola che il modello segue comunque è puro costo.
Test, lint e CI: le barriere contro cui Claude Code va a sbattere
Le istruzioni portano il modello a scrivere il tipo giusto di codice. Le barriere impediscono al tipo sbagliato di essere mergiato, e le configuro in modo che sia il modello, non io, a scoprire che qualcosa non va.
Su Qroda il modello incontra tre controlli a ogni push: un formatter in modalità lint e un linter con --strict, così un diff di formattazione o un warning fanno fallire la build prima che io veda la PR; la suite di test su un simulatore fissato per UDID; e una scansione del codice morto, così gli avanzi di un refactor falliscono invece di finire nella mia revisione. Sulla mia app più recente le barriere sono più severe di proposito, così il "no" arriva dal compilatore: i warning sono errori su ogni piattaforma, la strict concurrency è attiva, e uno script shell in CI e nel pre-commit applica le regole sui layer di CLAUDE.md (il layer di dominio importa solo Foundation, ogni layer ha una allowlist di framework, niente importa un framework di rete), fallendo con un path:line: rule per ogni violazione. Quello script esiste perché "le view non importano mai un framework di sistema" è esattamente il tipo di regola che il modello rispetta il più delle volte.
Niente di tutto questo è specifico di iOS. Su un servizio Go è go vet, golangci-lint al massimo della severità, e go test -race su un checkout pulito, più un controllo sui confini degli import se il repo ha layer che vale la pena proteggere. Su Terraform è terraform validate, un linter, e un plan a ogni pull request che un umano legge prima che qualunque cosa venga applicata. Su configurazioni Kubernetes è un controllo dello schema e un dry run lato server. Stesso punto: il modello scopre di aver sbagliato da uno strumento, prima che lo scopra io da una revisione.
Su questo sito le barriere sono ciò che il modello supera prima di poter dichiarare finita una modifica alla UI: unit test, ESLint con Prettier dentro, una build di produzione, e una suite Playwright con un passaggio di accessibilità che fallisce sulle violazioni serie. Dopo ogni modifica alla UI il modello esegue tutti e quattro, poi guida l'app in esecuzione nel browser di Playwright a 390 pixel di larghezza, perché la suite gira a 1280 e non coglierebbe l'overflow su mobile. Il banner in cima a questo post mostra perché quell'ultimo passo conta. Brief, design canvas, scelta di una direzione, implementazione con i token del sito, screenshot a 1280 e 390. Il primo screenshot mostrava gli stili di prosa dell'articolo che aggiungevano margini ai titoli dentro la card. Nessun test l'avrebbe colto; uno screenshot sì. Se fai lavoro di UI con Claude Code, dagli un browser e fallo guardare.
Il fallimento di una barriera dovrebbe avere una forma precisa, e il miglior esempio recente è un crash in CI che il modello ha risolto. Il framework di sync che usa la mia app più recente va in trap, in modo non catturabile, quando il processo non ha l'entitlement iCloud, e una build in CI con la firma del codice disattivata non ce l'ha. Così le build non firmate sul runner GitHub crashavano prima che girasse qualunque test, su una coda in background dove nessun catch poteva vederlo. Il fix vale la pena descriverlo per quello che non ha fatto: non ha cancellato il test e non ha saltato il ramo macOS. I rami sui simulatori ora firmano ad hoc così l'entitlement è incorporato, e il ramo macOS lo controlla in anticipo e degrada a uno stato "non disponibile" progettato, con i test di UI che richiedono uno stato sano spostati sui rami che possono averlo. Il commit ha anche aggiunto la trap a "Things that will bite you". Risolvi la causa, mantieni la barriera, annota la sorpresa.
Le barriere mi proteggono anche dall'istinto peggiore del modello, far diventare verde un check rosso con qualunque mezzo disponibile. Le regole dure del template, che prevalgono su tutto compreso un piano approvato, includono questa:
5. Never disable, weaken, or skip a test, type check, or lint rule to make a
check pass (§7).Di tutte le barriere, la suite di test è quella che cambia cosa il modello può fare, perché è il modo in cui il modello verifica il proprio lavoro. Senza test, "fatto" significa "ha compilato e l'ho riletto". Con i test, ogni task che un subagent prende in carico ha un controllo attaccato, e il modello lo esegue prima di riportare. Ecco perché il template dice che ogni modifica comportamentale arriva con i test, ogni bug fix con un test di regressione che fallisce prima del fix, e l'implementazione passa dalla skill di test-driven development: test che fallisce, codice minimo, refactor. Anche le regole più importanti dovrebbero essere test, perché un test è una regola con cui il modello non può discutere. In Qroda, il backend di sync richiede che ogni nuova proprietà del modello sia opzionale o con un default; un test di migrazione lo fissa, così un campo non opzionale fa fallire il test prima che il backend fallisca sul telefono di qualcuno. Dove puoi trasformare una regola in un test, fallo, e la versione in prosa diventa un commento sul perché il test esiste. Migliori sono i tuoi test, più puoi delegare.
Per essere onesto sulle lacune: il template elenca il mutation testing "dove lo stack lo supporta" e un lint dei messaggi di commit tra le cose che la CI deve coprire, e nessuno dei due esiste in nessuno dei due repo. Il brief chiedeva un hook che renda i file di test in sola lettura per l'agente, cosa che la ricerca che avevo letto indicava come il modo singolo più efficace per impedire a un modello di barare sui propri test. Non l'ho costruito, e non ho nessun hook mio. La regola sui test regge perché la CI esegue la suite su un checkout pulito e un umano rivede i diff dei file di test, che è più debole di un hook, e lo so. Se costruisci quell'hook prima di me, dimmelo.
Skill, subagent e comandi di Claude Code, e quali uso davvero
Ecco una sessione, dall'inizio alla fine. Su Qroda volevo una feature che legge da Apple Health, e ho aperto con una domanda invece che con un ordine: l'app può prendere la frequenza cardiaca dal watch, o da Health in generale, e può registrare l'attività sotto un tipo diverso? La skill di brainstorming è tornata con il problema riformulato, cosa permette Health, due modi per ottenere i dati, e i compromessi. Ne ho scelto uno. La skill di pianificazione ha scritto un piano nel repo: file da toccare, test da aggiungere, cosa dovrebbe fare un dispositivo senza watch, il rollback. Ho chiesto due modifiche e l'ho approvato. Il modello ha chiesto come eseguire, ho risposto "subagent", e ha lavorato il piano un task alla volta, ognuno in un contesto fresco, con i test e il linter come arbitro. La CI era verde. La feature è atterrata in un commit, il piano in un altro. E grazie alla regola sull'harness, si è chiusa con un suggerimento: mettere la feature dietro un kill switch locale, visto che l'app non ha un backend da cui attivare un flag remoto. Ho detto di sì, e quel pattern ora è una riga nel file di progetto. Gli unici prompt che ho scritto sono stati la domanda, due modifiche, e una parola.
Voglio che ogni sessione segua quella procedura senza che io la scriva, ed è quello che fanno le skill su cui mi appoggio di più. Vengono tutte da un solo plugin, superpowers, e sono skill di processo più che di conoscenza: brainstorming, scrittura dei piani, sviluppo guidato dai subagent, debugging sistematico, e chiusura di un branch di sviluppo, in quest'ordine di utilizzo. Ogni fase della sessione qui sopra era una di loro che faceva il suo lavoro. I prompt che aprono una sessione sono brevi, perché la procedura la portano le skill:
Find every TODO in the codebase. Brainstorm how to resolve each one, write a
plan, and implement it once I've approved the plan.
Do all of the remaining roadmap items. Use worktrees and subagents where the
work is independent. When you're done, remove the completed items from the
README."Subagent" è nella mia cronologia più volte di qualunque altro prompt. Non uso la plan mode integrata; la skill fa lo stesso lavoro e lascia dietro di sé un documento. Se installi un solo plugin, installa questo, e nomina le sue skill nella mappa degli strumenti del tuo file di progetto, perché il modello non le usa in modo affidabile da solo.
Le skill di conoscenza scattano solo quando qualcosa le indica. Ho un pacchetto di 84 skill per i framework Apple installato, una per framework. Otto sono mai scattate, e le otto sono esattamente quelle che la mappa degli strumenti di Qroda nomina:
| Any Apple framework API, availability, behaviour | Context7 MCP, then the matching repository skill (`swiftui-*`, `swiftdata`, `cloudkit`, `storekit`, `mapkit`, ...) |
| Prose the user will post (PRs, commits, ADRs, team messages) | `humanizer` skill |I plugin dei language server fanno lo stesso punto dall'altra direzione: quello di Swift è scattato più di mille volte, mentre quelli di TypeScript, Go, Rust e C, installati con lo stesso click, stanno a zero. Nessuno cura le skill a mano, e nemmeno io. Un pacchetto per uno stack che tocchi ogni tanto può restare lì; una skill inutilizzata costa una riga di contesto e un language server inattivo non costa niente. Quello che conta è che lo stack in cui lavori davvero abbia il suo pacchetto installato e le sue skill nominate nel file di progetto, perché una skill che nessuno indica non scatta mai.
Humanizer c'è perché non voglio che niente di ciò che lascia la mia macchina si legga come scritto da un modello. Toglie i segni distintivi della prosa scritta a macchina, e lo chiamo per nome per un sito marketing, le descrizioni sull'App Store, i riepiloghi di lavoro, questo post.
La revisione deve cogliere ciò che l'implementazione ha mancato, quindi non può condividere il contesto dell'implementazione. Non ho definizioni di agenti personalizzate; uso il pattern dei subagent di superpowers e l'agente revisore di feature-dev, che la mappa degli strumenti nomina per la revisione a contesto fresco. Dopo l'implementazione, il diff viene rivisto una volta in un contesto fresco, limitato a correttezza e requisiti dichiarati: "segnala le lacune, non segnalare preferenze di stile". Un revisore che condivide il contesto dell'implementatore ne condivide i punti ciechi, e un revisore con una lunga checklist di audit trova qualcosa da dire su tutto, quindi la checklist vive in una skill chiamata in quel momento e da nessun'altra parte.
Non ho scritto nessuno slash command. Il plugin che fornisce /commit e /commit-push-pr è scattato una volta, in totale, e chiedere a un modello di fare commit e push è comunque eccessivo; quella è memoria muscolare. Dove il modello si guadagna il posto in git è la parte che una volta temevo: il rebase di un branch di lunga vita, districare un conflitto di merge su una dozzina di file, spezzare un working tree disordinato in commit che abbiano ciascuno un senso. Legge entrambi i lati di un conflitto più in fretta di me e spiega cosa ha risolto. Gli slash command sono per le cose che fai sempre allo stesso modo e che non riesci a descrivere in una frase, e la maggior parte delle persone non ne ha molte.
MCP, e il budget di contesto
Voglio che il modello abbia le mani sulle cose che tocca di continuo, e su nient'altro, quindi la lista MCP è corta: Kubernetes in modalità sola lettura e XcodeBuildMCP a livello globale; Playwright, Context7, GitHub, Serena e Vercel tramite plugin; xcrun mcpbridge di Apple e un server per la documentazione Apple limitati a Qroda.
Ognuno ha un compito che il modello svolge in ogni sessione. XcodeBuildMCP è nominato nella sezione Commands di entrambi i progetti iOS come il modo per compilare, eseguire e testare su un simulatore. Context7 porta la regola globale di cercare la documentazione delle librerie prima di rispondere, perché i framework Apple che uso "sono cambiati in modo sostanziale nelle release recenti". Playwright è il modo in cui il modello controlla una pagina web che ha modificato invece di dirmi che va bene. Il plugin di GitHub è per il lavoro sulle PR. Kubernetes è quello che uso da ~/.kube per fare una domanda a un cluster in linguaggio naturale, e la sola lettura è tutto il punto: non può essere convinto a fare un delete. Serena funziona quando un file di progetto dice al modello di usarla per dichiarazioni e call site invece di grep; altrimenti resta inattiva.
Tieni la lista corta per lo stesso motivo per cui tieni il file di istruzioni corto sulle regole: ogni strumento che un server MCP espone è uno schema che il modello si porta dietro a ogni turno. La ricerca degli strumenti, che carica gli schemi solo quando servono, aiuta; non rende gratuito un server morto. Installa un server quando un file di progetto lo richiede, e preferisci la modalità sola lettura quando ce n'è una.
Potatura: chiedere a Claude di fare l'audit del proprio setup
Voglio che il setup resti della dimensione di quello che uso, e il modo più economico che ho trovato è far fare l'audit a Claude stesso. Apro una sessione nella mia home directory e chiedo, in tre passi:
Which skills, MCP servers and plugins has Claude Code actually used on this
machine? Show me the usage counts and last-used dates.
Which of the MCP servers do something the built-in tools don't?
Are any plugins and MCP servers duplicates of each other? Where they are,
keep the plugin and uninstall the server.Claude sa dove sono i propri contatori (skillUsage e pluginUsage in ~/.claude.json, un conteggio e una data di ultimo uso per voce) e li legge. Poi cancello cose. I due server MCP globali sono quello che resta dopo quell'audit. Questo post ha innescato l'ultimo passaggio, che ha trovato un pacchetto da 57 plugin a zero, 76 skill Apple inattive, un plugin per un backend che una delle mie app non ha più, due plugin di stile didattico che iniettavano istruzioni in ogni sessione (ora spariti), e un plugin per gli hook che era girato 64.000 volte senza nessun hook da eseguire.
"Inutilizzato" significa quello che dice il contatore: zero usi in tutte le sessioni. Ho smesso di indovinare se potrei volere una cosa più avanti; il pacchetto era quell'ipotesi, e il contatore è la sua pagella. Se un progetto ha bisogno di una capacità, il suo CLAUDE.md la nomina e la installo allora. Installare è un comando; portarsi dietro la cosa è una tassa su ogni turno. Finora ho eseguito l'audit quando il setup sembrava lento, due volte; mensile è la cadenza a cui sto passando, non una per cui posso ancora garantire. Ci vogliono dieci minuti, e il modello è bravo a farlo, perché per una volta la domanda ha una risposta numerica.
Non solo codice
Lo stesso setup regge le sessioni che non stanno in un repository di codice, circa una su dieci delle mie. Due recenti mostrano cosa ci si guadagna.
Volevo le mie foto di Unsplash anche su Pexels. Pexels non ha un'API di upload, il che significava una serata a reinserire a mano titoli, tag e località. Ho chiesto se Claude Code potesse farlo se gli avessi dato entrambi gli account e le foto. Ha scritto un piccolo script ripristinabile che ha tirato giù tutte le 89 foto con i loro tag e le località dall'API di Unsplash in un manifest, ha scaricato gli originali in una cartella pending, e poi li ha caricati su Pexels in batch da 50 tramite il browser, spostando ogni file in uploaded man mano, così un crash non poteva causare un duplicato. Il manifest è lo stato, le cartelle sono la barra di avanzamento, e potevo allontanarmi.
Volevo una mappa di luoghi per la fotografia e le gite in giornata nel Triveneto, l'angolo nord-orientale d'Italia fatto di Veneto, Trentino-Alto Adige e Friuli-Venezia Giulia, che rispettasse i miei criteri: raggiungibile da casa, degno di un obiettivo, non un parcheggio con vista. È iniziata nell'app di chat: ho fatto generare liste a Claude e le ho riversate in Google My Maps, il che mi ha lasciato con sette livelli, sette schemi incoerenti, 3.549 pin, e parecchio dello stesso posto tre volte. Claude Code ha poi costruito la pipeline che ha sistemato tutto: parsing, normalizzazione degli schemi, geocoding delle voci con solo l'indirizzo tramite OpenStreetMap con il modello a risolvere i nomi che nessun dizionario geografico riconosce, clustering di qualunque cosa entro cento metri, merge, e produzione di un unico livello pulito di 2.286 luoghi dove ogni duplicato unito sopravvive come campo "Nearby". Il file sorgente che ha dato inizio a tutto è l'unico file su cui il modello non può mai scrivere.
Il resto è più piccolo: batch nella mia cartella di export fotografico, domande a un cluster da ~/.kube, riepiloghi di lavoro scritti con humanizer attivo così si leggono come miei, le prime bozze di ogni testo per l'App Store, ogni messaggio di commit. Il pattern è lo stesso: descrivi il risultato, dagli gli account o la cartella, tieni lo stato in file così un crash è ripristinabile, e leggi il risultato prima che vada da qualche parte.
Dove cade, e cosa non delego
I fallimenti che mi interessano non sono quelli in cui il modello scrive un bug; per quelli ci sono le barriere. Quelli che mi costano tempo sono dove il sistema attorno al modello è sbagliato, e ne ho imparati quattro nel modo lento.
Il primo è chiedere accuratezza invece di specificarla. "Fai l'audit di tutto. Non dimenticare niente." produce un report con la forma dell'accuratezza, e il modello manca comunque la cosa che troveresti in cinque minuti usando l'app su un telefono vero. Qualunque cosa tu non riesca a esprimere come test, o come regola che nomina il fallimento, aspettati che la manchi. La regola "native-first" di Qroda esiste esattamente per quel motivo: un componente fatto a mano dove la piattaforma ne forniva già uno, trovato usando l'app, non da nessun audit.
Il secondo è perdere traccia di ciò che il modello ha già fatto. Ripulendo una checklist di release, ho scritto "L'audit è già stato fatto? Se no, eseguilo, poi cancella le voci completate." Non riuscivo a capire dai documenti se un task fosse avvenuto. È un fallimento di documentazione da parte mia, e la regola del template per cui ogni modifica completata riporta "cosa è cambiato, i comandi eseguiti e i loro risultati, cosa non è stato fatto" esiste per questo.
Il terzo è una regola che sparisce in silenzio. I file di istruzioni vengono ristrutturati, e una regola funzionante può cadere senza che nessuno decida di rimuoverla. L'unico sintomo è un contatore d'uso che smette di muoversi. Fai il diff del vecchio file contro il nuovo come faresti con il codice.
Il quarto è il costo. Lo sviluppo guidato dai subagent si espande a ventaglio. Su 20x non è mai stato un problema; su 5x lo è stato, una volta, e sono sceso a un task alla volta. Su un livello più piccolo, pianifica di più in un solo contesto, lancia meno, e tieni il modello fuori dai cicli senza supervisione. La finestra mobile di cinque ore sui piani a pagamento è ciò che dà forma a una giornata, più di qualunque numero per token.
Quello che faccio ancora io è una lista più corta di quanto fosse, e non sono sicuro di dove si assesterà. Comunicazione verso l'esterno, soprattutto: il modello scrive le bozze dei testi per lo store, delle note di rilascio e dei riepiloghi, e io decido cosa esce con il mio nome sopra. Le scelte architetturali costose da invertire passano da un ADR che leggo e approvo; il framework di rendering della mia app più recente è stato scelto in base ai numeri di uno spike su hardware reale, non in base all'opinione del modello. E leggo ogni diff, che è meno un confine che il lavoro stesso.
Ottenere la stessa configurazione di Claude Code
Il singolo cambiamento che ha fatto la differenza più grande su quanto Claude Code è buono per me è stato installare plugin e skill per lo stack in cui lavoro davvero. Di serie il modello conosce un framework come lo conosce un buon generalista. Con un language server vede quello che vede l'IDE, con un pacchetto di skill conosce gli idiomi attuali invece di quelli di due release fa, e con un browser può guardare quello che ha costruito. Ecco cosa uso, con i link.
I plugin vengono da tre marketplace. Quello ufficiale arriva con Claude Code; gli altri due li ho aggiunti con /plugin marketplace add.
- anthropics/claude-plugins-official: quelli che uso ogni giorno sono
superpowers(le skill di processo, da obra/superpowers),playwright,context7,github,vercel,serena(ricerca nel codice consapevole dei simboli, da oraios/serena),feature-dev(l'agente revisore),security-guidance, eswift-lsp. Installa il plugin LSP per il tuo linguaggio; TypeScript, Go, Rust e C sono nello stesso posto. - warpdotdev/claude-code-warp: notifiche native quando una sessione si ferma o ha bisogno di input, se il tuo terminale è Warp.
- blader/humanizer: toglie i segni distintivi della prosa scritta a macchina.
- wshobson/agents: un grande marketplace della community con plugin a forma di ruolo. Ne ho installato la maggior parte e non ne uso quasi nessuno. Scegli i due o tre che corrispondono al tuo stack e salta il resto.
I pacchetti di skill si installano con la CLI skills di vercel-labs/skills: npx skills add owner/repo li mette in ~/.agents/skills e li collega a Claude Code. Sulla mia macchina:
- dpearson2699/swift-ios-skills: una skill per ogni framework Apple, aggiornata a iOS 26 e Swift 6. Il pacchetto a cui punta la mappa degli strumenti di Qroda.
- vercel-labs/agent-skills e expo/skills: skill per Next.js, React ed Expo per il lato web.
Server MCP, oltre a quelli che portano i plugin:
- containers/kubernetes-mcp-server, eseguito con
--read-only, per fare domande a un cluster. - getsentry/XcodeBuildMCP, il ciclo di build, esecuzione e test per i simulatori, più
xcrun mcpbridgedi Apple che arriva con Xcode 26. - kimsungwhee/apple-docs-mcp per la documentazione Apple, limitato al progetto iOS.
E il CLAUDE.md principale, riassunto, così puoi scrivere il tuo o farlo scrivere a Claude dallo stesso brief. Sedici sezioni in tre gruppi.
Fatti del progetto, per repo, lunghi quanto serve: cos'è il progetto e dove vive la specifica; cosa è esplicitamente fuori scope; una tabella del vocabolario di dominio; stack, fornitori e ambienti; una mappa del repository; i comandi esatti per avviare, testare, un singolo test, le migrazioni e il controllo di "fatto"; una mappa degli strumenti da argomento a skill, server o documento da consultare; file da non modificare mai a mano; convenzioni; classificazione dei dati; percorsi critici per la sicurezza; budget in numeri; dove vive ogni tipo di test; la suite di documentazione; "things that will bite you"; convenzioni git e CI.
Regole universali, quaranta-sessanta righe: usa le skill installate, non inventare mai una superficie API, proponi la funzionalità dell'harness quando una avrebbe aiutato; classifica ogni modifica come direct, plan-only o full, con "fatto" definito una volta; la modifica più piccola che risolve completamente la richiesta, nessuna dipendenza o fornitore senza chiedere, la terza occorrenza giustifica l'estrazione; codice dei fornitori dietro un layer interno; ogni modifica comportamentale arriva con i test, un bug fix con un test di regressione, mai indebolire un test per farlo passare; segreti solo dall'ambiente; una storia di osservabilità in ogni piano; prestazioni e costi rispetto ai budget; revisione in un contesto fresco; modifiche allo schema tramite migrazioni e infrastruttura tramite codice; conventional commits; documentazione nello stesso diff; sette regole dure che prevalgono anche su un piano approvato; rendicontazione onesta, incluso ciò che non è stato fatto.
Manutenzione: il file è codice. Correggi la regola che ha permesso un errore, sposta in un controllo una regola che il modello continua a ignorare, cancella una regola che il modello segue comunque, e aggiungi ogni sorpresa a "things that will bite you" nella stessa modifica. Un blocco di personalizzazione per lo stack alla fine contiene le regole che un linter non può esprimere per la tua piattaforma.
Se preferisci non scriverlo a mano, il brief è la scorciatoia. Chiedi a Claude un CLAUDE.md definitivo con il vincolo sulla superficie delle regole citato prima, dagli il tuo file di progetto attuale da cui estrarre, e fagli smistare ogni regola in prosa, hook, controllo in CI, skill o scartata prima che scriva qualunque cosa. Il mio ha richiesto un pomeriggio e da allora ha avuto bisogno solo di piccole correzioni.
Qualcosa che puoi fare questo pomeriggio
Se stai configurando tutto da zero, lo farei nell'ordine opposto rispetto alla maggior parte delle persone.
Prima le barriere: warning come errori, il lint più severo a cui la codebase sopravvive, test su un checkout pulito in CI. Un'ora se il repo ha già un linter e un job di test, gran parte del pomeriggio se non li ha. Il modello ci sbatterà contro cento volte prima di te, ed è quello il punto.
Poi un plugin di processo (superpowers) e il language server per il tuo stack, più un browser se fai lavoro di UI, e nient'altro finché un file di progetto non lo richiede. Dieci minuti.
Poi il file di progetto, solo fatti: cos'è, cosa è fuori scope, i comandi esatti, il vocabolario, e una sezione "things that will bite you" vuota a cui aggiungi nello stesso commit di ogni fix. Un'ora per i fatti; il resto si scrive da solo nelle settimane successive. Aggiungi una regola solo quando il modello sbaglia qualcosa due volte, e per ogni "mai" che scrivi, chiediti cosa lo fa rispettare. Se la risposta è "niente", hai un desiderio.
Poi, ogni tanto, esegui l'audit: chiedi a Claude quali delle sue skill, plugin e server MCP hanno un contatore d'uso a zero, e cancellali. Dieci minuti, e la risposta ti sorprenderà almeno una volta.
Quello che resta è un contratto: corto sulle regole, lungo sui fatti, e modificato ogni volta che il codice ti sorprende.
lucavallin

