Custom commands zostały połączone ze Skills. Kiedy migrować do `.claude/skills/` i co na tym zyskujesz.
Pierwsze trzy artykuły w całości omówiły slash commands: od pliku Markdown przez iniekcję !komendy aż po orkiestrację z użyciem subagentów i MCP. Nic z tego się nie zdezaktualizowało — ale za kulisami zespół oficjalny przeprowadził scalenie: custom commands zostały wchłonięte przez Skills.
Twój .claude/commands/review.md dalej działa, /review wciąż jest dostępne, nic nie musisz zmieniać. Jeśli jednak chcesz, żeby komenda dorobiła się nowych możliwości (wiele plików, wykonanie w forku, automatyczna aktywacja po path), nowa ścieżka to .claude/skills/review/SKILL.md. Ten tekst wyjaśnia dwie rzeczy: jak migrować i czy w ogóle warto.
Oficjalna obietnica kompatybilności jest jednoznaczna: .claude/commands/deploy.md i .claude/skills/deploy/SKILL.md rejestrują się tak samo jako /deploy i zachowują się identycznie. Przy kolizji nazw wygrywają skills.
Najkrótsza ścieżka migracji:
cd .claude/commands
mkdir -p ../skills/review
mv review.md ../skills/review/SKILL.md
W zawartości pliku nie zmieniasz ani jednej linii. YAML frontmatter, !`komenda`, @file, $ARGUMENTS — wszystko pozostaje kompatybilne.
Tyle że zatrzymując się na tym kroku, czytelnik słusznie pyta: to po co w ogóle migrować? Odpowiedź leży w tym, że katalog skill może pomieścić dowolnie wiele plików, podczas gdy command zawsze tylko jeden.
SKILL.md jest punktem wejścia, a w tym samym katalogu możesz trzymać dowolne dodatkowe pliki. Wyobraź sobie taką strukturę:
.claude/skills/review/
├── SKILL.md # entry point, krótkie instrukcje + odnośniki
├── checklist.md # długa checklist do code review
├── examples/
│ └── good-diff.md # przykład pozytywny
└── scripts/
└── lint.sh # skrypt wywoływany przez SKILL.md
Wewnątrz SKILL.md odwołujesz się do nich przez relatywny path:
Sprawdź bieżący diff zgodnie z kryteriami z [checklist.md](checklist.md).
Zobacz [examples/good-diff.md](examples/good-diff.md) dla oczekiwanego formatu wyjścia.
Te pliki pomocnicze nie trafiają do context automatycznie — Claude czyta je, kiedy są potrzebne. Oficjalna rekomendacja: trzymać SKILL.md poniżej 500 linii, a resztę wynosić do plików pomocniczych.
disable-model-invocation: które skills odpalasz tylko ręcznieDomyślnie Claude może samodzielnie uruchomić skill, gdy uzna moment za właściwy. W przypadku komend z efektami ubocznymi jak /deploy, /commit, /send-email to niebezpieczne — nie chcesz, żeby „zadeployował, bo kod mu się spodobał".
---
name: deploy
description: Deploy na produkcję
disable-model-invocation: true
allowed-tools: Bash(kamal deploy:*), Bash(git push:*)
---
Z tą linią /deploy odpala się wyłącznie ręcznie — Claude nie wywoła go z własnej inicjatywy w trakcie rozmowy.
Odwrotnie, user-invocable: false oznacza „wywołać może tylko sam Claude, ale w menu / tego skill nie zobaczysz" — pasuje do skills wiedzy tła (np. legacy-system-context, które Claude ładuje automatycznie w odpowiednich sytuacjach, a ręczne uruchamianie nie ma sensu).
context: fork: uruchamiaj skill w subagencieTo największa zmiana jakości. W poprzednim artykule widzieliśmy, że command przez allowed-tools: Task mogła poprosić model o podniesienie subagenta — ale opis „odpal subagenta Explore, żeby…" musiałeś wpisywać ręcznie w prompt.
W SKILL wystarczy jedna linia frontmattera:
---
name: deep-research
description: Głęboka analiza symbolu
context: fork
agent: Explore
---
Zbadaj wszystkie użycia $ARGUMENTS:
- wszystkie punkty wywołania
- scenariusze biznesowe
- alternatywne implementacje
Zwróć podsumowanie ≤300 słów.
Gdy odpalisz /deep-research SomeClass, cały SKILL.md staje się promptem osobnego subagenta, wykonywanego przez agent type Explore, a na koniec zwraca tylko konkluzję. Context głównej rozmowy pozostaje zupełnie czysty.
Z „odpalania subagenta" jako opisu w prompcie robi się deklaratywny atrybut skill.
paths: automatyczna aktywacja po typie pliku---
name: rails-conventions
description: Konwencje kodu w tym projekcie Rails
paths: ["app/**/*.rb", "config/**/*.rb"]
---
Przestrzegaj konwencji Rails tego projektu:
- używaj service object zamiast fat controller
- wszystkie scope ActiveRecord muszą być nazwane
...
Gdy edytujesz app/models/user.rb, ten skill ląduje automatycznie w context; gdy edytujesz package.json — nie. Precyzyjniej niż globalne tło CLAUDE.md — faktycznie „CLAUDE.md w warstwach po path".
/plan do skillKońcowy przykład /plan z poprzedniego artykułu był jednoplikową command:
.claude/commands/plan.md
Wersja skill:
.claude/skills/plan/
├── SKILL.md
├── research-prompt.md # instrukcje subagenta 1
└── risk-prompt.md # instrukcje subagenta 2
SKILL.md:
---
name: plan
description: Wygenerować plan wdrożenia na podstawie ticketa Linear
disable-model-invocation: true
allowed-tools: mcp__linear__*, Task, Read, Grep, Bash(git log:*)
---
## Context
@.claude/context/architecture.md
## Stan
!`git log --oneline -10`
## Zadanie
Pobierz opis i komentarze ticketa Linear $ARGUMENTS.
Za pomocą Task odpal równolegle dwa subagenty:
1. Analiza kodu: prompt w [research-prompt.md](research-prompt.md)
2. Ocena ryzyka: prompt w [risk-prompt.md](risk-prompt.md)
Skonsoliduj oba wyniki w: kroki wdrożenia + listę ryzyk + rekomendacje co do granulacji commitów.
Prompty obu subagentów leżą w osobnych plikach — możesz je zmieniać bez dotykania SKILL.md. Sam skill zostaje schludny, poniżej 30 linii, a pliki pomocnicze w razie potrzeby mogą mieć po kilkaset linii każdy.
Jeśli nie chcesz nawet samodzielnie orkiestrować subagentów, możesz pójść na całość i wrzucić cały skill do forka, żeby agent Explore wykonał wszystko jednym zamachem:
---
name: plan
context: fork
agent: Explore
allowed-tools: mcp__linear__*
---
/plan ENG-4213 → agent Explore w odizolowanym context bierze całą zawartość SKILL.md jako zadanie → zwraca tylko finalny plan. Główna rozmowa pozostaje zupełnie czysta.
Nie każda command zasługuje na upgrade. Pozostanie w .claude/commands/ jest lepsze, gdy:
Proste /commit, /pr-desc i im podobne — frontmatter plus kilka linii promptu — w .claude/commands/ wyglądają wręcz czytelniej. Oficjalnie obie formy współistnieją i żadna nie jest deprekowana.
Najczystsza dziś organizacja .claude/ wygląda mniej więcej tak:
.claude/
├── commands/ # lekkie: jeden plik + prosty prompt
│ ├── commit.md
│ └── pr-desc.md
├── skills/ # ciężkie: wiele plików / fork / kontrola dostępu
│ ├── plan/
│ │ ├── SKILL.md
│ │ ├── research-prompt.md
│ │ └── risk-prompt.md
│ ├── deploy/
│ │ └── SKILL.md # disable-model-invocation
│ └── rails-conventions/
│ └── SKILL.md # autoaktywacja przez paths glob
└── context/
└── coding-standards.md
Nie migruj wszystkiego hurtem. Sygnałem do migracji jest: „ta command zaczyna puchnąć" — powyżej 200 linii, trzeba rozbić dokumentację, chcesz puścić to w subagencie. Wtedy zmiana patha to kwestia kilku minut.
| Pożądana możliwość | commands/ |
skills/ |
|---|---|---|
| Skrót do promptu w jednym pliku | ✅ | ✅ |
!`komenda` / @file / $ARGUMENTS |
✅ | ✅ |
Kontrola dostępu przez allowed-tools |
✅ | ✅ |
| Pliki pomocnicze (referencje, scripts) | ❌ | ✅ |
disable-model-invocation przeciw przypadkowym odpaleniom |
❌ | ✅ |
Izolowane wykonanie przez context: fork + agent: |
❌ | ✅ |
Autoaktywacja przez paths: glob |
❌ | ✅ |
W pierwszych trzech wierszach commands i skills są w pełni równoważne; ostatnie cztery to wyłączna domena skills. Bierzesz to, czego potrzebujesz, reszty nie ruszasz.
Oficjalny kierunek skłania się ku skills, ale obietnica kompatybilności commands/ jest jednoznaczna — to nie jest zmiana typu „migruj teraz albo zginiesz", tylko rozszerzenie „masz nowe możliwości bez przymusu". Zrozum różnice, migruj wedle potrzeb i nie ścigaj się o kosmetyczną jednolitość.