Free

Da Slash Commands a Skills: quando e come migrare

I custom commands sono confluiti in Skills. Quando migrare a `.claude/skills/` e cosa ci guadagni.


I tre articoli precedenti hanno coperto l'uso completo degli slash command: dal file Markdown all'iniezione tramite !comando, fino all'orchestrazione via subagent e MCP. Nulla di tutto ciò è obsoleto — ma dietro le quinte è avvenuta una fusione ufficiale: i custom command sono confluiti in Skills.

Il tuo .claude/commands/review.md continua a funzionare, /review è ancora disponibile, non devi cambiare nulla. Ma se vuoi che il comando cresca di capacità (più file, esecuzione in fork, attivazione automatica per path), la nuova strada è .claude/skills/review/SKILL.md. Questo articolo chiarisce due cose: come migrare e se ne vale la pena.


Migrazione minima: cambia un path, basta

La promessa di compatibilità ufficiale è chiara: .claude/commands/deploy.md e .claude/skills/deploy/SKILL.md vengono entrambi registrati come /deploy e si comportano nello stesso modo. In caso di collisione di nomi, vincono gli skill.

Passi minimi:

cd .claude/commands
mkdir -p ../skills/review
mv review.md ../skills/review/SKILL.md

Nel contenuto del file non cambia una sola riga. Frontmatter YAML, !`comando`, @file, $ARGUMENTS — tutto resta compatibile.

Fermandosi qui, però, viene spontaneo chiedersi: allora perché migrare? La risposta sta nel fatto che una cartella skill può ospitare più file, mentre un command può averne solo uno.


Perché migrare: le quattro cose in più di SKILL.md

1. File di supporto: tira fuori la documentazione lunga

SKILL.md è il punto d'ingresso; nella stessa cartella puoi mettere qualsiasi file accessorio. Immagina questa struttura:

.claude/skills/review/
├── SKILL.md            # entry point, istruzioni brevi + riferimenti
├── checklist.md        # checklist lunga di code review
├── examples/
│   └── good-diff.md    # esempio positivo
└── scripts/
    └── lint.sh         # script invocabile da SKILL.md

Dentro SKILL.md si referenziano via path relativo:

Rivedi il diff corrente seguendo i criteri di [checklist.md](checklist.md).
Consulta [examples/good-diff.md](examples/good-diff.md) per il formato di output atteso.

Questi file accessori non entrano automaticamente nel context — Claude li legge quando servono. La raccomandazione ufficiale: tenere SKILL.md sotto le 500 righe e spostare il resto nei file di supporto.

2. disable-model-invocation: quali skill solo tu puoi attivare a mano

Per default Claude può invocare autonomamente uno skill quando ritiene che sia il momento giusto. Per i comandi con effetti collaterali come /deploy, /commit, /send-email, è pericoloso — non vuoi che «deployi perché trova il codice bello».

---
name: deploy
description: Deploy verso la produzione
disable-model-invocation: true
allowed-tools: Bash(kamal deploy:*), Bash(git push:*)
---

Con questa riga, /deploy si attiva solo digitandolo manualmente: Claude non lo lancerà più di sua iniziativa nel corso della conversazione.

Al contrario, user-invocable: false significa «lo può chiamare solo Claude, ma non appare nel menu /» — adatto a skill di conoscenza di sfondo (per esempio legacy-system-context, che Claude carica automaticamente nei contesti rilevanti e che non avrebbe senso innescare a mano).

3. context: fork: fai girare lo skill in un subagent

È l'evoluzione più grossa. Nel precedente articolo vedevamo che un command poteva usare allowed-tools: Task per chiedere al modello di avviare un subagent — ma dovevi scrivere a mano nel prompt «avvia un subagent Explore che…».

Con uno SKILL basta una riga di frontmatter:

---
name: deep-research
description: Investigare a fondo un simbolo
context: fork
agent: Explore
---

Indaga tutti gli usi di $ARGUMENTS:
- tutti i punti di chiamata
- scenari di business
- implementazioni alternative

Restituisci un riassunto di ≤300 parole.

Quando attivi /deep-research SomeClass: l'intero SKILL.md diventa il prompt di un subagent indipendente, eseguito con agent type Explore, che a fine esecuzione restituisce solo la conclusione. Il context della conversazione principale resta perfettamente pulito.

È come trasformare «avviare un subagent» da testo descrittivo nel prompt ad attributo dichiarativo dello skill.

4. paths: attivazione automatica per tipo di file

---
name: rails-conventions
description: Convenzioni di codice per questo progetto Rails
paths: ["app/**/*.rb", "config/**/*.rb"]
---

