From c4c1ad45204f80f39ebeb2861b8c8aaefd0e7341 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 15 Oct 2026 11:06:44 +0200 Subject: [PATCH] Documentazione: ADR su GUI Avalonia multipiattaforma e motori CLI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce docs/adr con ADR-0001 (GUI in solo C# con Avalonia per Windows e Linux) e ADR-0002 (Codex e Antigravity oltre a Claude Code), entrambi in stato Proposta. Aggiunge docs/README.md come indice unico con regole SSOT e checklist di rinomina, perché il nome del progetto non è ancora deciso. La roadmap ha la nuova Fase 5 e la Fase 4 ora contiene solo i passi, con le motivazioni spostate negli ADR. Co-Authored-By: Claude Sonnet 5.5 --- CLAUDE.md | 6 +- README.md | 4 +- docs/MVP.md | 11 +++- docs/README.md | 37 ++++++++++++ docs/ROADMAP.md | 49 +++++++-------- .../adr/0001-gui-multipiattaforma-avalonia.md | 60 +++++++++++++++++++ ...002-motori-cli-claude-codex-antigravity.md | 47 +++++++++++++++ 7 files changed, 182 insertions(+), 32 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/adr/0001-gui-multipiattaforma-avalonia.md create mode 100644 docs/adr/0002-motori-cli-claude-codex-antigravity.md diff --git a/CLAUDE.md b/CLAUDE.md index 7edc027..bd538ba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,8 +8,10 @@ LlmRun: eseguibile C# (.NET 10, Windows) che invoca Claude Code (`claude -p`) da ## Workflow doc-first (obbligatorio) -- Specifica e criteri di accettazione: [docs/MVP.md](docs/MVP.md). Fasi e stato: [docs/ROADMAP.md](docs/ROADMAP.md). Uso: [README.md](README.md). -- Ad ogni richiesta di modifica: aggiornare prima i doc interessati (MVP.md, ROADMAP.md con le spunte, README.md se cambia l'uso), poi il codice, poi questo file se cambiano comandi, design o vincoli. Nessuna modifica deve lasciare i doc disallineati. +- Specifica e criteri di accettazione: [docs/MVP.md](docs/MVP.md). Fasi e stato: [docs/ROADMAP.md](docs/ROADMAP.md). Indice dei doc e regole (SSOT, ADR): [docs/README.md](docs/README.md); una decisione architetturale si scrive solo nel suo ADR, gli altri doc la richiamano con un link. Uso: [README.md](README.md). +- Ad ogni richiesta di modifica: aggiornare prima i doc interessati (MVP.md, ROADMAP.md con le spunte, README.md se cambia l'uso; un nuovo ADR in `docs/adr/` per ogni scelta architetturale), poi il codice, poi questo file se cambiano comandi, design o vincoli. Nessuna modifica deve lasciare i doc disallineati. + +> In corso: migrazione a GUI Avalonia multipiattaforma ([ADR-0001](docs/adr/0001-gui-multipiattaforma-avalonia.md), ROADMAP Fase 5). Finché non è conclusa, le sezioni sotto descrivono lo stato attuale (WinForms + WebView2). ## Comandi diff --git a/README.md b/README.md index 95f9c81..67d60a2 100644 --- a/README.md +++ b/README.md @@ -32,4 +32,6 @@ bin\Debug\net10.0-windows\LlmRun.exe dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true ``` -Documentazione: [docs/MVP.md](docs/MVP.md), [docs/ROADMAP.md](docs/ROADMAP.md). +> **Piattaforme**: oggi solo Windows. È pianificato un eseguibile standalone per Windows e Linux con GUI in solo C# (Avalonia): vedi [ADR-0001](docs/adr/0001-gui-multipiattaforma-avalonia.md). La CLI è già portabile, la GUI attuale no. Pianificato anche l'uso di Codex CLI e Antigravity CLI già installati da terminale, oltre a Claude Code: [ADR-0002](docs/adr/0002-motori-cli-claude-codex-antigravity.md). + +Documentazione: [docs/MVP.md](docs/MVP.md), [docs/ROADMAP.md](docs/ROADMAP.md), [indice e decisioni architetturali](docs/README.md). diff --git a/docs/MVP.md b/docs/MVP.md index a89e052..2e0dcfb 100644 --- a/docs/MVP.md +++ b/docs/MVP.md @@ -5,7 +5,7 @@ Eseguibile C# a riga di comando che inoltra un prompt a Claude Code (`claude`) l ## Uso ``` -llmrun.exe "spiega questo progetto" + "spiega questo progetto" ``` Tutti gli argomenti sono uniti in un unico prompt. @@ -17,6 +17,8 @@ Tutti gli argomenti sono uniti in un unico prompt. 5. Se `claude` non è trovato: messaggio chiaro ed exit code 127. ## GUI (chat) +> **Stato**: questa sezione descrive la GUI attuale (WinForms + WebView2 + `ui.html`, solo Windows). La destinazione è una GUI Avalonia in solo C# per Windows e Linux: vedi [ADR-0001](adr/0001-gui-multipiattaforma-avalonia.md) e [ROADMAP.md](ROADMAP.md), Fase 5. Il comportamento funzionale (chat, sessioni, cronologia, selettori) resta valido; cambiano tecnologia, protocollo pagina↔C# e percorso della cronologia. + Senza argomenti si apre una finestra WinForms che contiene solo un WebView2: l'intera interfaccia (header, conversazione, composer) è HTML/CSS in `ui.html`, in stile claude.ai/ChatGPT. Con argomenti resta la CLI. **Struttura della pagina** @@ -26,7 +28,7 @@ Senza argomenti si apre una finestra WinForms che contiene solo un WebView2: l'i - **Composer** (in basso, scheda arrotondata): textarea che cresce fino a ~8 righe, selettori **Modello** (Predefinito, Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 5.5, "Altro ID…" con campo libero) ed **Effort** (Predefinito, low, medium, high, xhigh, max), pulsante Invia circolare con icona. `Invio` invia, `Maiusc+Invio` va a capo. Hint sulla tastiera sotto la scheda. - Passati come `--model` / `--effort`; con "Predefinito" il flag viene omesso. Solo GUI. - **Contesto**: `claude -p --session-id ` al primo messaggio, `--resume ` ai successivi. "Nuova chat" svuota la vista e genera un nuovo guid. -- **Cronologia**: dopo ogni scambio la chat è salvata in `%LOCALAPPDATA%\LlmRun\chats\.json` (guid = id di sessione di `claude`, titolo, data, flag `started`, messaggi con ruolo e testo). Riaprendo una chat si rimostra la conversazione e si prosegue con `--resume `, quindi `claude` ricorda il contesto. Il messaggio dell'utente viene salvato subito, prima della risposta (così non si perde se l'app si chiude mentre Claude risponde); la risposta si aggiunge appena arriva. Una chat nuova e vuota non viene salvata. **All'avvio l'app riapre automaticamente l'ultima conversazione** (la più recente); se non ce ne sono parte con la schermata iniziale. "Nuova chat" resta sempre disponibile. Eliminare una chat cancella solo il file JSON, non la sessione di `claude`. Non si può aprire/eliminare una chat mentre Claude sta rispondendo. +- **Cronologia**: dopo ogni scambio la chat è salvata in `\\chats\.json` (oggi `%LOCALAPPDATA%`; vedi [Nome del progetto](README.md#nome-del-progetto)) (guid = id di sessione di `claude`, titolo, data, flag `started`, messaggi con ruolo e testo). Riaprendo una chat si rimostra la conversazione e si prosegue con `--resume `, quindi `claude` ricorda il contesto. Il messaggio dell'utente viene salvato subito, prima della risposta (così non si perde se l'app si chiude mentre Claude risponde); la risposta si aggiunge appena arriva. Una chat nuova e vuota non viene salvata. **All'avvio l'app riapre automaticamente l'ultima conversazione** (la più recente); se non ce ne sono parte con la schermata iniziale. "Nuova chat" resta sempre disponibile. Eliminare una chat cancella solo il file JSON, non la sessione di `claude`. Non si può aprire/eliminare una chat mentre Claude sta rispondendo. - **Limite noto**: la sessione di `claude` è legata alla cartella in cui gira (quella dell'exe): se si sposta l'exe, le vecchie chat si leggono ancora ma `--resume` non ritrova il contesto. - La risposta compare a fine generazione (nessuno streaming); durante l'attesa un indicatore a puntini animati e Invia disabilitato. Se `claude` esce con errore, lo stderr appare come messaggio di errore. - I link si aprono nel browser di sistema. L'HTML grezzo nel markdown è disabilitato. @@ -45,13 +47,15 @@ Sorgente di verità per l'aspetto, derivato dalla skill `ui-ux-pro-max` (stile " - **Non incluso**: evidenziazione sintattica del codice (richiederebbe una libreria da incorporare). ## Scelte tecniche +Le scelte architetturali sono negli [ADR](README.md#indice-adr). Quanto segue descrive lo stato attuale. + - .NET 10 (WinForms). `Program.cs` (CLI + avvio) e `Gui.cs` (chat). Dipendenze NuGet solo per la GUI: `Markdig` (markdown→HTML) e `Microsoft.Web.WebView2` (richiede il runtime WebView2, già presente su Windows 11). - `ProcessStartInfo.ArgumentList` per passare il prompt (niente problemi di quoting). - `claude` è un .exe nativo (`~/.local/bin`): si avvia direttamente, senza `cmd /c`. Lo stdin è chiuso subito per evitare l'attesa di 3s di claude. - Working dir: `AppContext.BaseDirectory`, non la cwd del chiamante. ## Fuori scope (MVP) -Streaming token-per-token nella GUI, annullamento di una risposta in corso, rinomina/ricerca delle chat, config file, altri motori oltre a Claude Code (Codex, Antigravity: vedi [ROADMAP.md](ROADMAP.md), Fase 4), logging su file, test automatici, supporto Linux/macOS. +Streaming token-per-token nella GUI, annullamento di una risposta in corso, rinomina/ricerca delle chat, config file, altri motori oltre a Claude Code (Codex, Antigravity: vedi [ADR-0002](adr/0002-motori-cli-claude-codex-antigravity.md)), logging su file, test automatici, supporto macOS. Il supporto Linux è pianificato: [ADR-0001](adr/0001-gui-multipiattaforma-avalonia.md), Fase 5. ## Criteri di accettazione - [ ] Eseguito da un'altra cartella, `claude` parte nella cartella dell'exe (verificabile chiedendo "pwd"). @@ -60,5 +64,6 @@ Streaming token-per-token nella GUI, annullamento di una risposta in corso, rino - [ ] Un prompt con virgolette e spazi arriva intatto. ## Domande aperte +- Nome definitivo del progetto (oggi provvisorio: vedi [Nome del progetto](README.md#nome-del-progetto)). - Permessi: serve `--allowedTools` o `--permission-mode` per l'uso non interattivo? - Formato output: testo semplice o `--output-format stream-json`? diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b6d7c8e --- /dev/null +++ b/docs/README.md @@ -0,0 +1,37 @@ +# Documentazione + +Indice e regole. Ogni informazione vive in **un solo documento**; gli altri la richiamano con un link. + +| Documento | Contenuto (sorgente di verità per…) | +|---|---| +| [../README.md](../README.md) | Uso, requisiti, build e publish | +| [MVP.md](MVP.md) | Specifica funzionale, design UI/UX, criteri di accettazione | +| [ROADMAP.md](ROADMAP.md) | Fasi e stato (spunte); solo passi, mai motivazioni | +| `adr/NNNN-*.md` | Decisioni architetturali e loro motivazioni (indice sotto) | +| [../CLAUDE.md](../CLAUDE.md) | Guida per Claude Code: comandi, architettura del codice, vincoli | + +## Nome del progetto +Il nome è **provvisorio** (oggi `LlmRun`) e non è ancora deciso. Questa sezione è l'unica sorgente: gli altri doc scrivono "l'app" o ``. + +Se il nome cambia, aggiornare solo questi punti: +- [ ] `AssemblyName`/nome del csproj e dell'eseguibile (`.exe`, ``) +- [ ] Costante del nome nel codice (titolo finestra, intestazione della barra laterale, cartella dati) +- [ ] **Cartella dati** `//chats`: cambiando nome le chat salvate non si trovano più; migrare o leggere anche la vecchia cartella +- [ ] Titolo di [../README.md](../README.md) e riga iniziale di [../CLAUDE.md](../CLAUDE.md) (nome del csproj nei comandi) + +## Flusso (doc-first, doc-as-code) +1. Prima i doc, poi il codice: ADR (se c'è una scelta architetturale) → MVP → ROADMAP → README → codice → CLAUDE.md. +2. I doc stanno nel repo e cambiano con lo stesso commit del codice a cui si riferiscono. +3. Una modifica non deve lasciare i doc disallineati. + +## Regole degli ADR +- Un file per decisione, `adr/NNNN-titolo-breve.md`, numerazione progressiva. +- Stati: `Proposta` → `Accettata` → eventualmente `Sostituita da ADR-NNNN` o `Rifiutata`. +- Un ADR accettato non si riscrive: se la decisione cambia se ne scrive uno nuovo che lo sostituisce e si aggiorna lo stato del vecchio. +- Sezioni: Contesto, Criteri, Opzioni, Decisione, Conseguenze, Da verificare, Riferimenti. + +## Indice ADR +| ADR | Titolo | Stato | +|---|---|---| +| [0001](adr/0001-gui-multipiattaforma-avalonia.md) | GUI multipiattaforma in solo C# con Avalonia | Proposta | +| [0002](adr/0002-motori-cli-claude-codex-antigravity.md) | Più motori CLI (Claude Code, Codex, Antigravity) su Windows e Linux | Proposta | diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 70ca0a6..3fea131 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -26,32 +26,29 @@ Dettagli dell'MVP in [MVP.md](MVP.md). - [ ] Test automatici e CI ## Fase 4 — Più motori (Claude Code, Codex, Antigravity) -Obiettivo: oltre a Claude Code, usare **OpenAI Codex CLI** e **Antigravity CLI** (`agy`) dalla stessa chat, scegliendo il motore da una nuova schermata **Impostazioni** della GUI. +Decisione, tabella dei comandi e rischi: [ADR-0002](adr/0002-motori-cli-claude-codex-antigravity.md). Qui solo i passi. Va fatta dopo (o insieme a) la Fase 5, che estrae il punto unico di avvio processo. -Flag delle tre CLI (da verificare con `--help` delle versioni installate: derivano da documentazione e ricerche, non da prove su questo PC, dove `codex` e `agy` non sono ancora installati): +- [ ] Verificare con `--help` i flag reali di `codex` e `agy` su Windows e Linux (ADR-0002) e portare l'ADR a "Accettata" +- [ ] Astrazione "motore" in C#: `RunClaude` diventa `RunEngine(engine, ...)` +- [ ] Rilevamento dei motori nel PATH; motori assenti disabilitati, messaggio chiaro +- [ ] Il JSON di ogni chat memorizza il motore; cambiare motore apre una nuova chat +- [ ] GUI: schermata Impostazioni (motore, modello, effort) persistita su disco; modelli ed effort in base al motore; motore della chat indicato nell'interfaccia +- [ ] Motore Codex: lettura dell'id di sessione dall'output per la ripresa +- [ ] Motore Antigravity: gestione del blocco con output rediretto (timeout, errore chiaro) +- [ ] Politica dei permessi: sola lettura di default, opzione esplicita per concedere di più +- [ ] CLI: opzione `--engine`, coerente con la GUI -| | Claude Code | Codex CLI | Antigravity CLI | -|---|---|---|---| -| Comando | `claude -p ` | `codex exec ` | `agy -p ` | -| Continuare | `--session-id ` poi `--resume ` | `codex exec resume ` | da verificare | -| Modello | `--model` | `-m` / `--model` | da verificare | -| Effort | `--effort` | via `--config` (da verificare) | non noto | +## Fase 5 — Multipiattaforma (Windows + Linux), GUI in solo C# +Decisione e motivazioni: [ADR-0001](adr/0001-gui-multipiattaforma-avalonia.md). Qui solo i passi. -**Architettura** -- [ ] Un'astrazione "motore" in C#: per ogni motore, eseguibile, argomenti per primo messaggio e per ripresa, elenco modelli, supporto effort, lettura dell'id di sessione. `RunClaude` diventa `RunEngine(engine, ...)`; la logica di avvio (cartella dell'exe, stdin chiuso) resta in un solo punto, eliminando la duplicazione CLI/GUI. -- [ ] Rilevamento dei motori installati (PATH) e messaggio chiaro se mancano; i motori assenti sono disabilitati nelle Impostazioni. -- [ ] Il file JSON di ogni chat memorizza il **motore**; riaprendo una chat si usa il suo motore. Il contesto di sessione non passa da un motore all'altro: cambiare motore apre una nuova chat. - -**GUI: Impostazioni** -- [ ] Schermata/pannello Impostazioni (icona nella barra laterale) con selettore del **motore** attivo. -- [ ] Il selettore Modello mostra solo i modelli del motore scelto; Effort compare solo se il motore lo supporta. -- [ ] Impostazioni persistite su disco (motore, modello, effort), così si ritrovano alla riapertura. Si lega al "config file" della Fase 3. -- [ ] Il motore della chat aperta è indicato nell'interfaccia (etichetta sull'intestazione o sulla voce in elenco). - -**Rischi e punti da verificare** -- [ ] **Codex**: l'id di sessione non lo sceglie l'app (lo genera Codex): va letto dall'output (probabilmente con l'output JSON) per poter riprendere la chat. -- [ ] **Antigravity**: segnalato un blocco di `agy -p` quando lanciato da sottoprocesso con output rediretto su Windows ([issue #318](https://github.com/google-antigravity/antigravity-cli/issues/318)); provare con un timeout (`--print-timeout`) e prevedere un messaggio d'errore. I flag vanno messi prima di `-p`. -- [ ] **Permessi**: Codex e Antigravity chiedono conferma per le azioni; in modalità non interattiva serve decidere una politica (sola lettura di default, opzione esplicita per concedere di più) invece di usare flag che saltano ogni controllo. -- [ ] Formato dell'output di ciascun motore (testo semplice o JSON) e normalizzazione prima del rendering markdown. -- [ ] Autenticazione: ogni CLI deve essere già autenticata; l'app non gestisce login. -- [ ] CLI (`LlmRun "prompt"`): opzione `--engine`, coerente con la GUI. +- [ ] Chiudere le verifiche dell'ADR-0001 con un prototipo e portarlo a "Accettata" +- [ ] Nome dell'app in un solo punto del codice (costante usata per titolo finestra, cartella dati; `AssemblyName` nel csproj), così la rinomina segue la checklist di docs/README.md +- [ ] Target `net10.0` (non più `net10.0-windows`); rimuovere WinForms e WebView2 +- [ ] Estrarre in un solo punto la logica di avvio di `claude` (cartella dell'exe, stdin chiuso), oggi duplicata tra `Program.cs` e `Gui.cs` +- [ ] Cronologia in `Environment.SpecialFolder.LocalApplicationData` (stesso formato JSON, chat esistenti ancora leggibili) +- [ ] GUI Avalonia: finestra, barra laterale delle chat, conversazione, composer con modello ed effort +- [ ] Rendering markdown in Avalonia (titoli, liste, tabelle, citazioni, codice), pulsante Copia, link nel browser di sistema +- [ ] Tema chiaro/scuro che segue il sistema, con i token di MVP.md → "Design (UI/UX)" +- [ ] Eliminare `ui.html` e il protocollo `WebMessage` +- [ ] Publish single-file self-contained `win-x64` e `linux-x64`, provati su entrambi i sistemi +- [ ] Aggiornare README.md e CLAUDE.md (comandi, architettura, vincoli) a migrazione conclusa diff --git a/docs/adr/0001-gui-multipiattaforma-avalonia.md b/docs/adr/0001-gui-multipiattaforma-avalonia.md new file mode 100644 index 0000000..7700fa2 --- /dev/null +++ b/docs/adr/0001-gui-multipiattaforma-avalonia.md @@ -0,0 +1,60 @@ +# ADR-0001 — GUI multipiattaforma in solo C# con Avalonia + +- **Stato**: Proposta +- **Data**: 2026-10-15 +- **Sostituisce**: la parte "GUI WinForms + WebView2 + `ui.html`" di [MVP.md](../MVP.md) (le sezioni interessate rimandano a questo ADR) + +## Contesto +L'app nasce per Windows: GUI WinForms con un solo WebView2 che carica `ui.html` (HTML/CSS/JS), CLI in `Program.cs`. L'obiettivo ora è avere **un eseguibile standalone per Windows e Linux** nel modo più semplice, **scritto interamente in C#, senza HTML**. + +Oggi non è possibile: WinForms e WebView2 sono solo Windows, il csproj punta a `net10.0-windows`, la cronologia usa `%LOCALAPPDATA%`. La CLI invece è già portabile. + +## Criteri di decisione +1. Un solo codice sorgente, compilabile per `win-x64` e `linux-x64`. +2. Standalone: publish single-file self-contained, senza runtime né librerie da installare oltre a quanto offre un normale desktop. +3. Solo C# (e XAML per il layout): niente HTML/CSS/JS. +4. Mantenere la GUI a finestra (chat con barra laterale, markdown, selettori modello/effort). +5. Riuso massimo della logica esistente (`claude -p`, sessioni, cronologia JSON, Markdig). + +## Opzioni considerate +| Opzione | Esito | Motivo | +|---|---|---| +| Mantenere WinForms + WebView2 | Scartata | Solo Windows, e richiede HTML. | +| Photino / WebView nativa | Scartata | Richiede HTML e, su Linux, webkit2gtk da installare: non standalone. | +| Server HTTP locale (Kestrel) + browser | Scartata | Portabile e semplice, ma la UI resta HTML e non è una finestra propria. | +| MAUI | Scartata | Nessun supporto desktop Linux ufficiale. | +| Terminal.Gui (TUI) | Alternativa | Puro C#, binario leggero, ma è un'interfaccia da terminale, non una finestra. | +| **Avalonia UI** | **Scelta** | GUI nativa, C# + XAML, render Skia, Windows e Linux, publish single-file self-contained. | + +## Decisione +La GUI viene riscritta con **Avalonia UI**: +- Layout in XAML, logica in C# con `ViewModel` e binding. `ui.html`, il protocollo `WebMessage` e le dipendenze WinForms/WebView2 spariscono. +- Rendering markdown con una libreria Avalonia basata su Markdig, al posto della conversione in HTML. I link `http(s)` si aprono nel browser di sistema. +- Un solo progetto con target `net10.0` (non più `net10.0-windows`). Due publish single-file self-contained: `win-x64` e `linux-x64`. +- La CLI (`Program.cs` con argomenti) resta com'è e funziona su entrambi i sistemi. +- La cronologia usa `Environment.SpecialFolder.LocalApplicationData` (`%LOCALAPPDATA%` su Windows, `~/.local/share` su Linux), sottocartella `/chats`. Il nome viene da un'unica costante (vedi [Nome del progetto](../README.md#nome-del-progetto)). +- La logica di avvio del processo (cartella dell'exe, stdin chiuso, `ArgumentList`) viene estratta in **un solo punto** condiviso da CLI e GUI, eliminando la duplicazione oggi segnalata in `CLAUDE.md`. Si lega all'astrazione "motore" di [ADR-0002](0002-motori-cli-claude-codex-antigravity.md). +- L'aspetto (token di colore, tipografia, accessibilità) resta definito in [MVP.md](../MVP.md) → "Design (UI/UX)", tradotto in risorse/stili Avalonia. Il tema segue il sistema (chiaro/scuro) tramite `ThemeVariant`. + +## Conseguenze +**Positive** +- Un solo eseguibile per sistema, senza dipendenze di runtime. +- Nessun HTML/JS da mantenere; il vincolo STA di WinForms/WebView2 non c'è più. +- Pulizia della duplicazione CLI/GUI. + +**Negative / costi** +- Riscrittura della sola parte GUI (`Gui.cs` + `ui.html`), più ampia di una soluzione basata sul browser. +- Eseguibile più pesante (include Avalonia/Skia). +- Perdita di alcune comodità del web: la resa del markdown (tabelle, blocchi di codice, pulsante Copia) dipende dalla libreria scelta e va riprodotta o adattata. +- Su Linux serve un desktop con X11 o XWayland e le librerie di base (fontconfig ecc.). + +## Da verificare (prima di passare a "Accettata") +- [ ] La libreria markdown per Avalonia scelta è compatibile con la versione di Avalonia usata e con `net10.0`, e rende tabelle, citazioni e blocchi di codice in modo accettabile. +- [ ] Il publish single-file `linux-x64` parte su una distribuzione pulita (nessuna libreria nativa mancante oltre a quelle di desktop). +- [ ] `claude` viene trovato nel PATH su Linux e la CLI mantiene exit code e codice 127. +- [ ] Il tema chiaro/scuro segue il sistema anche su Linux. +- [ ] Le chat esistenti restano leggibili (stesso formato JSON). Se il nome cambia cambia anche la cartella dati: prevedere la migrazione della vecchia cartella. + +## Riferimenti +- Piano di lavoro: [ROADMAP.md](../ROADMAP.md), Fase 5. +- Specifica funzionale della chat: [MVP.md](../MVP.md). diff --git a/docs/adr/0002-motori-cli-claude-codex-antigravity.md b/docs/adr/0002-motori-cli-claude-codex-antigravity.md new file mode 100644 index 0000000..7c6c028 --- /dev/null +++ b/docs/adr/0002-motori-cli-claude-codex-antigravity.md @@ -0,0 +1,47 @@ +# ADR-0002 — Più motori CLI (Claude Code, Codex, Antigravity) su Windows e Linux + +- **Stato**: Proposta +- **Data**: 2026-10-15 +- **Collegato a**: [ADR-0001](0001-gui-multipiattaforma-avalonia.md) (GUI e piattaforme) + +## Contesto +L'app lancia solo `claude -p`. Si vuole usare dalla stessa chat anche **OpenAI Codex CLI** e **Antigravity CLI** (`agy`), così come `claude` già installati da terminale dall'utente, su Windows e Linux. L'app non li installa e non gestisce login: sono programmi esterni, autenticati a parte. + +## Criteri di decisione +1. Aggiungere un motore costa una definizione dichiarativa, non nuova logica sparsa. +2. Funziona uguale su Windows e Linux: i motori si trovano nel PATH come da terminale. +3. Un solo punto di avvio processo (cartella dell'exe, stdin chiuso, `ArgumentList`), condiviso da CLI e GUI. +4. Nessuna scorciatoia che disattivi i controlli di permesso senza una scelta esplicita dell'utente. + +## Decisione +- **Astrazione "motore"** in C#. Ogni motore descrive: nome e eseguibile, argomenti per il primo messaggio e per la ripresa, elenco modelli, supporto effort, modo per ottenere l'id di sessione. `RunClaude` diventa `RunEngine(engine, …)`. +- **Rilevamento** dei motori cercando l'eseguibile nel PATH (su Windows anche le estensioni di PATHEXT). I motori assenti sono disabilitati nelle Impostazioni, con messaggio chiaro; la CLI esce con 127 come oggi. +- **Una chat = un motore**. Il file JSON della chat memorizza il motore; il contesto di sessione non passa da un motore all'altro, quindi cambiare motore apre una nuova chat. +- **Impostazioni** nella GUI: motore attivo, modello, effort (solo se supportato), persistite su disco accanto alla cronologia. La CLI ottiene `--engine`. +- **Permessi**: di default sola lettura / nessun bypass dei controlli; concedere di più è un'opzione esplicita. +- **Output**: ogni motore ha un parser che lo normalizza in testo markdown prima del rendering. + +## Comandi dei motori +Da verificare con `--help` delle versioni installate: derivano da documentazione e ricerche, non da prove su questo PC, dove `codex` e `agy` non sono installati. + +| | Claude Code | Codex CLI | Antigravity CLI | +|---|---|---|---| +| Comando | `claude -p ` | `codex exec ` | `agy -p ` | +| Continuare | `--session-id ` poi `--resume ` | `codex exec resume ` | da verificare | +| Modello | `--model` | `-m` / `--model` | da verificare | +| Effort | `--effort` | via `--config` (da verificare) | non noto | + +## Conseguenze +**Positive**: un solo flusso di avvio; nuovi motori aggiungibili con una definizione; elimina la duplicazione CLI/GUI. +**Negative**: i flag delle CLI cambiano nel tempo e vanno mantenuti; le sessioni non si trasferiscono tra motori; più superficie da testare su due sistemi operativi. + +## Rischi e da verificare +- [ ] **Codex**: l'id di sessione lo genera Codex e non l'app; va letto dall'output (probabilmente con output JSON) per riprendere la chat. +- [ ] **Antigravity**: segnalato un blocco di `agy -p` da sottoprocesso con output rediretto su Windows ([issue #318](https://github.com/google-antigravity/antigravity-cli/issues/318)). Provare con `--print-timeout` e prevedere un messaggio d'errore. I flag vanno messi prima di `-p`. Da provare anche su Linux. +- [ ] **Forma dell'eseguibile**: `claude` è un .exe nativo avviabile direttamente; Codex e Antigravity, se installati con un gestore di pacchetti (es. npm), su Windows possono essere script `.cmd` che richiedono `cmd.exe /c`. Su Linux sono normali eseguibili o script con shebang. Verificare e gestire per motore. +- [ ] Autenticazione: ogni CLI deve essere già autenticata; l'app mostra l'errore del motore senza gestire login. +- [ ] Formato dell'output (testo o JSON) e normalizzazione per ciascun motore. +- [ ] Mappatura effort e modelli per motore, con elenco modelli aggiornabile. + +## Riferimenti +- Passi: [ROADMAP.md](../ROADMAP.md), Fase 4.