PHP 8.6 vychází 19. listopadu. DressCode pro něj kód přepisuje už teď. 16 dní Přechod na novější PHP →

AI agenti: Claude Code a Codex

AI agent píše PHP kód rychle a po svém. DressCode po každé jeho editaci srovná soubor podle standardu projektu a jako dobrý krejčí mu hned řekne, co přešil: diff přepisu, odstraněné importy a co zbylo, s radou, co s tím dělat.

Instalace

V Claude Code stačí dva příkazy:

/plugin marketplace add nette/agent-plugins
/plugin install php-fixer@nette

Plugin php-fixer pak po každé editaci PHP souboru pustí DressCode s konfigurací projektu (nejbližší dresscode.neon), a kde žádná není, se standardem Nette. Do Codexu se tentýž plugin přidá příkazem codex plugin add php-fixer@nette; jeho hooky je potřeba jednou schválit v /hooks. Kde DressCode není nainstalovaný v projektu ani globálně, nainstaluje ho skill install-php-fixer.

Hook zachytí zápisy nástroji Edit a Write v Claude Code a apply_patch v Codexu. Soubor, který agent zapíše příkazem v shellu (Bash), hook nevidí; takový soubor srovná až další editace nebo dresscode fix.

Co agent dostane

Když se agent nedozví, co se mu v souboru pod rukama změnilo, nastává známá smyčka: agent zapíše use, hook ho jako nepoužitý smaže, agent přidá kód, který ten import potřeboval, a diví se, kde se stala chyba. Nebo upraví další místo podle textu, který si pamatuje, a editace selže, protože soubor už vypadá jinak. Formát agent na to odpovídá větami pro model:

DressCode changed `src/Cart.php`; the changes below are already in the file:

- removed the import of `Acme\Shop\Payment\Gateway`: nothing used it; if you meant to use it, add the import in the same edit as the use.

```diff
@@ -12,7 +10,7 @@

 	public function add(string $name, int $price): void
 	{
-		$this->items[] = ["name" => $name, "price" => $price];
+		$this->items[] = ['name' => $name, 'price' => $price];
 	}


```

Left in `src/Cart.php`, at the lines of the file as it is now:
- line 19: the `@` operator must not be used (`mistakes.errorSuppression`). Fix it; where the current code is intended and you know why, keep it with a comment on its line, `// @ <why>`, giving the real reason for `<why>`; otherwise tell the user.
  • K čistému souboru hook nevypíše nic, takže nezahlcuje kontext.
  • Přepis přijde jako diff toho, co už v souboru je, takže další editace míří správně. Kde je přepis delší, než se do zprávy vejde, dostane agent místo diffu pokyn soubor přečíst znovu.
  • Zpráva jmenuje odstraněný import, s radou přidat ho ve stejné editaci jako jeho použití.
  • U každého porušení stojí, co s ním dělat: u rizikové opravy, proč se neudělala a že změna musí zachovat zamýšlené chování, a kde projekt schvaluje výjimku komentářem (klíč suppressionComments), ukázka toho komentáře. dresscode:ignore se agentovi nenabízí nikdy.
  • Varování ke konfiguraci formát vynechá, s těmi agent nic nenadělá.

Styl souboru

Hook předá DressCode i text souboru před editací (--before). Co ten text nedodržoval, je styl souboru, ne chyba agenta: DressCode to nechá, jak to soubor píše, a agentovi řekne, ať tam píše ve stylu souboru:

Before the edit `src/Legacy.php` did not follow `indentation.unit`, `literals.quotes`, so DressCode leaves them as the file writes them; write the code there in the style of the rest of the file.

Soubor, který ještě standardu neodpovídá, se tak při úpravě jedné metody nepřeformátuje celý, do úzkého commitu se nedostane nic, co agent nepsal, a soubor odsazený mezerami zůstane odsazený mezerami. Co editace pokazila, se naopak opraví, ať to stojí kdekoli: import, kterému vzala poslední použití, nebo řádky, které obalila novým blokem. Nový soubor je celý agentův, a proto se opraví celý. Na zbytek projektu je dresscode fix, který pusťte vědomě a commitněte zvlášť.

Bez hooku

Agent nebo nástroj, který umí spustit příkaz po zápisu souboru, pustí totéž sám:

dresscode fix src/Cart.php -f agent --skip-excluded --before /tmp/Cart.before.php --lines 12-14

Díky --skip-excluded příkaz nesáhne na soubor, který konfigurace vylučuje v excludePaths, třeba na fixturu testu, do které agent zapsal. Bez --before se opraví celý soubor, --lines zužuje jen výpis.

Upgrade s agentem

Po upgradu knihoven zbude seznam míst, která musí přepsat člověk, a každá hláška v něm říká, co napsat místo starého API. Takový seznam je přesně práce pro agenta. S formátem agent dostane diff toho, co DressCode přepsal, a u každého zbylého nálezu, co s ním dělat:

dresscode upgrade today -f agent

Formát agent nevypisuje radu k dalšímu běhu, kterou dává terminál, a tak příkaz pusťte znovu, dokud něco přepisuje. Odhad a plán upgradu dostane agent jako data, třeba dresscode upgrade plan php 8.4 --format json, a stejně tak běh plánu, upgrade tasks a upgrade status; formát agent tyhle příkazy nemají. Dokument nese kořen projektu v klíči root a u uloženého plánu klíč planIdentity, otisk souboru plánu, podle kterého agent pozná, o kterém plánu dokument mluví. Ve formátu json se DressCode na nic neptá, ani v terminálu, a tak typy zapněte přepínačem --types a zvednutí verzí v composer.json při upgrade run povolte přepínačem --yes; bez něj běh Composer ani nespustí a skončí s exit kódem 4. Data dávají agentovi i init a migrate: dresscode init --format json změří konfiguraci, vezme doporučené odpovědi a to, na co by se ptal, vrátí pod instructions.

Méně rizikových oprav

Rizikové opravy hook neudělá, jen je ohlásí. Aby jich zbývalo co nejméně, patří do dresscode.neon i klíč nameResolution: certain: s ním přestanou být rizikové opravy, které stojí na tom, že je funkce globální, a hook je udělá sám. Totéž udělají typy s opravami, které stojí na typu hodnoty.

Zobrazit na GitHubu · Nahlásit problém se stránkou na GitHubu · 2. 11. 2026