Segui le convenzioni Rails di questo progetto:
- usa service object invece di fat controller
- gli scope ActiveRecord devono essere nominati
...

Mentre stai editando app/models/user.rb, questo skill viene aggiunto automaticamente al context; quando editi package.json no. Più preciso del background globale di CLAUDE.md — una specie di «CLAUDE.md stratificato per path».


In pratica: promuovere /plan a skill

L'ultimo /plan dell'articolo precedente era un command a singolo file:

.claude/commands/plan.md

Versione skill:

.claude/skills/plan/
├── SKILL.md
├── research-prompt.md     # istruzioni per il subagent 1
└── risk-prompt.md         # istruzioni per il subagent 2

SKILL.md:

---
name: plan
description: Produrre un piano implementativo a partire da un ticket Linear
disable-model-invocation: true
allowed-tools: mcp__linear__*, Task, Read, Grep, Bash(git log:*)
---

## Context

@.claude/context/architecture.md

## Stato

!`git log --oneline -10`

## Compito

Recupera descrizione e commenti del ticket Linear $ARGUMENTS.

Usa Task per lanciare in parallelo due subagent:
1. Ricerca nel codice: prompt in [research-prompt.md](research-prompt.md)
2. Valutazione dei rischi: prompt in [risk-prompt.md](risk-prompt.md)

Unifica i due risultati producendo: passi implementativi + elenco rischi + raccomandazioni sulla granularità dei commit.

I prompt dei due subagent vivono in file separati: li si modifica senza toccare SKILL.md. Lo skill resta sotto le 30 righe, pulito, mentre i file accessori possono superare tranquillamente le centinaia di righe l'uno.

Se non vuoi nemmeno orchestrare tu i subagent, puoi spingerti oltre: buttare l'intero skill in fork e lasciare che l'agente Explore lo esegua di filato:

---
name: plan
context: fork
agent: Explore
allowed-tools: mcp__linear__*
---

/plan ENG-4213 → l'agente Explore, in un context isolato, prende tutto il contenuto di SKILL.md come compito → restituisce solo il piano finale. La conversazione principale resta completamente pulita.


Quando non migrare

Non tutti i command meritano l'upgrade. Conviene restare in .claude/commands/ quando:

  • Basta un singolo Markdown: non ci sono checklist, esempi o script da esternalizzare.
  • Non serve l'esecuzione in fork: il task è fortemente accoppiato alla conversazione principale e ha bisogno di vedere tutta la cronologia.
  • Non serve l'attivazione automatica per path: è l'utente a triggerarlo a mano.
  • Non serve controllo degli accessi: niente di male se Claude lo chiama da solo.

I semplici /commit, /pr-desc e simili — un frontmatter più qualche riga di prompt — risultano persino più chiari in .claude/commands/. Ufficialmente: entrambe le forme coesistono e nessuna sarà deprecata.


Stato attuale della coesistenza

Oggi l'organizzazione più pulita di .claude/ è più o meno così:

.claude/
├── commands/           # leggero: file singolo + prompt semplice
│   ├── commit.md
│   └── pr-desc.md
├── skills/             # pesante: multi-file / fork / controllo accessi
│   ├── plan/
│   │   ├── SKILL.md
│   │   ├── research-prompt.md
│   │   └── risk-prompt.md
│   ├── deploy/
│   │   └── SKILL.md    # disable-model-invocation
│   └── rails-conventions/
│       └── SKILL.md    # attivazione auto via paths glob
└── context/
    └── coding-standards.md

Non migrare tutto in blocco. Il segnale per migrare è «questo command sta iniziando a gonfiarsi» — oltre 200 righe, bisogno di spezzare la doc, voglia di farlo girare in un subagent. Quando ci sei, cambi il path. Questione di minuti.


In sintesi

Capacità desiderata commands/ skills/
Shortcut a prompt in singolo file
!`comando` / @file / $ARGUMENTS
Controllo accessi tramite allowed-tools
File di supporto (riferimenti, script)
disable-model-invocation anti-falso-trigger
Esecuzione isolata con context: fork + agent:
Attivazione automatica via paths: glob

Sulle prime tre righe commands e skills sono perfettamente equivalenti; le ultime quattro sono prerogativa degli skill. Si usa ciò che serve e basta.

La direzione ufficiale pende verso gli skill, ma la promessa di compatibilità di commands/ è chiara — non è un cambio del tipo «migra subito o sparisci», ma un'estensione «ti offro più potenza senza obbligarti». Capisci le differenze, migra quando serve, non inseguire un'uniformità estetica.