This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
diffwatch è un visualizzatore diff in tempo reale per Claude Code CLI. Intercetta le operazioni Edit/Write tramite hooks Claude Code, mostra i diff in una web UI React e permette accept/reject con rollback sul filesystem.
npm run build # esbuild → dist/ (CLI + server + hooks + UI React)
npm run dev # Build + avvia server su http://127.0.0.1:3333
npm run start # Avvia server (richiede build precedente)
# CLI
node dist/cli.js start # Avvia server + apre browser
node dist/cli.js start --port=4000 # Porta custom
node dist/cli.js start --no-open # Senza aprire browser
node dist/cli.js install # Registra hooks in ~/.claude/settings.json
node dist/cli.js uninstall # Rimuove hooks
node dist/cli.js status # Stato hooks + serverNon c'è test runner configurato. Esiste tests/security.test.ts ma nessuno script di test in package.json.
Flusso dati: Claude Code → Hooks (stdin JSON) → HTTP POST → Server → WebSocket → React UI
- PreToolUse (
src/hooks/pre-tool-use.ts): catturacontentBefore+ calcolaexpectedAfter, inviaPOST /api/snapshot - PostToolUse (
src/hooks/post-tool-use.ts): legge il file reale dopo la modifica, inviaPOST /api/applied
Gli hooks ricevono JSON via stdin (HookInput), comunicano col server via HTTP, e escono sempre con code 0 (non bloccano mai Claude Code). Porta configurabile via DIFFWATCH_PORT env var.
- Express 5 + WebSocket (
ws) su stesso httpServer, path/ws - SnapshotStore (
store.ts): store in-memoria conMap<changeId, FileSnapshot>+ indiceMap<filePath, changeId[]>. Singleton. - Ciclo di vita snapshot:
preview→applied→accepted|rejected - Rollback (
src/diff/rollback.ts): verifica che il contenuto attuale corrisponda acontentAfterprima di sovrascrivere concontentBefore(conflict detection) - Diff engine (
src/diff/engine.ts): wrapper attorno adiff.createPatch()per formato unified
| Endpoint | Chiamante | Funzione |
|---|---|---|
POST /api/snapshot |
Hook pre | Crea snapshot con before/expectedAfter |
POST /api/applied |
Hook post | Aggiorna snapshot con contenuto reale |
POST /api/rollback |
Browser | Ripristina file (verifica conflitti) |
POST /api/accept |
Browser | Marca come accettato (noop fs) |
POST /api/accept-all |
Browser | Accetta tutte le pending |
POST /api/reject-all |
Browser | Rollback LIFO di tutte le pending |
GET /api/changes |
Browser | Lista tutti gli snapshot |
SPA React 19 bundlata con esbuild (browser target es2020). Componenti: Header, FileList, DiffViewer, ActionBar, BatchActions. Hooks custom: useWebSocket (riconnessione con backoff), useChanges (stato modifiche).
esbuild produce 6 output separati:
dist/cli.js(Node ESM, banner shebang + createRequire)dist/server.js(Node ESM)dist/hooks/pre-tool-use.js,dist/hooks/post-tool-use.js(Node ESM, shebang)dist/ui/app.js(browser ESM, minificato),dist/ui/app.css
Moduli Node nativi sono external, i npm packages vengono bundlati.
Modifica ~/.claude/settings.json aggiungendo hooks PreToolUse/PostToolUse con matcher Edit|Write. La rimozione filtra per command contenente "diffwatch".
FileSnapshot: entità centrale (changeId, filePath, contentBefore, contentAfter, status, unifiedDiff)SnapshotStatus:'preview' | 'applied' | 'accepted' | 'rejected'HookInput: contratto stdin degli hooks Claude CodeWsMessage: messaggi WebSocket server→browser (discriminated union sutype)- Costanti:
DEFAULT_PORT=3333,HOOK_HTTP_TIMEOUT_MS=2000
- TypeScript strict, ESM (
"type": "module") - esbuild (no tsc emit, solo type-check con
noEmit: true) - Express 5, ws 8, diff 7, simple-git 3, open 10
- React 19 + diff2html (rendering diff nel browser)
- Node >= 20