@marcomigozzi/trailhead 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.it.md +354 -0
  2. package/README.md +36 -12
  3. package/bin/lib/codex-projection.js +400 -0
  4. package/bin/lib/codex-projection.test.js +252 -0
  5. package/bin/lib/host-descriptor.js +404 -0
  6. package/bin/lib/host-descriptor.test.js +172 -0
  7. package/bin/trailhead.js +454 -66
  8. package/bin/trailhead.test.js +274 -0
  9. package/package.json +1 -1
  10. package/plugins/trailhead/.claude-plugin/plugin.json +1 -1
  11. package/plugins/trailhead/commands/adopt.md +1 -1
  12. package/plugins/trailhead/commands/dashboard.md +6 -0
  13. package/plugins/trailhead/commands/quick.md +6 -0
  14. package/plugins/trailhead/commands/seed.md +1 -1
  15. package/plugins/trailhead/commands/todo.md +1 -1
  16. package/plugins/trailhead/commands/whiteboard.md +6 -0
  17. package/plugins/trailhead/hooks/lib/commit-message-check.js +74 -0
  18. package/plugins/trailhead/hooks/lib/commit-message-check.test.js +83 -0
  19. package/plugins/trailhead/hooks/trailhead-check-update.js +54 -24
  20. package/plugins/trailhead/hooks/trailhead-commit-guard.js +7 -10
  21. package/plugins/trailhead/skills/trailhead/SKILL.md +104 -30
  22. package/plugins/trailhead/skills/trailhead/references/capture.md +6 -0
  23. package/plugins/trailhead/skills/trailhead/references/configuration.md +7 -1
  24. package/plugins/trailhead/skills/trailhead/references/teamwork.md +3 -1
  25. package/plugins/trailhead/skills/trailhead/references/techniques/code-review.md +1 -1
  26. package/plugins/trailhead/skills/trailhead/references/techniques/codebase-map.md +1 -1
  27. package/plugins/trailhead/skills/trailhead/references/techniques/debug.md +2 -0
  28. package/plugins/trailhead/skills/trailhead/references/techniques/plan-review.md +1 -1
  29. package/plugins/trailhead/skills/trailhead/references/techniques/prototype.md +1 -1
  30. package/plugins/trailhead/skills/trailhead/references/techniques/research.md +1 -1
  31. package/plugins/trailhead/templates/statusline-trailhead.sh +40 -8
  32. package/plugins/trailhead/templates/trailhead-commit-msg +57 -0
