File di Istruzioni AI
Ogni assistente vuole le proprie regole in un file diverso. Claude Code legge
CLAUDE.md, Cursor legge .cursorrules, Windsurf legge .windsurfrules,
Copilot legge .github/copilot-instructions.md, e la convenzione comune tra i
vendor è AGENTS.md. Mantenere le stesse istruzioni in cinque file diversi è il
modo perfetto per far sì che quattro di essi diventino obsoleti.
rebase init scrive tutti e cinque — come puntatori a un singolo file che andrai effettivamente a modificare:
your-project/├── ai-instructions.md ← the real content├── CLAUDE.md ← pointer├── AGENTS.md ← pointer├── .cursorrules ← pointer├── .windsurfrules ← pointer└── .github/ └── copilot-instructions.md ← pointerOgni file puntatore è composto da tre righe:
# Rebase AI RulesPlease refer to and follow the instructions defined in [ai-instructions.md](./ai-instructions.md).The Rebase skills for this assistant live in `.claude/skills/`. If they are not there yet, install them, with the Rebase MCP server: `rebase skills install --agent claude --mcp`.Sulla 0.23 la terza riga si limita a dire all’assistente di eseguire
rebase skills install --agent claude, e il .mcp.json più sotto avvia il
server con npx -y @rebasepro/mcp dal registry.
Gli altri differiscono solo nella directory delle skill dell’agente e nel suo
valore --agent — --agent cursor, --agent windsurf, --agent codex,
--agent copilot — e nel percorso relativo, che è ../ai-instructions.md in
.github/copilot-instructions.md e ai-instructions.md in AGENTS.md. La
terza riga è condizionale perché rebase init --agent potrebbe aver già
installato le skill prima che l’assistente la legga.
Questo avviene a ogni rebase init, per ogni preset incluso --headless.
Non ci sono flag né richieste di conferma.
rebase init scrive anche .mcp.json, che indirizza Claude Code, Cursor e
qualsiasi altro client MCP al server MCP di Rebase — la
copia propria del progetto, una devDependency fissata insieme alla CLI
(npx --no rebase-mcp in un progetto npm):
{ "mcpServers": { "rebase": { "command": "pnpm", "args": ["exec", "rebase-mcp"], "env": { "REBASE_PROJECT_DIR": "." } } }}REBASE_PROJECT_DIR è ".", non un percorso assoluto: il client avvia il server
nella radice del progetto, e un percorso assoluto è l’unica riga di quel file che
non può essere committata. C’è perché ~/.rebase/projects.json vale per l’intera
macchina — un progetto che non nomina una directory propria ricade su ciò che vi
ha salvato l’ultimo progetto di quella macchina. Vedi
la precedenza.
Perché un puntatore invece di una copia
Sezione intitolata “Perché un puntatore invece di una copia”I file puntatore sono deliberatamente privi di contenuti. Gli assistenti seguono i link Markdown relativi, quindi un file di tre righe che fa riferimento a quello reale ottiene lo stesso risultato di una copia — offrendo al contempo vantaggi che una copia non ha:
- Un solo file da modificare. Le regole non possono divergere tra gli assistenti, perché esiste un solo set di regole.
- Un solo diff da revisionare. Una modifica alle convenzioni del progetto è una modifica a un solo file, non a cinque file identici che un revisore deve confrontare.
- Aggiungere un assistente richiede tre righe. Un nuovo strumento con un nuovo nome di file ottiene un puntatore, non una sesta copia delle tue convenzioni.
È un pattern che vale la pena mantenere se fai un fork dello scaffold, e che vale la pena adottare anche in repository che non sono affatto progetti Rebase.
Con cosa inizia ai-instructions.md
Sezione intitolata “Con cosa inizia ai-instructions.md”Il file scaffoldato è deliberatamente breve — rimanda a
rebase skills install per approfondire, poi definisce le regole che
gli assistenti sbagliano abbastanza spesso da meritare di essere ripetute all’inizio di ogni
sessione:
- Schema come codice. Le collezioni sono definite in
config/collections/. Non modificare mai a mano lo schema Drizzle generato o le tabelle Postgres — vedi Schema as Code. - Come si applica una modifica a una collection dipende dal database. Mentre
pnpm devè in esecuzione, salvare il file della collection è l’intero passo: il boot rigenera lo schema Drizzle e crea le tabelle e le colonne mancanti.pnpm db:pushserve solo per ciò che il boot lascia deliberatamente stare — una colonna rinominata, un tipo ristretto, un campo rimosso — sul database di sviluppo gestito come sul tuo PostgreSQL. In produzione la coppia èpnpm db:generatee poipnpm db:migrate. Da 0.25 Su 0.24pnpm db:pushrichiede il tuo PostgreSQL, e il file lo dice. - Usa l’SDK. Passa attraverso
rebase.dataAsAdmin.<slug>per il lavoro svolto con l’identità del servizio, oppuregetDriver(c)dentro una function quando la lettura deve avvenire come chiamante. Sul server il client non espone un accessoredatasemplice. L’SDK va sempre usato: l’SQL grezzo e le chiamate dirette a Drizzle bypassan la validazione, le callback e la RLS. - Proteggi ogni route personalizzata. Le route in
backend/functions/sono montate senza autenticazione. UsarequireAuth/requireAdminda@rebasepro/server/functionsnello slot middleware dedicato della route — leggerec.get("user")non costituisce una protezione, e non lo è nemmenoapp.use()dopo la route.
Quest’ultima è quella fondamentale da ricordare. Fa la differenza tra un middleware che viene eseguito e uno che non lo è, e un assistente a cui non è stato detto scriverà puntualmente la versione che non lo fa — vedi Funzioni personalizzate.
requireAdmin ammette solo il ruolo admin. Quando un ruolo più ristretto o una chiave API
deve poter chiamare una route, la protezione da aggiungere è requireScope, con uno scope
dichiarato dall’app — vedi Ruoli e scope.
Personalizzarlo
Sezione intitolata “Personalizzarlo”ai-instructions.md è il tuo file. Niente lo rigenera o lo sovrascrive — a differenza delle
skill installate, che vengono sostituite a ogni
rebase skills install. Le convenzioni specifiche del progetto vanno inserite qui.
Ciò che merita spazio è ciò che un assistente non può dedurre dal codice: quali collezioni sono legacy, quale servizio possiede quale tabella, la convenzione di denominazione che non è imposta da nessuna parte, la migrazione che non deve essere rieseguita. Mantienilo breve — le istruzioni caricate in ogni richiesta competono con il task effettivo per l’attenzione dell’assistente, e un file lungo viene solo scorso superficialmente.
E tieni a mente il limite: questo file determina ciò che un assistente scrive. Non ha alcuna influenza su ciò che un agente connesso al tuo database può fare — questo è determinato dalle credenziali in suo possesso, e nulla nel Markdown può cambiarlo. Vedi il modello di credenziali del server MCP.