---
title: "Preparare un progetto per Claude Code e Codex: dal setup alla prima modifica"
source: "https://www.matteovincenti.com/blog/preparare-progetto-claude-code-codex"
language: it
author: "Matteo Vincenti"
published: 2026-10-25
category: "AI"
tags: ["Claude Code", "Codex", "Agenti AI", "Workflow"]
---

# Preparare un progetto per Claude Code e Codex: dal setup alla prima modifica

Dalla cartella vuota alla prima modifica verificata: istruzioni AGENTS.md e CLAUDE.md, test, permessi e handoff per lavorare con gli agenti AI.

![Un portatile accanto a una cartella con documenti che rappresentano struttura, istruzioni e test del progetto.](https://cdn.sanity.io/images/xrqkwry7/production/4e05c3fd3c96f4ae7455c1084cf19724a833213b-1536x1024.png?w=1400&fit=max&auto=format)

Categoria: AI · Tag: Claude Code, Codex, Agenti AI, Workflow

Ogni nuova sessione di lavoro con un agente può riaprire le stesse domande: qual è la cartella giusta, come si eseguono i test, quali file si possono cambiare? Se le risposte rimangono nelle conversazioni, il progetto dipende da ciò che ci ricordiamo di riscrivere nel prompt.

Preparare il repository significa rendere queste informazioni facili da trovare e collegarle a un risultato controllabile. Qui partiamo da una cartella vuota, costruiamo una piccola funzione per i nomi dei file CSV e affidiamo una modifica circoscritta a Claude Code o Codex. Il percorso funziona anche a mano: prima un test passa, poi un requisito nuovo lo mette in crisi, infine una correzione risolve il problema senza alterare l’estensione del file.

Il repository è l’insieme dei file del progetto, normalmente versionato con Git; la sua *root* è la cartella principale. I Projects delle applicazioni di chat hanno una gestione propria di istruzioni e documenti. Il setup qui riguarda agenti che lavorano sui file locali: caricare gli stessi documenti in una chat non equivale ad aprire il repository.

Se hai già un progetto, conserva il suo setup. La sezione «Portare il setup nel progetto vero» mostra come ricavare comandi e vincoli dai file esistenti; il laboratorio permette di provare il percorso completo senza intervenire sul codice di lavoro.

## Partire da un progetto che sappiamo controllare

Servono un editor, Node.js 22 o successivo e npm. I comandi di creazione delle cartelle qui sotto sono per un terminale macOS, Linux o WSL. Se Node non è disponibile, installalo seguendo le [istruzioni ufficiali](https://nodejs.org/en/download). Per la funzione non servono pacchetti aggiuntivi, credenziali o servizi.

Crea una cartella nuova, separata dai progetti su cui lavori:

```bash
mkdir agent-project-example
cd agent-project-example
mkdir src test tasks
node --version
npm --version
```

Da questo punto tutti i comandi partono da `agent-project-example`. Apri proprio questa cartella nell’editor. Scriverai tu i sette file seguenti, nei passaggi indicati: nessun comando di Claude o Codex li genera.

```txt
agent-project-example/
├── package.json
├── src/
│   └── export-name.mjs
├── test/
│   └── export-name.test.mjs
├── AGENTS.md
├── CLAUDE.md
├── tasks/
│   └── export-name.md
└── handoff.md
```

Comincia dai tre file che rendono eseguibile l’esempio. `package.json` dà un nome al progetto e definisce il comando di test:

```json
{
  "name": "csv-export-name-example",
  "private": true,
  "type": "module",
  "engines": { "node": ">=22" },
  "scripts": { "test": "node --test --test-reporter=spec test/export-name.test.mjs" }
}
```

In `src/export-name.mjs` inserisci la versione iniziale della funzione:

```javascript
import { extname } from 'node:path';

export function exportName(fileName) {
  const extension = extname(fileName);
  const base = fileName.slice(0, fileName.length - extension.length);
  const stem = base.trim().toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '');

  return `${stem || 'export'}${extension}`;
}
```

`exportName` riceve un nome completo come `Report Marzo.csv`. Separa l’estensione, rende minuscola la parte precedente e sostituisce spazi e altri separatori con trattini. Il risultato è `report-marzo.csv`. Non legge né scrive file.

Crea `test/export-name.test.mjs` con questi cinque casi:

```javascript
import assert from 'node:assert/strict';
import test from 'node:test';
import { exportName } from '../src/export-name.mjs';

test('keeps the CSV extension while formatting an ASCII name', () => {
  assert.equal(exportName('Report Marzo.csv'), 'report-marzo.csv');
});

test('collapses separators and retains digits', () => {
  assert.equal(exportName('  Report__Marzo---2026.csv'), 'report-marzo-2026.csv');
});

test('preserves the exact extension spelling', () => {
  assert.equal(exportName('Report Marzo.CSV'), 'report-marzo.CSV');
});

test('formats internal dots without changing the final extension', () => {
  assert.equal(exportName('Report finale.v2.csv'), 'report-finale-v2.csv');
});

test('uses the existing fallback when the base has no ASCII letters or digits', () => {
  assert.equal(exportName('  ---  .csv'), 'export.csv');
});
```

Il [test runner integrato in Node](https://nodejs.org/api/test.html) esegue le verifiche; `assert.equal` confronta il risultato con quello atteso. Avvia:

```bash
npm test
```

L’esito iniziale deve essere cinque test superati e nessun errore. Non eseguire `npm install`: il progetto non ha dipendenze da scaricare. Se il comando non parte o un caso fallisce, correggi prima il setup. Un agente incaricato di una modifica deve poter distinguere un difetto già presente da quello che sta introducendo.

La sequenza di codice e test usata per questa guida è stata verificata con Node.js 22.23.4 e npm 10.9.9 su macOS arm64. La prova riguarda l’esempio eseguibile; non misura l’efficacia o il consumo di Claude Code e Codex.

## Una sola fonte per le istruzioni del progetto

Le regole che restano valide fra un incarico e l’altro appartengono al progetto: comando di test, cartella da cui eseguirlo, limiti delle modifiche. Il requisito della singola modifica arriverà invece in un documento separato.

Crea `AGENTS.md` nella root:

```markdown
# Repository instructions

This dependency-free Node.js example formats CSV export names.

- Work from the project root. Use Node.js 22 or later.
- Read the task file named in the prompt and handoff.md before editing.
  These are custom project documents, not automatically loaded files.
- Run npm test before and after a source change. No installation is needed.
- Keep the acceptance tests unchanged while implementing the task.
  If a test conflicts with the request, report the conflict first.
- Preserve the filename extension and existing regression-test behavior.
- Do not add packages, edit unrelated files, commit, push, or publish.
- Update handoff.md with changed files, the exact command, the observed
  result, and remaining work. Report a check as blocked if it cannot run.
```

In questo esempio uso l’inglese per i documenti riutilizzabili; puoi scegliere la lingua del tuo team. Ogni riga riguarda un’azione verificabile. Non serve aggiungere una descrizione generica dell’agente ideale.

Accanto ad `AGENTS.md`, crea `CLAUDE.md` con una sola riga:

```txt
@AGENTS.md
```

La riga va nel file come testo, senza i delimitatori del blocco di codice. È la sintassi di import di Claude Code: carica il file indicato, con percorso relativo a `CLAUDE.md`. Evita di mantenere due copie delle stesse regole; il contenuto importato occupa comunque contesto. [Documentazione sugli import](https://code.claude.com/docs/en/memory#import-additional-files).

Codex cerca le istruzioni all’avvio, combinando quelle globali con quelle trovate dalla root del progetto fino alla cartella corrente. In una stessa directory `AGENTS.override.md` ha precedenza su `AGENTS.md`. Per questo esempio avvialo dalla root, e apri una nuova sessione se cambi le istruzioni. [Discovery di AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md#how-codex-discovers-guidance).

Le versioni recenti di Claude Code supportano anche la lettura diretta di `AGENTS.md`, ma la selezione dipende dalle altre istruzioni presenti e dalle impostazioni. Il piccolo `CLAUDE.md` mantiene esplicito l’import. In Claude Code puoi controllare i file di memoria attraverso `/context` e `/memory`; per Codex segui i controlli di caricamento nella [guida ufficiale](https://learn.chatgpt.com/docs/agent-configuration/agents-md#verify-your-setup).

Questi file dicono all’agente come lavorare. Scrivere “non fare push” non revoca le credenziali Git né impedisce tecnicamente il comando: i limiti di accesso si configurano nel client. Per una prova locale bastano i file del progetto e l’esecuzione dei test; non occorre concedere accesso alla produzione. Le impostazioni sono documentate nelle guide ai [permessi di Claude Code](https://code.claude.com/docs/en/permissions) e alla [sicurezza di Codex](https://learn.chatgpt.com/docs/agent-approvals-security). Il rapporto fra istruzioni e controlli applicati dal software è approfondito nell’articolo sull’[harness engineering](https://www.matteovincenti.com/blog/harness-engineering-controlli-agenti-ai).

## Dare al primo incarico un confine preciso

La funzione iniziale perde le lettere accentate: `Caffè già pagato.csv` diventa `caff-gi-pagato.csv`. La richiesta è conservarne la lettera di base, ottenendo `caffe-gia-pagato.csv`. L’estensione deve rimanere intatta, compresa l’eventuale maiuscola `.CSV`.

Scrivi `tasks/export-name.md`:

```markdown
# Retain decomposable Latin letters in CSV export names

## Requested behavior

exportName receives a complete CSV filename, not a path.
Convert decomposable Latin accents to their ASCII letters in the base name:
- Caffè già pagato.csv -> caffe-gia-pagato.csv
- Cafe\u0301 résumé.csv -> cafe-resume.csv
  (\u0301 is the combining acute accent used in the JavaScript test.)

## Acceptance conditions

- Preserve the exact final extension, including .CSV.
- Preserve lowercasing, separator collapsing, digits, internal-dot handling,
  and the export fallback covered by the five existing tests.
- Pass all six tests with npm test.
- Keep test/export-name.test.mjs unchanged while implementing the source fix.

## Scope and delivery

Change src/export-name.mjs and record the result in handoff.md.
Use built-in APIs. Do not add dependencies or filesystem I/O.
General transliteration (including ø and ß), non-Latin scripts, paths,
hidden files, and malformed inputs are outside this task.
Report the changed files and the exact verification result.
```

Il documento definisce cosa cambiare e cosa conservare. Il suo nome è una convenzione dell’esempio: Claude e Codex non lo caricano automaticamente perché si trova in una cartella chiamata `tasks`. Lo indicheremo nella richiesta.

Prima di modificare il sorgente, aggiungi questo sesto test in fondo a `test/export-name.test.mjs`, lasciando i cinque precedenti:

```javascript
test('retains decomposable Latin letters in accented CSV names', () => {
  assert.equal(exportName('Caffè già pagato.csv'), 'caffe-gia-pagato.csv');
  assert.equal(exportName('Cafe\u0301 résumé.csv'), 'cafe-resume.csv');
});
```

Il secondo input contiene una `e` seguita dal segno di accento Unicode `\u0301`: sullo schermo può sembrare identico a una `é`, pur essendo rappresentato diversamente nella stringa.

Esegui di nuovo `npm test`. Ora il risultato atteso è cinque test superati e uno fallito; il messaggio mostra questa differenza:

```txt
actual:   caff-gi-pagato.csv
expected: caffe-gia-pagato.csv
```

È il momento giusto per fissare il punto di partenza. Crea `handoff.md` con il testo seguente se corrisponde all’esito che hai appena osservato; altrimenti registra l’errore effettivo e risolvi la differenza prima di procedere.

```markdown
# Export-name handoff

State: the source still has the original ASCII-only formatter.
The sixth test has been added for decomposable Latin accents.

Last check: npm test — five tests passed and one failed.
Actual: caff-gi-pagato.csv
Expected: caffe-gia-pagato.csv

Next: read tasks/export-name.md, change only the base-name formatting
in src/export-name.mjs, keep the six tests unchanged, then run npm test.
No source fix has been applied yet.
```

Anche `handoff.md` è un nostro documento. Serve a conservare lo stato del lavoro e il prossimo passo: non è memoria automatica del client.

## Passare il lavoro all’agente, oppure completarlo a mano

Se hai già installato Claude Code o Codex e configurato l’accesso al tuo account, avvia **uno dei due** dalla root dell’esempio:

```bash
claude
```

oppure:

```bash
codex
```

Se il client manca, usa prima il quickstart di [Claude Code](https://code.claude.com/docs/en/quickstart) o di [Codex](https://learn.chatgpt.com/docs/codex/cli). L’uso dell’agente dipende dall’account e dal piano; il laboratorio Node si può completare senza avviarlo.

Prima del task, controlla che il client sia partito con le istruzioni previste. In Claude Code, `/context` mostra i Memory files e `/memory` i percorsi: cerca il `CLAUDE.md` appena creato. In una nuova sessione Codex puoi chiedere:

```txt
Without reading additional files, summarize the repository instructions
already available in this session. Name their source paths and the test command.
Do not change files or run commands.
```

Confronta la risposta con il file: ti aspetti la root dell’esempio, `npm test` e il vincolo sui test di accettazione. Se qualcosa manca, controlla directory e discovery nella guida ufficiale prima di proseguire. Il riepilogo è un controllo diagnostico; l’output dei test servirà a verificare il lavoro. Chiedere subito `Read AGENTS.md` salterebbe questa distinzione: il file potrebbe essere letto su richiesta anche se non era stato caricato all’avvio.

Dopo questo controllo, invia il task:

```txt
Read AGENTS.md, tasks/export-name.md, and handoff.md.
Explain the current state and run npm test before editing.
Implement only the source change requested by the task.
Keep the acceptance tests unchanged.
Run npm test again, inspect the changed files, and update handoff.md
with the observed result and any remaining work.
Do not commit, push, or publish.
```

La richiesta richiama i file che descrivono il lavoro, invece di ricopiarli nella conversazione. Per capire se l’agente è partito dal punto giusto, controlla che abbia letto il task e rilevato il fallimento del sesto test. Se propone una ristrutturazione del progetto o cambia il risultato atteso, il lavoro si è allargato oltre l’incarico.

Per il percorso manuale, o per confrontare la patch proposta, questa è la versione completa corretta di `src/export-name.mjs`:

```javascript
import { extname } from 'node:path';

export function exportName(fileName) {
  const extension = extname(fileName);
  const base = fileName.slice(0, fileName.length - extension.length);
  const stem = base.normalize('NFD').replace(/\p{M}/gu, '').trim().toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '');

  return `${stem || 'export'}${extension}`;
}
```

La modifica aggiunge la normalizzazione `NFD` e rimuove i segni combinanti con `\p{M}` dalla sola parte precedente l’estensione. NFD scompone caratteri come `è` in lettera e accento; il resto della funzione continua a gestire minuscole, separatori e fallback come prima. [Normalizzazione Unicode in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize).

Il confine sulla base del nome conta più della lunghezza della patch. Applicare la stessa trasformazione a tutto `fileName` produce, per esempio, `report-marzo-csv`: l’accento sarebbe risolto, ma l’estensione avrebbe perso il punto. Il primo test intercetta già questa regressione.

## Verificare il risultato e lasciare un handoff utile

Con il sorgente corretto e i sei test invariati, lancia ancora:

```bash
npm test
```

Devi ottenere sei test superati e zero falliti. Rileggi anche il sorgente: il passaggio che estrae l’estensione e il valore restituito devono essere ancora quelli della versione iniziale. Il confronto ti dice se la modifica riguarda davvero il punto richiesto, anche quando la suite è verde.

Se hai usato un agente, confronta i file modificati con il perimetro del task. Nella fase di implementazione il test aggiunto era già fissato: gli interventi previsti sono sul sorgente e sull’handoff. Nell’esempio puoi confrontarli con i blocchi dell’articolo; in un repository già versionato usa il diff del tuo editor o di Git. Git non è necessario per eseguire questo laboratorio.

Quando il risultato corrisponde, aggiorna `handoff.md`:

```markdown
# Export-name handoff

State: the requested source fix is implemented.
Changed: src/export-name.mjs and this handoff.
The source applies NFD normalization and combining-mark removal to
the base name. Extension handling is unchanged.

Last check: npm test — six tests passed, zero failed.
The acceptance tests were unchanged during the source fix.
Remaining work: review the source diff. No commit or publication requested.
```

La nota riporta un esito preciso e lascia la review come lavoro successivo. Se il test non è stato eseguito, scrivi perché; “dovrebbe funzionare” non è un risultato da passare alla sessione seguente.

Per riprendere in una nuova sessione, dalla stessa root usa:

```txt
Read AGENTS.md, tasks/export-name.md, and handoff.md.
Compare the handoff with the current source and tests.
Run npm test and report any difference from the recorded state.
Do not change files yet.
```

La nuova sessione ha così una domanda limitata: il progetto corrisponde ancora alla nota? Se nel frattempo qualcuno ha cambiato i test o il sorgente, la discrepanza deve emergere prima di proseguire. La scelta di cosa conservare nel passaggio di consegne è sviluppata nella guida a [context engineering, memoria e handoff](https://www.matteovincenti.com/blog/context-engineering-memoria-handoff-wiki).

## Portare il setup nel progetto vero

Nei miei repository convivono situazioni diverse: applicazioni con i propri comandi, un repository che coordina altri progetti e istruzioni generate da una fonte comune. Scrivere «esegui i test dalla root» senza indicare quale progetto possiede la modifica lascia all’agente una decisione che dovremmo aver già risolto.

Comincia da una ricognizione limitata all’incarico. Leggi le istruzioni esistenti, il README, il manifest delle dipendenze, il lockfile e i controlli CI pertinenti. Segui anche gli script richiamati: il nome `build` o `test` da solo dice poco su ciò che verrà eseguito. In un repository Git, `git status --short` e `git diff --stat` aiutano a riconoscere le modifiche già presenti, da conservare.

Puoi affidare questa lettura all’agente con una richiesta come questa:

```txt
Inspect the existing instructions and the files relevant to this task.
Do not edit files, install dependencies, or run project commands yet.
Identify the project that owns the change and its working directory.
Read the README, manifests, lockfiles, relevant CI checks, and the scripts
they invoke. Report the runtime, package manager, prerequisites,
generated files and their editable sources.
For each proposed check, cite its source and explain what it verifies.
Separate observed configuration, planned work, and checks not yet run.
Report conflicts between instructions and code.
```

C’è un esempio molto concreto nel mio [log-service-js](https://github.com/MatteoVincenti/log-service-js/blob/e2dfd28029e510037309018841d74a4e39e7d8e4/package.json): il manifest espone `build`, `watch`, `serve` e `start`, ma nessuno script `test`; il [README](https://github.com/MatteoVincenti/log-service-js/blob/e2dfd28029e510037309018841d74a4e39e7d8e4/README.md) mette ancora i test fra i TODO. Copiare qui `npm test` dal laboratorio produrrebbe subito un’istruzione sbagliata.

Una piccola mappa rende evidente la differenza. Questa confronta i file del progetto pubblico alla revisione collegata con il laboratorio della guida:

_Portare il setup nel progetto vero_

| Voce | Laboratorio CSV | Progetto di logging |
| --- | --- | --- |
| Comando e directory | `npm test`, root dell’esempio | `yarn build`, root del progetto secondo il README |
| Fonte del comando | `package.json → scripts.test` | `package.json → scripts.build`, che invoca `scripts/build.js` |
| Prerequisiti | Node 22+, npm; nessun pacchetto aggiuntivo | Node, Yarn e dipendenze del progetto disponibili |
| Controllo disponibile | Sei casi sul comportamento dopo la correzione | Build tramite esbuild; script di test non dichiarato |
| Stato della verifica | Sei test superati nella prova descritta sopra | Configurazione letta; build non eseguita |

La decisione cambia: nel laboratorio possiamo assegnare subito la correzione; se nel progetto reale manca un controllo del comportamento da modificare, il primo incarico è costruirne uno rappresentativo. Una build riuscita serve, ma non dice se un messaggio di log viene inviato al destinatario corretto. Con un controllo già disponibile, invece, eseguilo prima della patch e conserva l’esito come punto di confronto. Se richiede un servizio o una credenziale non disponibili, registra quel blocco prima di stimare il lavoro.

Non serve compilare una mappa dell’intero sistema per ogni ritocco. La ricognizione iniziale diventa una base da aggiornare quando cambiano i comandi o l’area su cui si lavora. Anche le [best practice di Claude Code](https://code.claude.com/docs/en/best-practices) riservano la pianificazione più articolata ai problemi che la richiedono.

Nel repository [openai-python](https://github.com/openai/openai-python/blob/main/AGENTS.md), per esempio, le istruzioni spiegano quali parti derivano dalla generazione del codice e quali comandi usare. Il file di [VS Code](https://github.com/microsoft/vscode/blob/main/.github/copilot-instructions.md) richiama i controlli del progetto e i processi di sviluppo già disponibili. Sono esempi utili per scegliere che cosa documentare; copiare i loro comandi in un altro repository creerebbe informazioni sbagliate.

La condivisione delle istruzioni richiede una scelta simile. Nel laboratorio basta l’import di `AGENTS.md`. Se il progetto genera configurazioni per più client, indica chiaramente la fonte da modificare, i file derivati e il comando reale che li rigenera; usa il controllo delle differenze previsto da quel generatore. Modificare soltanto una copia generata significa perdere la correzione alla rigenerazione successiva. Aggiungerei questo meccanismo quando esiste un problema concreto di copie divergenti, non per preparare sette file.

Tieni nelle istruzioni stabili ciò che serve quasi sempre e rimanda alle procedure specialistiche quando il task le richiede. È un criterio presente anche nei video ufficiali [Getting started with Codex](https://www.youtube.com/watch?v=px7XlbYgk7I) e [Claude Code best practices](https://www.youtube.com/watch?v=gv0WHhKelSE): comandi e mappa del progetto nelle istruzioni, dettagli e avanzamento in documenti dedicati. Il numero di righe conta meno della possibilità di trovare l’indicazione giusta.

Nel passaggio di consegne di un progetto versionato aggiungi la revisione di partenza, le modifiche locali rimaste, il comando con la sua directory e l’esito. Se il task ha creato build, log o container temporanei, registra anche cosa hai rimosso e cosa serve ancora; evita pulizie generali su dipendenze o dati condivisi. Queste informazioni cambiano con il lavoro e appartengono all’handoff.

Per la modifica sui nomi CSV una skill aggiungerebbe una procedura da mantenere a un incarico già chiaro. Ha senso introdurla quando la stessa attività si ripete e richiede passaggi propri, come una review con criteri condivisi: la guida alle [skills per Claude e Codex](https://www.matteovincenti.com/blog/ottimizzare-skills-claude-codex) entra in quel caso. Un server MCP diventa utile quando il lavoro richiede dati o azioni in un sistema esterno; qui lettura dei file e terminale sono sufficienti.

La prova finale del laboratorio è semplice: una nuova sessione trova `npm test`, ottiene sei test verdi e riconosce che resta da rivedere il diff. Nel progetto reale cerca lo stesso passaggio di consegne: un lavoro delimitato, un comando rintracciabile e uno stato che chi riprende può controllare.