package/README.it.md ADDED
@@ -0,0 +1,354 @@
1
+ # trailhead
2
+
3
+ 🇬🇧 [English](README.md) · 🇮🇹 **Italiano**
4
+
5
+ **Avvia e conduci grandi progetti come una mappa di ticket su GitHub Issues, risolvendone uno alla volta finché la via verso la destination non è chiara.**
6
+
7
+ `trailhead` è una skill orchestratrice per [Claude Code](https://docs.claude.com/en/docs/claude-code). Dà a un'idea grande e nebbiosa un punto da cui partire (un *trailhead*) e un modo disciplinato per portarla fino a un risultato funzionante, con l'intero piano che vive sul tuo issue tracker invece che in file locali sparsi.
8
+
9
+ ---
10
+
11
+ ## 💡 Perché esiste trailhead
12
+
13
+ Due approcci al lavoro di progetto guidato dagli agenti risolvono ciascuno una metà del problema:
14
+
15
+ - **[Wayfinder](https://github.com/mattpocock/skills)** (di Matt Pocock) è brillante nell'*iniziare*. Trasforma un'idea informe in una **mappa condivisa di decision ticket sul tuo issue tracker**, denominati attraverso una vera conversazione di grilling, con una frontier visibile e una "fog of war" per ciò che non è ancora abbastanza nitido da pianificare. Risolvi una decision per sessione e la mappa cresce verso l'esterno. Ciò che deliberatamente non fa è *costruire*: pianifica, poi passa la mano (handoff).
16
+
17
+ - **GSD** (il workflow system [open-gsd](https://github.com/open-gsd/gsd-core)) è brillante nel *fare*. Il suo ciclo `discuss → plan → execute → verify`, i commit atomici e la cattura senza attrito rendono la costruzione vera e propria affidabile e revisionabile. Ma il suo stato vive in un albero locale `.planning/`, separato da dove il team può vederlo.
18
+
19
+ Lavorando su entrambi, uno schema continuava a ripresentarsi: **usa una mappa e un onboarding in stile Wayfinder per decidere la forma del lavoro, poi un motore in stile GSD per costruire ogni pezzo, senza mai lasciare l'issue tracker.** `trailhead` è quello schema trasformato in un'unica skill, una sua interpretazione autonoma di entrambe le idee anziché un wrapper attorno all'una o all'altra.
20
+
21
+ > **trailhead è self-contained.** Wayfinder e GSD sono *ispirazione*, non dipendenze. Ogni tecnica che quei sistemi impacchettano come skill separata (grilling, TDD, debugging sistematico, codebase mapping, code review) è **integrata qui come protocollo inline**. Il core di trailhead non invoca nessun'altra skill; i suoi subagent (research, codebase-map, review) usano i subagent nativi dell'host (il tool `Agent` integrato di Claude Code, oppure il toolkit `multi_agent` di Codex). L'unica cosa da installare è trailhead stesso. C'è un'unica eccezione opt-in: quando abilitata, la modalità mockup di `claude.ai/design` invia a un progetto design-system tramite DesignSync (l'MCP `claude_design` più la skill `/design-sync`). Se questa non è disponibile, ripiega silenziosamente sui mockup su disco locale.
22
+
23
+ Le scelte di design che ne derivano:
24
+
25
+ - **Tutto vive su GitHub Issues.** La mappa è la parent issue; ogni ticket è una child issue; discussione, piano e verifica sono *commenti*. Non c'è alcuna directory `.planning/`: il repo contiene solo codice, e il piano è sempre visibile a chiunque abbia accesso al repo.
26
+ - **L'esecuzione avviene dentro la mappa.** A differenza del Wayfinder puro ("plan, don't do"), i build ticket si diplomano dalla fog e vengono eseguiti come figli della mappa. La destination è l'**artefatto funzionante** (un'app deployata), non un documento di specifica, anche se un progetto può ridefinire questo e fermarsi alla specifica.
27
+ - **Lean by default.** Il macchinario pesante (codebase mapping, debugging sistematico) gira una volta dove vale la pena; il ciclo per-ticket resta leggero.
28
+
29
+ - **Costruito per i team, perché il piano è condiviso.** Il tracker è l'unica fonte di verità, quindi la mappa è un **workspace condiviso**, non il file locale di una singola persona. Molte persone (e i loro agenti) ci lavorano contemporaneamente, e i meccanismi impediscono che si scontrino:
30
+ - **Claiming.** Prendi un ticket assegnandolo a te stesso; l'assegnatario *è* il lock. Una collisione ti ferma e chiede, invece di sovrascrivere il lavoro di qualcun altro. Chi rivendica un ticket lo possiede dall'inizio alla fine e lo chiude, senza un approvatore separato.
31
+ - **Una frontier condivisa, un ticket per sessione.** La **frontier** (ticket aperti, non assegnati, non bloccati) è la coda comune di ciò che è prendibile ora; ognuno ne sceglie uno diverso. Risolvere un ticket termina la sessione, così il lavoro resta in porzioni revisionabili, un ticket alla volta.
32
+ - **Isolation per sessioni concorrenti su una macchina.** Due agenti che modificano un unico checkout si corrompono a vicenda, quindi la convenzione `isolation:` dà a ogni ticket in corso il proprio **`git worktree`** (o un intero **`clone`** per le app legate a un path che un worktree non riesce a buildare); righe `Scope:` disgiunte lasciano girare in parallelo lavori non sovrapposti e serializzano solo dove c'è vera sovrapposizione.
33
+ - **Pause, resume, split.** Qualsiasi ticket può essere messo in **pause** con un commento di checkpoint e **ripreso** più tardi da chiunque (una volta rilasciato), o **splittato** in figli quando supera la dimensione di una sessione, con i blocker ripuntati così la frontier resta onesta.
34
+ - **Più mappe insieme.** Un repo può portare **più di una mappa attiva** (milestone o feature parallele), ciascuna con la propria frontier con scope, così due persone possono condurre due sforzi sullo stesso repo senza pestarsi i piedi, e puoi parcheggiare una mappa per lavorarne un'altra.
35
+ - **Esterni e fiducia.** Le issue aperte da altre persone passano attraverso una **inbox** che riformula quelle valide in ticket *sul posto* (mantenendo l'autorialità di chi ha segnalato), mentre una guardia di **trust e provenance** mette in quarantena le issue etichettate `trailhead:*` da fonti non fidate finché un maintainer non le adotta, supportata da un workflow di label-guard lato repo.
36
+
37
+ Il protocollo completo vive nella sezione **Lavorare in team** più sotto.
38
+
39
+ ---
40
+
41
+ ## 📦 Install
42
+
43
+ > **Gira su Claude Code e Codex CLI.** trailhead è scritto una volta sola; l'installer proietta artefatti nativi per l'host. Su **Claude Code**: una skill + comandi `/trailhead:*` + hook. Su **Codex CLI**: una skill nativa invocata `$trailhead`, una skill `$trailhead-<verb>` per ogni verbo per la discoverability, e le guardrail come hook nativi di Codex. Scegli l'host con `--claude` / `--codex`, o lascia che l'installer lo rilevi da solo. Altri host possono seguire (l'installer usa un descrittore per-host).
44
+
45
+ **Prerequisiti:** una [`gh` CLI](https://cli.github.com) autenticata (il tracker è GitHub Issues) e un repo GitHub in cui lavorare. Il percorso npm richiede anche Node 18+.
46
+
47
+ ### Come plugin Claude Code (nativo, gestito da `/plugin`)
48
+ ```
49
+ /plugin marketplace add ToRvaLDz/trailhead
50
+ /plugin install trailhead@trailhead
51
+ ```
52
+ Aggiorna con `/plugin update trailhead`; rimuovi con `/plugin uninstall trailhead`.
53
+
54
+ ### Oppure via npm (installa nella config dir del tuo agente)
55
+ ```
56
+ npx @marcomigozzi/trailhead # rileva l'host (default ~/.claude)
57
+ npx @marcomigozzi/trailhead --claude # Claude Code (~/.claude o $CLAUDE_CONFIG_DIR)
58
+ npx @marcomigozzi/trailhead --codex # Codex CLI ($CODEX_HOME o ~/.codex)
59
+ npx @marcomigozzi/trailhead --symlink # dev install (Claude; symlink al checkout, le modifiche sono live)
60
+ npx @marcomigozzi/trailhead --uninstall # rimuove tutto ciò che ha aggiunto (abbinalo a --claude / --codex)
61
+ npx @marcomigozzi/trailhead --dir=<path> # punta a una config dir specifica
62
+ ```
63
+ Su **Claude Code** copia la skill (+ le sue `references/`), i comandi `/trailhead:*`, gli hook (in `hooks/`, registrati in `settings.json`) incluso un **update check** al SessionStart, e i template di label-guard + statusline, in modo idempotente.
64
+
65
+ Su **Codex CLI** (`--codex`) proietta una skill nativa Codex invocata come **`$trailhead`** (`$trailhead work`, `$trailhead new "idea"`, …), una skill sottile **`$trailhead-<verb>`** per ogni verbo per la discoverability, le quattro guardrail come **hook** nativi di Codex (`~/.codex/hooks.json`, abilitando `features.hooks`), e i pin di modello per-tecnica da **`models.codex.*`** in `~/.codex/agents/`. Serve Codex **0.145.0+** (l'installer fa un gate su `codex --version`). La modalità mockup `claude.ai/design` non è disponibile su Codex, quindi lì i mockup UI ripiegano sul disco locale.
66
+
67
+ Ri-esegui l'install per aggiornare, oppure esegui **`/trailhead:update`** (Claude) / **`$trailhead update`** (Codex) da dentro l'agente: rileva come trailhead è stato installato e installa la versione più recente dove è sicuro farlo (un `git pull` per un dev-symlink, una ri-esecuzione `npx` per npm, o `/plugin update` per il plugin). Quando esiste una versione più recente, la statusline mostra un flag `⬆ trailhead <version>` (Claude).
68
+
69
+ ### Dopo l'installazione
70
+ Riavvia o ricarica il tuo agente così i comandi si registrano, poi esegui **`/trailhead`** per iniziare (smart entry), o `/trailhead:new "<idea>"` per tracciare una mappa. **Su Codex** la superficie è `$trailhead`: esegui **`$trailhead`** per lo smart entry, `$trailhead new "<idea>"` per tracciare, o una skill per-verbo `$trailhead-<verb>`. Nota: una volta installato, l'**hook di commit guard gira a ogni `git commit`** (imponendo i Conventional Commits e bloccando `Co-Authored-By`); disabilita gli hook del plugin nelle impostazioni se non lo vuoi. In ogni caso trailhead è self-contained: nessun'altra skill o plugin è richiesta, niente preflight, niente version drift.
71
+
72
+ ---
73
+
74
+ ## 🗺️ Come funziona
75
+
76
+ Una **map** è una singola issue GitHub etichettata `trailhead:map`. È un indice, non un archivio: una Destination, delle Notes permanenti, i `Decisions so far`, la fog `Not yet specified`, e ciò che è `Out of scope`.
77
+
78
+ **Cosa merita una mappa?** Una mappa è l'unità per uno sforzo che è **troppo grande da tenere in una sola sessione** e porta con sé **decisioni aperte**, non solo esecuzione. In pratica è una **milestone** (una release, una versione, "v2 della dashboard"), o una **singola feature abbastanza grande da dover decidere prima di poter costruire**: dove vivono i dati, quale libreria, cosa fa davvero la schermata. Tracciare una mappa dà un nome alla sua destination e dirama quello sforzo in molti ticket, cablati dalle loro dipendenze. Man mano che le decisioni si risolvono, la fog si dirada e i build ticket si diplomano, finché la destination non è raggiunta.
79
+
80
+ Ciò che **non** ha bisogno di una propria mappa è un singolo pezzo di lavoro definito senza domande aperte, abbastanza piccolo da finire in una sessione. Quello è semplicemente **un ticket**, un `build` diretto (o un `todo`): un *work* che prendi con `/trailhead:work` e risolvi in una seduta, senza bisogno di tracciare. **Regola pratica: decisioni da prendere, o troppo grande per una seduta → una mappa; "fai solo X" → un singolo work.** Una feature che nasce come un work isolato ma si scopre aver bisogno di decisioni viene promossa a una propria mappa (o splittata); una mappa le cui domande evaporano tutte collassa di nuovo in una manciata di work. E un repo può contenere **più mappe insieme** (milestone o feature parallele), ciascuna con la propria frontier, così puoi parcheggiarne una e lavorarne un'altra.
81
+
82
+ Ogni **ticket** è una child issue con una label di tipo e un corpo di una sola domanda. La **frontier** è l'insieme dei ticket aperti, non assegnati, i cui blocker sono tutti chiusi: ciò che è prendibile proprio ora. Rivendichi un ticket assegnandolo a te stesso, lo risolvi con il motore per il suo tipo, poi registri la risposta come commento, lo chiudi, e ne fai il gist di nuovo sulla mappa.
83
+
84
+ Man mano che i ticket si risolvono, la fog si dirada: domande che erano troppo vaghe da formulare diventano abbastanza nitide da diventare ticket, una alla volta, finché non resta nulla da decidere o costruire e la destination è raggiunta.
85
+
86
+ Una mappa ha come scope **un** solo sforzo, quindi la conoscenza che appartiene al *repo* (non a una singola mappa) vive in **anchor issue con scope di repo**, create una volta e condivise da ogni mappa (le Notes di ciascuna mappa le collegano soltanto, così nulla resta orfano quando una mappa finisce):
87
+
88
+ - **`trailhead:codebase`**: la codebase map distillata (architettura, stack, convenzioni, rischi, test/build), scritta una volta all'adopt e aggiornata solo su drift importanti.
89
+ - **`trailhead:conventions`**: il **modo di lavorare** del progetto, leggibile da tutti: un piccolo header machine-read che il motore obbedisce (`git: main|pr`, `release: command|auto`, `isolation: none|worktree|clone`) sopra la prosa umana. `/trailhead:adopt` e `:new` lo chiedono all'inizio. `isolation: worktree` dà a ogni ticket in esecuzione il proprio `git worktree` + branch (le sessioni concorrenti su un clone non condividono mai un working tree); `isolation: clone` gli dà invece un clone dedicato, per le app legate a un path che un worktree non riesce a buildare.
90
+ - **`trailhead:dashboard`**: l'indice pinnato dell'intera superficie, un link a ogni mappa aperta (con le progress bar native di GitHub), la whiteboard, e conteggi live (inbox, frontier della whiteboard). Aggiornato quando una mappa viene tracciata o esaurita, quando un ticket della whiteboard nasce o si risolve (non ha una progress bar nativa, quindi la dashboard è l'unico posto in cui appare), e su richiesta via `/trailhead:dashboard`.
91
+
92
+ Questi tre riempiono i **3 slot di issue pinnate** di GitHub, così gli anchor di trailhead di un repo restano a un click di distanza; **le mappe stesse non vengono mai pinnate** (sono indicizzate dalla dashboard, dato che la mappa "attiva" è stato locale per-checkout, non un fatto globale del repo). La *config* del progetto (models, TDD, design…) è ancora una cosa separata, un semplice file `.trailhead/config.json` alla radice del repo, mai in una issue.
93
+
94
+ ---
95
+
96
+ ## 🔄 Workflow
97
+
98
+ **Il ciclo di vita.** Ogni progetto percorre lo stesso loop:
99
+
100
+ 1. **Start**: `/trailhead:new "<idea>"` (greenfield) o `/trailhead:adopt` (codice esistente: mappa la codebase una volta, poi vai lean). Questo *traccia la mappa*: dai un nome alla destination, poi mappa la frontier in ampiezza (breadth-first) nei primi ticket e nella fog.
101
+ 2. **Lavora la frontier, un ticket per sessione**: `/trailhead:work` prende il prossimo ticket prendibile (o quello che nomini) ed esegue il motore per il suo tipo: `research` raccoglie un fatto · `decision` dirama le opzioni poi fa grilling per scegliere · `prototype` crea un artefatto grezzo a cui reagire · `build` esegue discuss → plan → execute → verify · `bug` esegue repro → diagnose → fix → verify · `task` è plumbing manuale che sblocca una decision.
102
+ 3. **Chiudi e sblocca**: risolvi il ticket (commento + chiusura), fanne il gist in `Decisions so far`, e rimuovi `trailhead:blocked` da ogni dipendente il cui ultimo blocker si è appena chiuso, diplomandolo sulla frontier.
103
+ 4. **Ripeti** finché la frontier è vuota e la fog si è diradata: la destination (un artefatto funzionante) è raggiunta.
104
+
105
+ Lungo il cammino: **cattura** idee in corso d'opera senza deragliare, **splitta** un ticket cresciuto troppo, **pause/resume** tra le sessioni, e lascia che più persone lavorino in parallelo i ticket sbloccati.
106
+
107
+ ### Un esempio pratico: "add social login"
108
+
109
+ Destination: *gli utenti accedono con Google e GitHub, accanto a email/password.* Il charting la dirama in sei ticket (uno per ogni tipo) cablati dalle loro dipendenze:
110
+
111
+ ```
112
+ ① research "OAuth providers + library: Supabase Auth native or Auth.js?" ← frontier (AFK)
113
+ ② decision "approach: Supabase Auth native vs Auth.js custom" ← blocked by ①
114
+ ③ task "register OAuth apps on Google + GitHub, get client id/secret" ← frontier (HITL)
115
+ ④ prototype "how the login screen with social buttons looks" ← frontier (HITL)
116
+ ⑤ build "implement Google + GitHub login" ← blocked by ②③④
117
+ ⑥ bug (appears after ⑤ ships)
118
+ ```
119
+
120
+ Frontier iniziale = ①③④, tre persone possono partire in parallelo. Poi:
121
+
122
+ - **① research** → un subagent legge la documentazione, restituisce un finding pronto per la decisione, chiude → sblocca ②.
123
+ - **② decision** → dirama le opzioni, grill per scegliere native vs custom, registra il perché.
124
+ - **③ task** → l'agente ti consegna una checklist (servono i *tuoi* account Google/GitHub); tu registri le app, lui registra dove vivono le credenziali.
125
+ - **④ prototype** → una schermata di login grezza (sul progetto claude.ai/design configurato), approvata prima del codice UI.
126
+ - Con ②③④ chiusi, **⑤ build** si diploma → discuss → plan → execute (commit atomici, TDD ai seam dell'auth) → verify (test + code review + acceptance: l'agente guida il browser attraverso il vero flusso di login).
127
+ - Dopo il rilascio noti un redirect sbagliato in prod → `/trailhead:bug --of ⑤ "GitHub redirect goes to localhost"` → un nuovo ticket che porta `Regression of: ⑤`, lavorato repro → diagnose → fix → verify. ⑤ resta chiuso.
128
+
129
+ ```
130
+ ① research ─┐
131
+ ③ task ─────┼─► ② decision ─┐
132
+ ④ prototype ┘ ├─► ⑤ build ──(ship)──► ⑥ bug (Regression of: ⑤)
133
+ ③ task ──────────────────────┘
134
+ ```
135
+
136
+ I tipi preparatori (`research`/`decision`/`prototype`/`task`) sbloccano quelli costruttivi (`build`/`bug`); il parallelismo è reale ma tra sessioni sulla frontier, non dentro una sola.
137
+
138
+ ### …poi arriva un suggerimento: inbox → fog → graduation
139
+
140
+ L'app è live, e un utente *non del team* apre una issue normale: *"can we add Apple sign-in too?"* Nessuna label `trailhead:*`, quindi non è ancora un ticket. Ecco come una voce esterna diventa un ticket di prima classe sulla mappa, senza perdere l'autorialità di chi ha segnalato:
141
+
142
+ 1. **Inbox**: `/trailhead:inbox` la elenca sotto *New: to triage*. È in scope ma non nitida: solo web o nativo? serve l'account Apple Developer a pagamento? Non puoi ancora formulare una singola Question a cui si possa rispondere, quindi non forzi un ticket.
143
+ 2. **Fog**: etichettala `trailhead:fog` e **tieni la issue aperta come spazio di chiarimento**. Un commento pubblica le domande di affinamento (grilling asincrono); chi ha segnalato e chiunque interessato la affinano nel thread. È fuori dalla frontier ma tracciata: `gh issue list --label trailhead:fog` è la lista durevole, e chi ha segnalato segue la propria issue.
144
+ 3. **Graduation**: la discussione converge. La prossima volta che esegui `/trailhead:inbox`, la sua sezione *Parked fog* fa emergere il thread come recentemente-attivo: è così che noti che la fog si è diradata. Ora la Question è formulabile, quindi la **adotti sul posto**: sostituisci `trailhead:fog` con `trailhead:ticket` + una label di tipo, aggiungi la riga `Parent:` e la `## Question`. Stesso numero di issue, stesso reporter accreditato, atterra sulla frontier, pronta per `/trailhead:work`.
145
+
146
+ ```
147
+ suggestion issue ──inbox──► 🌫️ fog (kept open, discussed) ──sharpens──► 🎫 ticket on the frontier
148
+ (same #, reporter still credited)
149
+ ```
150
+
151
+ Nessun backlog separato, nessun credito perso: la mappa assorbe i suggerimenti esterni allo stesso modo in cui fa crescere i propri, attraverso una fog che si diploma quando è nitida.
152
+
153
+ ---
154
+
155
+ ## ⌨️ Commands
156
+
157
+ `trailhead` è invocato dall'utente (non si attiva da solo). La **prima parola** è il verbo; il resto è testo o un numero di ticket. Senza verbo, `/trailhead` fa **smart entry**: ispeziona il repo e propone la mossa giusta successiva.
158
+
159
+ Ogni verbo è anche un comando con namespace (`/trailhead:new`, `/trailhead:work`, `/trailhead:bug`, …) così digitando `/trailhead` li elenca tutti nel command picker. `/trailhead <verb>` e `/trailhead:<verb>` sono equivalenti.
160
+
161
+ ### Flow
162
+
163
+ | Command | Cosa fa |
164
+ |---|---|
165
+ | `/trailhead` | smart entry: rileva lo stato e propone |
166
+ | `/trailhead:new [idea]` | traccia una nuova mappa da un'idea informe |
167
+ | `/trailhead:adopt` | adotta un progetto esistente (mappa la codebase una volta, poi vai lean) |
168
+ | `/trailhead:work [ticket]` | lavora il prossimo ticket della frontier, o quello che nomini |
169
+ | `/trailhead:quick [ticket \| "text"]` | lavora un ticket per intero, fuori dalla mappa: apre un ticket della whiteboard da `"text"` (o prende `<n>`), esegue il motore completo, fa grilling solo se serve, non splitta mai |
170
+ | `/trailhead:whiteboard` | mostra la whiteboard: i ticket sciolti (senza mappa) e la loro frontier |
171
+ | `/trailhead:inbox [issue]` | fa il triage delle issue aperte da altri e integra quelle buone nella mappa |
172
+ | `/trailhead:resume [ticket]` | riprende un ticket in pausa dal suo checkpoint `PAUSED` |
173
+ | `/trailhead:pause [note]` | mette un checkpoint sul ticket in gioco così chiunque può riprenderlo |
174
+ | `/trailhead:ticket <type> <title>` | apre un ticket al volo (diverge brevemente prima: un atto di micro-charting) |
175
+ | `/trailhead:split [ticket]` | splitta un ticket sovradimensionato in figli, supersede l'originale |
176
+ | `/trailhead:grill [topic]` | esegue una sessione di grilling autonoma su una decision/topic |
177
+ | `/trailhead:map` | mostra la mappa a bassa risoluzione (destination, decisions, frontier, fog) |
178
+ | `/trailhead:dashboard` | mostra la dashboard del repo: l'indice pinnato di ogni mappa aperta, la whiteboard, e i conteggi live |
179
+
180
+ ### Capture: zero attrito, una riga di conferma, non risolve nulla
181
+
182
+ | Command | Atterra come | Significato |
183
+ |---|---|---|
184
+ | `/trailhead:todo <text>` | un ticket sulla frontier | *lo sto facendo*: lavoro definito, ora |
185
+ | `/trailhead:seed <text>` | un ticket bloccato (trigger annotato) | *lo farò quando X accade* |
186
+ | `/trailhead:idea <text>` | la fog (`Not yet specified`) | *forse lo farò*: si diploma a ticket se si affina |
187
+ | `/trailhead:note <text>` | testo verbatim | *ricorda questo*: non necessariamente lavoro |
188
+ | `/trailhead:bug [--of <ticket>] <text>` | un ticket `bug` | un difetto; `--of` lo registra come `Regression of:` di un ticket chiuso |
189
+
190
+ Le quattro capture fog/ticket formano uno spettro di impegno e tempistica: **note < idea < seed < todo**.
191
+
192
+ Quando una mappa è aperta, una capture che produce un ticket (`todo`/`bug`/`seed`/un `idea` nitido) chiede se depositarlo sulla **mappa attiva** o sulla **whiteboard**, la casa per il lavoro sciolto, senza mappa, che non appartiene a nessuna mappa (o non vale la pena tracciarne una). Senza mappa aperta atterra sulla whiteboard. Lavora un ticket della whiteboard con **`/trailhead:quick`** (che ne apre anche uno da `"text"` e lo lavora nella stessa seduta), e vedili tutti con `/trailhead:whiteboard`.
193
+
194
+ ### 🧯 Non restare intrappolato in una mappa: la whiteboard
195
+
196
+ In profondità dentro una mappa, emerge qualcosa di non correlato: un bug in un'altra area, una faccenda, un'idea veloce su cui vuoi agire adesso. Forzarla sulla frontier della mappa inquina la mappa; tracciare un'intera nuova mappa per essa è eccessivo. È a questo che serve la **whiteboard**, il lavoro sciolto senza mappa, e due mosse ti impediscono di restare bloccato:
197
+
198
+ - **Mettila da parte.** Un `todo`/`bug`/`seed`/`idea` nitido lanciato mentre una mappa è aperta chiede *mappa o whiteboard?*. Mandala alla whiteboard e resta fuori dalla mappa: tracciata, ma fuori dai piedi, così la frontier della mappa continua a significare "la via verso questa destination".
199
+ - **Fallo al volo.** `/trailhead:quick "<text>"` apre un ticket della whiteboard e lo lavora dall'inizio alla fine nella stessa seduta, il motore completo discuss → plan → execute → verify (commit atomici, code review, tutto quanto), tranne che **fa grilling solo se serve e non splitta mai**, e salta ogni passo di book-keeping della mappa. `/trailhead:quick <n>` fa lo stesso per un ticket che esiste già.
200
+
201
+ Vedi l'intera whiteboard con `/trailhead:whiteboard`. Niente cambia riguardo alla mappa: ne sei semplicemente sceso, hai fatto la cosa, e ci risali quando sei pronto.
202
+
203
+ I tre che mandano le persone in confusione sono **idea, seed, todo**, quindi eccoli esplicitati:
204
+
205
+ - **`idea`** = *forse, e non ancora chiaro.* Atterra nella **fog** (`Not yet specified`), **non** come ticket, perché non puoi nemmeno formulare la domanda in modo nitido ancora, quindi non c'è nulla da lavorare. Si **diploma** in un ticket più tardi, quando la frontier la raggiunge o semplicemente diventa più chiara.
206
+ - **`seed`** = *sì, ma non ancora.* È **un** ticket, ma **parcheggiato** (`trailhead:blocked`) su un **trigger** che nomini ("when the public API ships", "when we pass 1k users"). La domanda è già nitida; ciò che manca è una **condizione**, non la chiarezza. Quando il trigger scatta, si diploma sulla frontier.
207
+ - **`todo`** = *sì, ora.* Lavoro definito che farai e basta: nasce come **`build` ticket sulla frontier**, prendibile immediatamente.
208
+
209
+ I due tagli che contano: **idea vs seed** è aspettare la *chiarezza* vs aspettare una *condizione* (entrambi atterrano "dopo", per ragioni diverse); **seed vs todo** è impegnato *dopo* vs impegnato *ora*. Sotto tutti e tre sta **`note`** (testo grezzo da ricordare, forse mai lavoro), e di lato c'è **`bug`** (un difetto, non un livello di impegno). Il test per idea vs ticket è sempre: **puoi formulare la domanda con precisione ora?** Sì → un ticket (`todo` se prendibile, `seed` se gated); no → la fog (`idea`).
210
+
211
+ ---
212
+
213
+ ## 🎫 Tipi di ticket e i loro motori
214
+
215
+ Ogni ticket porta una label di tipo; ogni tipo ha il proprio modo di essere risolto.
216
+
217
+ Ogni tipo ha il proprio motore inline: nessuna skill esterna viene invocata.
218
+
219
+ | Type | Produce | Mode | Engine |
220
+ |---|---|---|---|
221
+ | 🧭 `decision` | una scelta | HITL | diverge le opzioni se non chiare, poi grill per convergere su una |
222
+ | 🔬 `research` | un fatto | AFK | un subagent su un branch usa-e-getta (l'unico tipo eseguito in parallelo) |
223
+ | 🎨 `prototype` | una direzione approvata | HITL | un artefatto grezzo usa-e-getta a cui reagire; le schermate UI passano da qui (disco, o un progetto claude.ai/design configurato) prima del codice UI |
224
+ | 🔨 `build` | codice funzionante | HITL/AFK | `discuss → plan → execute → verify`: commit atomici, TDD ai seam, **prima un mockup per la UI rivolta all'utente** (tecnica Prototype, gated da `design.approval`), code review + acceptance testing (browser-drive o UAT conversazionale passo-passo) |
225
+ | 🐛 `bug` | codice corretto | HITL/AFK | `repro → diagnose → fix → verify`; un difetto in lavoro chiuso è un ticket *nuovo* (`Regression of:`), non una riapertura |
226
+ | 🔧 `task` | un cambiamento di stato esterno | HITL/AFK | lavoro manuale che sblocca una decision (provisioning accessi, spostamento dati, iscrizioni) |
227
+
228
+ Due regole pratiche: i build ticket **non fanno mai auto-grill**: su un'ambiguità bloccante la skill si ferma e chiede; e il brainstorming (divergenza) vive nel charting, nel micro-charting di `ticket`, e nella fase di opzioni di una `decision`, mai nel grilling stesso, che converge soltanto.
229
+
230
+ ---
231
+
232
+ ## 🏷️ Labels
233
+
234
+ Tutto ciò di cui la mappa ha bisogno è espresso come label GitHub, così lo stato è interrogabile nella UI del tracker:
235
+
236
+ - **Strutturali:** `trailhead:map`, `trailhead:ticket`
237
+ - **Anchor con scope di repo (uno ciascuno per repo, pinnati):** `trailhead:codebase` 🧱 (la codebase map distillata), `trailhead:conventions` 📜 (il modo di lavorare), `trailhead:dashboard` 📊 (l'indice pinnato di mappe + whiteboard + conteggi) — ogni titolo porta la sua icona (come il 🗺 della mappa) così gli anchor pinnati si distinguono a colpo d'occhio
238
+ - **Type (una per ticket):** 🧭 `trailhead:decision` · 🔬 `research` · 🎨 `prototype` · 🔨 `build` · 🐛 `bug` · 🔧 `task`
239
+ - **State:** `trailhead:blocked` (ha un blocker aperto) · `seed` (parcheggiato su un trigger) · `out-of-scope` (chiuso, oltre la destination) · `superseded` (chiuso, splittato in figli)
240
+ - **Container:** `trailhead:whiteboard` (un ticket sciolto, senza mappa, fuori dalla frontier di ogni mappa, sulla frontier propria della whiteboard)
241
+
242
+ La **frontier** è quindi una singola query (aperto, non assegnato, non `trailhead:blocked`), senza bisogno di parsare il corpo.
243
+
244
+ ## 👥 Lavorare in team
245
+
246
+ Molte persone (e le loro sessioni di agente) condividono una mappa e la lavorano in concorrenza:
247
+
248
+ - **Claim = assegnare a te stesso.** Chi rivendica possiede il ticket dall'inizio alla fine e lo chiude: non c'è approvatore e nessuno da attendere. Su una collisione di claim la sessione si ferma e chiede a te, invece di risolverla silenziosamente.
249
+ - **Split** un ticket sovradimensionato in figli e supersede l'originale (`/trailhead:split`).
250
+ - **Pause/resume** tramite un commento di checkpoint `PAUSED`, così qualsiasi sessione può riprendere un ticket.
251
+ - **Isola le sessioni concorrenti con i worktree.** Il claiming tiene due sessioni fuori dallo *stesso* ticket, ma due sessioni su ticket *diversi* nello *stesso* clone condividono comunque un working tree. Imposta `isolation: worktree` nell'header delle conventions e ogni ticket in esecuzione gira nel proprio `git worktree` su un branch `trailhead/t<n>`, integrato di nuovo nel trunk al Resolve. Implica un branch per ticket anche sotto `git: main` (git non farà il checkout del trunk due volte), ed è la postura giusta per un **monorepo** (un worktree condivide l'object store, molto più economico di un secondo clone). Un'avvertenza: un worktree isola il *source* ma è un path nuovo senza dipendenze installate, quindi un **package legato a un path** (React Native/Expo, toolchain native, qualsiasi cosa legata a un `node_modules` locale) non buildera da lì. Per questi c'è **`isolation: clone`**: un clone dedicato per-ticket che installa le proprie dipendenze e builda/UATa come l'app vera (più pesante di un worktree, e lo strumento giusto per un submodule Expo/RN). Oppure tieni `isolation: none` e serializza. Altrimenti esegui le sessioni concorrenti in clone separati.
252
+ - **Un marker session-ticket per la tua statusline.** Quando inizia a lavorare un ticket, trailhead deposita una riga singola, gitignorata, `.trailhead/session-ticket` (`#<n> <title>`) alla radice di lavoro e la pulisce all'handoff. È puramente un hint economico e offline così una statusline (o qualsiasi tool) può mostrare *su quale ticket è questa sessione* senza colpire il tracker; trailhead stesso continua a trattare le Issue come fonte di verità.
253
+ - **Ti dà una spinta quando l'isolation non è mai stata scelta.** Se un repo è stato tracciato o adottato prima che impostassi una modalità `isolation:` (quindi assume silenziosamente `none`), la prima volta che vai a lavorare un ticket con un vero rischio di collisione (un altro ticket in corso, o tooling legato a un path nel suo `Scope:`) trailhead fa emergere un suggerimento di una riga della modalità adatta (`worktree` o `clone`) invece di modificare silenziosamente il checkout condiviso. Qualunque cosa decidi, incluso tenere `none`, scrive la chiave `isolation:` nelle conventions così la scelta è registrata e non chiede mai più. Un header che ha già impostato `isolation:` viene lasciato in pace.
254
+ - **Dai scope ai ticket per path su un monorepo.** Un ticket può portare una riga `Scope:` che nomina il/i package/dir che tocca: scope disgiunti parallelizzano in sicurezza, e dà scope a build/test e ai commit del worktree limitandoli al package interessato. `/trailhead:adopt` rileva un monorepo e propone sia `isolation: worktree` sia la convenzione `Scope:`. Sotto `isolation: none`, `Scope:` **serializza** anche un'area condivisa: al momento del claim una sessione si trattiene se lo scope di un altro ticket in corso si sovrappone, così due ticket con scope sullo stesso submodule/package non possono girare insieme (è così che tieni due sessioni fuori da un'app legata a un path).
255
+ - **I git submodule sono gestiti come repo separati.** Il lavoro che atterra dentro un submodule viene committato *dentro il submodule* più un bump del gitlink nel parent, e (sotto `worktree`) isolato a livello di submodule, non del superproject. Un ticket che copre due submodule resta atomico tramite un singolo commit del parent che bumpa entrambi i gitlink insieme; il suo `Scope:` li nomina entrambi. `/trailhead:adopt` rileva `.gitmodules` e scrive la regola nelle conventions.
256
+ - **Lo stato vive sui ticket** (claim, label, commenti; tutti conflict-free); il corpo della mappa è un indice ri-leggibile, non la fonte di verità. Il record durevole di una risoluzione è il commento del ticket stesso.
257
+ - **Le label sono protette dagli esterni.** Le label `trailhead:*` guidano la mappa, quindi trailhead si fida di una issue etichettata solo quando un collaboratore con accesso in scrittura ha applicato la label e (per un ticket) porta un `Parent:` valido. Qualsiasi altra cosa è messa in quarantena come `trailhead:unverified`, fuori dalla frontier. GitHub già blocca gli utenti senza accesso in scrittura dall'applicare label; contro gli utenti di triage e le automazioni, trailhead può **installare per te la GitHub Action di label guard** (da `templates/trailhead-label-guard.yml`) nella `.github/workflows/` del tuo repo, dove rimuove alla fonte le label `trailhead:*` non autorizzate. Installare un workflow richiede un token con lo scope `workflow`, quindi trailhead esegue `gh auth refresh -s workflow` se il push viene rifiutato.
258
+ - **Le issue aperte da altri vengono triage-ate, non fidate alla cieca.** `/trailhead:inbox` elenca le issue in ingresso (bug report, richieste, domande che non sono ancora trailhead ticket) e integra quelle valide **sul posto**: riformulandole come ticket, mantenendo l'autorialità di chi ha segnalato, e applicando le label all'adozione. Il resto viene instradato a fog, out-of-scope, duplicato, o needs-info.
259
+
260
+ ## ✅ Tenere i ticket onesti
261
+
262
+ Un ticket è una singola Question a cui si può rispondere, dimensionata a una sessione, così non lo fai mai crescere in corsa. Quando nuovo scope emerge mentre lavori (i test soprattutto scatenano idee), decidi caso per caso: piccolo e parte della stessa Question → fallo e basta; gonfia il ticket oltre una sessione → **splittalo**; lavoro separato o un follow-up → **catturalo** (`idea`/`todo`/`ticket`/`bug`) e continua. Gli extra non diventano mai righe silenziose dentro il ticket su cui sei.
263
+
264
+ I ticket che nascono da altro lavoro portano un puntatore di lignaggio nel loro corpo, così la mappa resta tracciabile:
265
+
266
+ | Pointer | Significato |
267
+ |---|---|
268
+ | `Split from:` | figlio di un ticket che è stato splittato |
269
+ | `Regression of:` | un bug nel lavoro di un ticket chiuso |
270
+ | `Surfaced from:` | un'idea/ticket emersa mentre si lavorava un altro ticket |
271
+
272
+ ---
273
+
274
+ ## ⚙️ Configuration
275
+
276
+ Tre layer: **il più vicino vince**, chiave per chiave (una chiave non impostata a un layer eredita il successivo):
277
+
278
+ - **Project**: un file `.trailhead/config.json` alla radice del repo: override per questo progetto, committato così un team condivide una config. La config vive in un file semplice, **mai nella issue della mappa**; è tua da cambiare in qualsiasi momento.
279
+ - **Global**: `~/.claude/trailhead/config.json`: i tuoi default permanenti su ogni progetto.
280
+ - **Defaults**: i valori integrati.
281
+
282
+ `/trailhead:config` esegue un **setup guidato, a menu**: scegli lo scope, poi percorri ogni impostazione (🌐 ticket language · 🧠 models · 🎨 design + approval · 🧪 TDD · 🖥️ acceptance testing · 🧑‍⚖️ plan review · 📊 statusline) come un menu con icone; niente editing manuale del JSON. Ogni passo è chiesto (nessuno saltato), e i **modelli plan ed execute sono sempre due scelte separate e version-pinned**. `config get` stampa la config effettiva unita; `config set <key> <value>` scrive una chiave.
283
+
284
+ Il passo **📊 statusline** offre di installare la status bar di trailhead per Claude Code: una riga con **model · project · branch · plan usage (`5h %` · reset · `7d %`) · una barra della context-window**, più una **seconda riga con il ticket attivo** (`▸ #N Title`) ogni volta che ne stai lavorando uno, e un flag `⬆ trailhead <version>` quando è disponibile un trailhead più recente (esegui `/trailhead:update`). Il project è sempre il nome del repo principale anche da un checkout isolato, e il branch porta un tag `(WT)` in un worktree o `(C)` in un clone per-ticket (niente sul checkout originale). È un'impostazione globale di Claude Code; se già usi una statusline (es. `ccstatusline`) il setup chiede prima di rimpiazzarla, e lo script espone anche i segmenti `--ticket-only` / `--context-only` / `--usage-only` da inserire in un tool esistente.
285
+
286
+ **Offerta al primo uso (una volta per progetto).** Non devi andarla a cercare: la prima volta che configuri un progetto (alla fine di `/trailhead:new`/`:adopt`, o su un `/trailhead` nudo quando esiste una mappa ma non una config) trailhead offre di eseguire il setup guidato, o di continuare sui default. Chiede **solo una volta**: configurare scrive `.trailhead/config.json`, e "continua sui default" scrive un `{}` vuoto. Una volta che quel file esiste non viene più offerto, e non interrompe mai a metà ticket.
287
+
288
+ | Key | Values (default **bold**) | Effetto |
289
+ |---|---|---|
290
+ | `ticket.language` | un codice ISO 639-1 (**`en`**) | la lingua in cui trailhead **scrive** la sua prosa GitHub e le descrizioni dei commit, disaccoppiata dalla lingua in cui conversa |
291
+ | `models.{plan,execute,research,review,debug}` | un id modello completo **versionato** (**inherit session**) | quale modello esegue ogni attività; `plan` ed `execute` sono sempre impostati separatamente |
292
+ | `design` | **`disk`** \| `claude.ai/design` | dove vanno i mockup UI: HTML usa-e-getta locale, o un progetto design-system su claude.ai/design via DesignSync |
293
+ | `design.approval` | **`explicit`** \| `auto` | attendi l'approvazione del mockup prima del codice UI, o procedi senza bloccare |
294
+ | `tdd` | **`seams`** \| `on` \| `off` | come il motore `build` testa |
295
+ | `acceptance.browser` | **`auto`** \| `on` \| `off` | guida il browser in Verify, o ti accompagna in una UAT conversazionale (passo-passo in chat, non una checklist da fare da solo) |
296
+ | `testing.webapp` / `testing.url` | bool / URL | è browser-drivabile, e dove |
297
+ | `plan_review` | **`off`** \| `on` \| CLI list | invia i PLAN di `build` ad AI CLI esterne (Gemini, Codex, …) per un secondo parere e converge sulle loro obiezioni |
298
+ | `plan_review.rounds` | integer (**`2`**) | numero massimo di round converge-and-re-review |
299
+
300
+ **Models.** Ogni chiave esegue la sua attività come **subagent** sul modello che nomini, così l'intera suddivisione per-attività si applica dentro una singola sessione di lavoro, qualunque modello quella sessione esegua:
301
+
302
+ - `plan` ed `execute` sono i passi del motore build/bug. Execute è anch'esso un subagent, e committa su `main`.
303
+ - `research`, `review`, `debug`, e il fan-out della codebase-map girano ciascuno sulla propria chiave.
304
+
305
+ Scegli `plan` ed `execute` separatamente, ciascuno per **id completo versionato** (mai un `opus` o `sonnet` nudo). Una chiave non impostata, o uguale al modello della sessione, gira semplicemente inline.
306
+
307
+ La **sessione principale resta l'orchestratore**. Tiene i momenti interattivi (il Discuss di un build, e l'acceptance/UAT del Verify) e fa charting, grilling e scrittura dei ticket sul proprio modello. Nessuna chiave governa la qualità dei ticket, quindi esegui le sessioni di charting sul tuo modello forte.
308
+
309
+ Esempio di file di config (la stessa forma funziona per il `.trailhead/config.json` di progetto e il `~/.claude/trailhead/config.json` globale):
310
+
311
+ ```json
312
+ { "ticket": { "language": "en" }, "models": { "plan": "claude-opus-4-8", "execute": "claude-sonnet-5" }, "tdd": "seams", "acceptance": { "browser": "auto" } }
313
+ ```
314
+
315
+ **Design mockups.** `design: disk` (il default) deposita un mockup HTML statico usa-e-getta accanto al codice e lo collega dal ticket. `design: claude.ai/design` invece invia il mockup a un **progetto design-system** su claude.ai/design via **DesignSync** (la skill `/design-sync` più l'MCP `claude_design`), dove lo affini visivamente.
316
+
317
+ Alla prima schermata UI, trailhead chiede quale design system usare. Puoi:
318
+
319
+ - **scegliere tra i tuoi 10 più recenti**,
320
+ - **incollare un URL `claude.ai/design/p/<id>`**, oppure
321
+ - **crearne uno nuovo** (ti chiede il nome).
322
+
323
+ Fa il caching dell'id scelto in `design.project`. Ogni schermata viene inviata lì, e la sua URL è collegata dal ticket. Una volta che approvi, trailhead **ri-fetcha** il design corrente (nel caso tu l'abbia modificato live) prima di scrivere qualsiasi codice UI.
324
+
325
+ DesignSync guida solo i progetti design-system, non quelli normali; per un progetto normale posizioni il mockup a mano. `design.approval` decide se il build attende il tuo esplicito via libera (`explicit`), o procede subito dopo aver mostrato il mockup (`auto`).
326
+
327
+ ---
328
+
329
+ ## 🪝 Hooks
330
+
331
+ Oltre alle istruzioni della skill, trailhead include tre hook propri (in `hooks/`, self-contained via `${CLAUDE_PLUGIN_ROOT}`) che *impongono* le parti della disciplina che non ci si dovrebbe fidare che il modello ricordi:
332
+
333
+ - **Commit guard** (`PreToolUse` su `git commit`): blocca in modo netto un commit il cui subject non è [Conventional Commits](https://www.conventionalcommits.org), e blocca in modo netto qualsiasi trailer `Co-Authored-By`. Questo rispecchia la validazione dei commit di GSD.
334
+ - **Secret guard** (`PreToolUse` sulle scritture `gh` di issue/PR): trailhead pubblica molto sul tracker (corpi dei ticket, commenti del motore, issue codebase/conventions, risoluzioni). Questo scansiona ciò che una scrittura `gh issue`/`gh pr`/`gh api` sta per pubblicare (l'inline `--body`, un heredoc, o un `--body-file`) e lo **blocca in modo netto** se corrisponde a un pattern di credenziale (chiavi private, token GitHub/AWS/OpenAI/Slack/Google/Stripe, JWT, o un `password`/`secret`/`token=…` hardcoded). Il blocco è un **segnale di pulisci-e-riprova, non un vicolo cieco**: trailhead redige il valore segnalato sul posto (`<REDACTED>` o un riferimento a env-var) e ripubblica automaticamente, così il contenuto pulito atterra comunque: il segreto semplicemente non raggiunge mai il tracker. Resta un *blocco* fail-safe anziché una silenziosa auto-riscrittura di proposito: un blocco non fa mai leak, mentre una redazione che silenziosamente non è stata applicata sì. Non scansiona mai le letture, solo le scritture in uscita.
335
+ - **Issue injection scanner** (`PostToolUse` sulle letture `gh`): trailhead legge testo di issue/PR/commenti scritto da chiunque abbia accesso al repo, cioè input non fidato. Quando quel testo contiene frasi di prompt-injection, l'hook inietta un avviso che ricorda all'agente di trattarlo come dati, mai come comandi. Solo advisory: non blocca mai.
336
+
337
+ Tutti e tre sono crash-safe (qualsiasi errore → allow) e attivi ogni volta che il plugin è installato. I guard di commit e secret quindi si applicano in **ogni** repo, non solo nei progetti trailhead: intenzionale, dato che i conventional commit, niente `Co-Authored-By`, e nessun segreto leakato sono regole permanenti di trailhead. Per fare opt-out, disabilita gli hook del plugin nelle impostazioni di Claude Code.
338
+
339
+ ---
340
+
341
+ ## 🙏 Acknowledgements
342
+
343
+ `trailhead` poggia sulle spalle di due corpi di lavoro. È una metodologia originale e self-contained **ispirata da** essi. Non copia né ridistribuisce il loro codice, e non invoca nessuna delle loro skill; reimplementa le idee come propri protocolli inline:
344
+
345
+ - **[Matt Pocock](https://www.aihero.dev)**: per **Wayfinder**, il cui modello map / frontier / fog-of-war è la spina dorsale della metà di pianificazione di trailhead, e le cui skill `grilling`, `domain-modeling`, `prototype`, `research`, e `tdd` hanno plasmato le tecniche inline di trailhead. Vedi [`mattpocock/skills`](https://github.com/mattpocock/skills).
346
+ - **Il team [open-gsd](https://github.com/open-gsd/gsd-core)**: per **GSD**, il cui ciclo `discuss → plan → execute → verify`, il modello di cattura, il codebase mapping, e il debugging sistematico sono il motore della metà di costruzione di trailhead.
347
+
348
+ Grazie. Se ti piacciono le idee qui, vai a mettere una star e usa gli originali: vanno molto più in profondità dei protocolli compatti di trailhead.
349
+
350
+ ---
351
+
352
+ ## 📄 License
353
+
354
+ MIT © Marco Migozzi ([@ToRvaLDz](https://github.com/ToRvaLDz))
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # trailhead
2
2
 
3
+ 🇬🇧 **English** · 🇮🇹 [Italiano](README.it.md)
4
+
3
5
  **Start and drive large projects as a map of tickets on GitHub Issues, resolving one at a time until the way to the destination is clear.**
4
6
 
5
7
  `trailhead` is an orchestrator skill for [Claude Code](https://docs.claude.com/en/docs/claude-code). It gives a big, foggy idea a place to begin (a *trailhead*) and a disciplined way to walk it to a working result, with the whole plan living on your issue tracker instead of in scattered local files.
@@ -14,9 +16,9 @@ Two approaches to agent-driven project work each nail one half of the problem:
14
16
 
15
17
  - **GSD** (the [open-gsd](https://github.com/open-gsd/gsd-core) workflow system) is brilliant at *doing*. Its `discuss → plan → execute → verify` cycle, atomic commits, and zero-friction capture make the actual construction reliable and reviewable. But its state lives in a local `.planning/` tree, separate from where the team can see it.
16
18
 
17
- Working across both, one pattern kept recurring: **use Wayfinder's map and onboarding to decide the shape of the work, then use GSD's engine to build each piece, without ever leaving the issue tracker.** `trailhead` is that pattern made into a single skill.
19
+ Working across both, one pattern kept recurring: **use a Wayfinder-style map and onboarding to decide the shape of the work, then a GSD-style engine to build each piece, without ever leaving the issue tracker.** `trailhead` is that pattern made into a single skill, its own self-contained take on both ideas rather than a wrapper around either.
18
20
 
19
- > **trailhead is self-contained.** Wayfinder and GSD are *inspiration*, not dependencies. Every technique those systems package as a separate skill (grilling, TDD, systematic debugging, codebase mapping, code review) is **built in here as an inline protocol**. trailhead's core invokes no other skill; its subagents (research, codebase-map, review) use Claude Code's built-in `Agent` tool. The only thing to install is trailhead itself. There is one opt-in exception: when enabled, `claude.ai/design` mockup mode pushes to a design-system project via DesignSync (the `claude_design` MCP plus the `/design-sync` skill). If that isn't available, it silently falls back to local-disk mockups.
21
+ > **trailhead is self-contained.** Wayfinder and GSD are *inspiration*, not dependencies. Every technique those systems package as a separate skill (grilling, TDD, systematic debugging, codebase mapping, code review) is **built in here as an inline protocol**. trailhead's core invokes no other skill; its subagents (research, codebase-map, review) use the host's native subagents (Claude Code's built-in `Agent` tool, or Codex's `multi_agent` toolkit). The only thing to install is trailhead itself. There is one opt-in exception: when enabled, `claude.ai/design` mockup mode pushes to a design-system project via DesignSync (the `claude_design` MCP plus the `/design-sync` skill). If that isn't available, it silently falls back to local-disk mockups.
20
22
 
21
23
  The design choices that fall out of it:
22
24
 
@@ -38,7 +40,7 @@ The design choices that fall out of it:
38
40
 
39
41
  ## 📦 Install
40
42
 
41
- > **Claude Code only, for now.** trailhead installs as a Claude Code skill + `/trailhead:*` commands + hooks. It's built to grow to other AI CLIs later (the installer already uses a per-agent adapter), but today Claude Code is the only supported host.
43
+ > **Runs on Claude Code and Codex CLI.** trailhead is authored once; the installer projects host-native artifacts. On **Claude Code**: a skill + `/trailhead:*` commands + hooks. On **Codex CLI**: a native skill invoked `$trailhead`, one `$trailhead-<verb>` skill per verb for discoverability, and the guardrails as native Codex hooks. Choose the host with `--claude` / `--codex`, or let the installer auto-detect. More hosts can follow (the installer uses a per-host descriptor).
42
44
 
43
45
  **Prerequisites:** an authenticated [`gh` CLI](https://cli.github.com) (the tracker is GitHub Issues) and a GitHub repo to work in. The npm path also needs Node 18+.
44
46
 
@@ -51,15 +53,21 @@ Update with `/plugin update trailhead`; remove with `/plugin uninstall trailhead
51
53
 
52
54
  ### Or via npm (installs into your agent's config dir)
53
55
  ```
54
- npx @marcomigozzi/trailhead # install into ~/.claude (or $CLAUDE_CONFIG_DIR)
55
- npx @marcomigozzi/trailhead --symlink # dev install (symlink to the checkout, edits go live)
56
- npx @marcomigozzi/trailhead --uninstall # remove everything it added
56
+ npx @marcomigozzi/trailhead # auto-detect the host (defaults to ~/.claude)
57
+ npx @marcomigozzi/trailhead --claude # Claude Code (~/.claude or $CLAUDE_CONFIG_DIR)
58
+ npx @marcomigozzi/trailhead --codex # Codex CLI ($CODEX_HOME or ~/.codex)
59
+ npx @marcomigozzi/trailhead --symlink # dev install (Claude; symlink to the checkout, edits go live)
60
+ npx @marcomigozzi/trailhead --uninstall # remove everything it added (pair with --claude / --codex)
57
61
  npx @marcomigozzi/trailhead --dir=<path> # target a specific config dir
58
62
  ```
59
- It copies the skill (+ its `references/`), the `/trailhead:*` commands, the hooks (into `hooks/`, registered in `settings.json`) including a SessionStart **update check**, and the label-guard + statusline templates, idempotently. Re-run `npx @marcomigozzi/trailhead` to update, or run **`/trailhead:update`** from inside the agent: it detects how trailhead was installed and installs the newer version where that is safe (a `git pull` for a dev-symlink, an `npx` re-run for npm, or `/plugin update` for the plugin). When a newer version exists, the statusline shows a `⬆ trailhead <version>` flag.
63
+ On **Claude Code** it copies the skill (+ its `references/`), the `/trailhead:*` commands, the hooks (into `hooks/`, registered in `settings.json`) including a SessionStart **update check**, and the label-guard + statusline templates, idempotently.
64
+
65
+ On **Codex CLI** (`--codex`) it projects a native Codex skill invoked as **`$trailhead`** (`$trailhead work`, `$trailhead new "idea"`, …), one thin **`$trailhead-<verb>`** skill per verb for discoverability, the four guardrails as native Codex **hooks** (`~/.codex/hooks.json`, enabling `features.hooks`), and per-technique subagent model pins from **`models.codex.*`** into `~/.codex/agents/`. Codex **0.145.0+** is required (the installer gates on `codex --version`). The `claude.ai/design` mockup mode isn't available on Codex, so UI mockups fall back to local disk there.
66
+
67
+ Re-run the install to update, or run **`/trailhead:update`** (Claude) / **`$trailhead update`** (Codex) from inside the agent: it detects how trailhead was installed and installs the newer version where that is safe (a `git pull` for a dev-symlink, an `npx` re-run for npm, or `/plugin update` for the plugin). When a newer version exists, the statusline shows a `⬆ trailhead <version>` flag (Claude).
60
68
 
61
69
  ### After installing
62
- Restart or reload your agent so the commands register, then run **`/trailhead`** to start (smart entry), or `/trailhead:new "<idea>"` to chart a map. Note: once installed, the **commit guard hook runs on every `git commit`** (enforcing Conventional Commits and blocking `Co-Authored-By`); disable the plugin's hooks in settings if you don't want that. Either way trailhead is self-contained: no other skill or plugin is required, no preflight, no version drift.
70
+ Restart or reload your agent so the commands register, then run **`/trailhead`** to start (smart entry), or `/trailhead:new "<idea>"` to chart a map. **On Codex** the surface is `$trailhead` instead: run **`$trailhead`** for smart entry, `$trailhead new "<idea>"` to chart, or a per-verb `$trailhead-<verb>` skill. Note: once installed, the **commit guard hook runs on every `git commit`** (enforcing Conventional Commits and blocking `Co-Authored-By`); disable the plugin's hooks in settings if you don't want that. Either way trailhead is self-contained: no other skill or plugin is required, no preflight, no version drift.
63
71
 
64
72
  ---
65
73
 
@@ -75,12 +83,13 @@ Each **ticket** is a child issue with a type label and a one-question body. The
75
83
 
76
84
  As tickets resolve, the fog clears: questions that were too vague to phrase become sharp enough to ticket, one at a time, until nothing is left to decide or build and the destination is reached.
77
85
 
78
- A map is scoped to **one** effort, so knowledge that belongs to the *repo* (not to any single map) lives in two **repo-scoped anchor issues**, created once and shared by every map (each map's Notes just links them, so nothing is stranded when a map finishes):
86
+ A map is scoped to **one** effort, so knowledge that belongs to the *repo* (not to any single map) lives in **repo-scoped anchor issues**, created once and shared by every map (each map's Notes just links them, so nothing is stranded when a map finishes):
79
87
 
80
88
  - **`trailhead:codebase`**: the distilled codebase map (architecture, stack, conventions, risks, test/build), written once at adopt and refreshed only on major drift.
81
89
  - **`trailhead:conventions`**: the project's **way of working**, readable by everyone: a small machine-read header the engine obeys (`git: main|pr`, `release: command|auto`, `isolation: none|worktree|clone`) over human prose. `/trailhead:adopt` and `:new` ask for it up front. `isolation: worktree` gives each executing ticket its own `git worktree` + branch (concurrent sessions on one clone never share a working tree); `isolation: clone` gives it a dedicated clone instead, for path-bound apps a worktree can't build.
90
+ - **`trailhead:dashboard`**: the pinned index of the whole surface, a link to every open map (with GitHub's native progress bars), the whiteboard, and live counts (inbox, whiteboard frontier). Refreshed when a map is charted or exhausted, when a whiteboard ticket is born or resolved (it has no native progress bar, so the dashboard is the only place it shows), and on demand via `/trailhead:dashboard`.
82
91
 
83
- Together with the map, these three fill GitHub's **3 pinned-issue slots**, so a repo's trailhead anchors stay one click away. Project *config* (models, TDD, design…) is separate again, a plain `.trailhead/config.json` file at the repo root, never in an issue.
92
+ These three fill GitHub's **3 pinned-issue slots**, so a repo's trailhead anchors stay one click away; **maps themselves are never pinned** (they're indexed by the dashboard instead, since the "active" map is per-checkout local state, not a repo-global fact). Project *config* (models, TDD, design…) is separate again, a plain `.trailhead/config.json` file at the repo root, never in an issue.
84
93
 
85
94
  ---
86
95
 
@@ -157,6 +166,8 @@ Every verb is also a namespaced command (`/trailhead:new`, `/trailhead:work`, `/
157
166
  | `/trailhead:new [idea]` | chart a new map from a loose idea |
158
167
  | `/trailhead:adopt` | adopt an existing project (map the codebase once, then go lean) |
159
168
  | `/trailhead:work [ticket]` | work the next frontier ticket, or the one you name |
169
+ | `/trailhead:quick [ticket \| "text"]` | work one ticket whole, off the map: opens a whiteboard ticket from `"text"` (or takes `<n>`), runs the full engine, grills only if needed, never splits |
170
+ | `/trailhead:whiteboard` | show the whiteboard: the loose (map-less) tickets and their frontier |
160
171
  | `/trailhead:inbox [issue]` | triage issues opened by others and integrate the good ones into the map |
161
172
  | `/trailhead:resume [ticket]` | resume a paused ticket from its `PAUSED` checkpoint |
162
173
  | `/trailhead:pause [note]` | checkpoint the ticket in play so anyone can resume it |
@@ -164,6 +175,7 @@ Every verb is also a namespaced command (`/trailhead:new`, `/trailhead:work`, `/
164
175
  | `/trailhead:split [ticket]` | split an oversized ticket into children, supersede the original |
165
176
  | `/trailhead:grill [topic]` | run a standalone grilling session on a decision/topic |
166
177
  | `/trailhead:map` | show the low-res map (destination, decisions, frontier, fog) |
178
+ | `/trailhead:dashboard` | show the repo dashboard: the pinned index of every open map, the whiteboard, and live counts |
167
179
 
168
180
  ### Capture: zero friction, one confirmation line, resolves nothing
169
181
 
@@ -177,6 +189,17 @@ Every verb is also a namespaced command (`/trailhead:new`, `/trailhead:work`, `/
177
189
 
178
190
  The four fog/ticket captures form a spectrum of commitment and timing: **note < idea < seed < todo**.
179
191
 
192
+ When a map is open, a capture that produces a ticket (`todo`/`bug`/`seed`/a sharp `idea`) asks whether to file it on the **active map** or the **whiteboard**, the home for loose, map-less work that doesn't belong to any map (or isn't worth charting one). With no map open it lands on the whiteboard. Work a whiteboard ticket with **`/trailhead:quick`** (which also opens one from `"text"` and works it in the same sitting), and see them all with `/trailhead:whiteboard`.
193
+
194
+ ### 🧯 Don't get trapped in a map: the whiteboard
195
+
196
+ Deep in a map, something unrelated surfaces: a bug in another area, a chore, a quick idea you want to act on now. Forcing it onto the map's frontier pollutes the map; charting a whole new map for it is overkill. That is what the **whiteboard** is for, loose map-less work, and two moves keep you from getting stuck:
197
+
198
+ - **Capture it aside.** A `todo`/`bug`/`seed`/sharp `idea` fired while a map is open asks *map or whiteboard?*. Send it to the whiteboard and it stays off the map: tracked, but out of the way, so the map's frontier keeps meaning "the way to this destination".
199
+ - **Do it on the fly.** `/trailhead:quick "<text>"` opens a whiteboard ticket and works it end to end in the same sitting, the full discuss → plan → execute → verify engine (atomic commits, code review, the lot), except it **grills only if needed and never splits**, and skips every map book-keeping step. `/trailhead:quick <n>` does the same for a ticket that already exists.
200
+
201
+ See the whole whiteboard with `/trailhead:whiteboard`. Nothing about the map changes: you just stepped off it, did the thing, and step back on when you're ready.
202
+
180
203
  The three that trip people up are **idea, seed, todo**, so here they are spelled out:
181
204
 
182
205
  - **`idea`** = *maybe, and not yet clear.* It lands in the **fog** (`Not yet specified`), **not** as a ticket, because you can't even phrase the question sharply yet, so there is nothing to work. It **graduates** into a ticket later, when the frontier reaches it or it simply gets clearer.
@@ -211,9 +234,10 @@ Two rules of thumb: build tickets **never auto-grill**: on blocking ambiguity th
211
234
  Everything the map needs is expressed as GitHub labels, so state is queryable in the tracker UI:
212
235
 
213
236
  - **Structural:** `trailhead:map`, `trailhead:ticket`
214
- - **Repo-scoped anchors (one each per repo):** `trailhead:codebase` (the distilled codebase map), `trailhead:conventions` (the way of working)
237
+ - **Repo-scoped anchors (one each per repo, pinned):** `trailhead:codebase` 🧱 (the distilled codebase map), `trailhead:conventions` 📜 (the way of working), `trailhead:dashboard` 📊 (the pinned index of maps + whiteboard + counts) — each title carries its icon (like the map's 🗺) so the pinned anchors stand apart at a glance
215
238
  - **Type (one per ticket):** 🧭 `trailhead:decision` · 🔬 `research` · 🎨 `prototype` · 🔨 `build` · 🐛 `bug` · 🔧 `task`
216
239
  - **State:** `trailhead:blocked` (has an open blocker) · `seed` (parked on a trigger) · `out-of-scope` (closed, beyond the destination) · `superseded` (closed, split into children)
240
+ - **Container:** `trailhead:whiteboard` (a loose, map-less ticket, off every map's frontier, on the whiteboard's own)
217
241
 
218
242
  The **frontier** is then a single query (open, unassigned, not `trailhead:blocked`), no body-parsing needed.
219
243
 
@@ -257,7 +281,7 @@ Three layers: **nearest wins**, key by key (a key unset at one layer inherits th
257
281
 
258
282
  `/trailhead:config` runs a **guided, menu-driven setup**: pick the scope, then walk each setting (🌐 ticket language · 🧠 models · 🎨 design + approval · 🧪 TDD · 🖥️ acceptance testing · 🧑‍⚖️ plan review · 📊 statusline) as an icon-labelled menu; no hand-editing JSON. Every step is asked (none skipped), and **plan and execute models are always two separate, version-pinned choices**. `config get` prints the effective merged config; `config set <key> <value>` writes one key.
259
283
 
260
- The **📊 statusline** step offers to install trailhead's Claude Code status bar: one line with **model · project · branch · plan usage (`5h %` · reset · `7d %`) · a context-window bar**, plus a **second line with the active ticket** (`▸ #N Title`) whenever you're working one, and a `⬆ trailhead <version>` flag when a newer trailhead is available (run `/trailhead:update`). It's a global Claude Code setting; if you already run a statusline (e.g. `ccstatusline`) the setup asks before replacing it, and the script also exposes `--ticket-only` / `--context-only` / `--usage-only` segments to slot into an existing tool.
284
+ The **📊 statusline** step offers to install trailhead's Claude Code status bar: one line with **model · project · branch · plan usage (`5h %` · reset · `7d %`) · a context-window bar**, plus a **second line with the active ticket** (`▸ #N Title`) whenever you're working one, and a `⬆ trailhead <version>` flag when a newer trailhead is available (run `/trailhead:update`). The project is always the main repo's name even from an isolated checkout, and the branch carries a `(WT)` tag in a worktree or `(C)` in a per-ticket clone (nothing on the original checkout). It's a global Claude Code setting; if you already run a statusline (e.g. `ccstatusline`) the setup asks before replacing it, and the script also exposes `--ticket-only` / `--context-only` / `--usage-only` segments to slot into an existing tool.
261
285
 
262
286
  **First-use offer (once per project).** You don't have to seek this out: the first time you set a project up (at the end of `/trailhead:new`/`:adopt`, or on a bare `/trailhead` when a map exists but no config does) trailhead offers to run the guided setup, or to continue on defaults. It asks **only once**: configuring writes `.trailhead/config.json`, and "continue on defaults" writes an empty `{}`. Once that file exists it's never offered again, and it never interrupts mid-ticket.
263
287