Documentazione: creazione degli eseguibili e valori iniziali di modello ed effort
README spiega come creare gli eseguibili Windows e Linux (scripts/publish.sh o dotnet publish a mano), la dimensione, come usarli e l'avviso sul file non firmato. MVP, ADR-0002, CLAUDE.md e TESTING.md (riga VM-20) indicano che all'avvio e a ogni cambio di CLI si parte dal modello più piccolo del motore con effort low. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8b20f5224e
commit
d6f293722e
5 files changed
+35
-12
No files matched your search
@@ -16,7 +16,7 @@ agent-wiki-ui (già `LlmRun`; il nome ha un'unica sorgente, vedi [docs/README.md
|
||||
|
||||
- Build: `dotnet build` (agent-wiki-ui.csproj, `net10.0`, Avalonia)
|
||||
- GUI: `dotnet run`; CLI: `dotnet run -- "prompt"`
|
||||
- Publish single-file (uno per sistema): `dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true` e `-r linux-x64`
|
||||
- Publish single-file (uno per sistema): `scripts/publish.sh` (crea `dist/win-x64/` e `dist/linux-x64/`, `dist/` è ignorata da git), oppure a mano `dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true` e `-r linux-x64`
|
||||
- Test: non esistono ancora (pianificati, Fase 6: `dotnet test`; il piano è in docs/TESTING.md). Per verificare la GUI senza schermo si può usare `Avalonia.Headless` con `CaptureRenderedFrame()` in un progetto di prova fuori dal repo.
|
||||
|
||||
## Architettura
|
||||
@@ -24,7 +24,7 @@ agent-wiki-ui (già `LlmRun`; il nome ha un'unica sorgente, vedi [docs/README.md
|
||||
Decisioni e motivazioni negli ADR ([docs/adr/](docs/adr/)); qui solo la mappa del codice.
|
||||
|
||||
- [Program.cs](Program.cs): top-level statements. Con argomenti è la CLI (`EngineRunner.RunInherited`, motore scelto con `--engine <id>` come primo argomento, default Claude Code); senza avvia Avalonia (`App`).
|
||||
- [Core/Engine.cs](Core/Engine.cs): astrazione "motore" (ADR-0002): `Engine` (id, nome, eseguibile, modelli, effort, `BuildArgs`, `Parse`, `FetchLatestVersionAsync` per il controllo delle versioni), `ClaudeEngine`, `CodexEngine`, registro `Engines` e ricerca nel PATH (`PathSearch`). Gli elenchi modelli sono fissi, da aggiornare quando ne escono di nuovi.
|
||||
- [Core/Engine.cs](Core/Engine.cs): astrazione "motore" (ADR-0002): `Engine` (id, nome, eseguibile, modelli, effort, `BuildArgs`, `Parse`, `FetchLatestVersionAsync` per il controllo delle versioni), `ClaudeEngine`, `CodexEngine`, registro `Engines` e ricerca nel PATH (`PathSearch`). Gli elenchi modelli sono fissi, da aggiornare quando ne escono di nuovi; `DefaultModelId` indica il modello più piccolo, scelto all'avvio insieme a effort `low` (se esce un modello più piccolo, aggiornarlo).
|
||||
- [Core/EngineRunner.cs](Core/EngineRunner.cs): **unico punto di avvio dei motori** (cartella dell'exe, stdin chiuso, `ArgumentList`): CLI con output ereditato, GUI con output catturato e interpretato da `Engine.Parse`, e `RunToolAsync` per i comandi di servizio (`--version`, `update`) con tempo massimo.
|
||||
- [Core/EngineUpdater.cs](Core/EngineUpdater.cs): controllo delle versioni in sola lettura (`CheckAsync`, `IsNewer`) e aggiornamento di un CLI con il suo `update` ufficiale (ADR-0004): versione prima/dopo, esito leggibile, metodo di installazione dedotto dal percorso reale e comando manuale da suggerire (l'app lo mostra, non lo esegue).
|
||||
- [Core/ChatStore.cs](Core/ChatStore.cs): cronologia, un JSON per chat in `<LocalApplicationData>/<nome-app>/chats/<guid>.json` (nome file = id della chat, validato come Guid prima dell'uso; campi `Engine` e `SessionId` opzionali: i file vecchi sono chat di Claude Code).
|
||||
|
||||
@@ -9,7 +9,7 @@ Eseguibile C# (.NET 10, Windows e Linux) che lancia Claude Code (`claude -p`) o
|
||||
|
||||
## Uso
|
||||
|
||||
GUI (nessun argomento): finestra di chat in stile claude.ai, con la conversazione in markdown in alto e il campo messaggio in basso (`Invio` invia, `Maiusc+Invio` va a capo, "Nuova chat" azzera il contesto). Il riquadro **Impostazioni** (in alto a destra) permette di scegliere la **CLI** (Claude Code o Codex), il **modello** e l'**effort** di ragionamento ("Predefinito" = nessun flag, vale la config del motore). Le chat si salvano su disco e l'ultima si riapre all'avvio. Sempre nel riquadro, la sezione **Aggiornamenti** dice se Claude Code e Codex hanno una versione nuova (pulsante evidenziato) e li aggiorna uno alla volta.
|
||||
GUI (nessun argomento): finestra di chat in stile claude.ai, con la conversazione in markdown in alto e il campo messaggio in basso (`Invio` invia, `Maiusc+Invio` va a capo, "Nuova chat" azzera il contesto). Il riquadro **Impostazioni** (in alto a destra) permette di scegliere la **CLI** (Claude Code o Codex), il **modello** e l'**effort** di ragionamento. All'avvio, e a ogni cambio di CLI, sono scelti il modello più piccolo (Haiku 5.5 per Claude Code, GPT-5.6 Luna per Codex) ed effort `low`, per risposte rapide e economiche; "Predefinito" = nessun flag, vale la config del motore. Le chat si salvano su disco e l'ultima si riapre all'avvio. Sempre nel riquadro, la sezione **Aggiornamenti** dice se Claude Code e Codex hanno una versione nuova (pulsante evidenziato) e li aggiorna uno alla volta.
|
||||
```
|
||||
dotnet run
|
||||
```
|
||||
@@ -20,13 +20,34 @@ dotnet run -- "spiega questo progetto"
|
||||
dotnet run -- --engine codex "spiega questo progetto"
|
||||
```
|
||||
|
||||
## Publish single-file
|
||||
Un eseguibile per sistema, senza dipendenze:
|
||||
## Creare gli eseguibili (Windows e Linux)
|
||||
Ogni eseguibile è un **unico file** che include il runtime .NET: chi lo usa non deve installare nulla. Serve solo il .NET SDK 10 sulla macchina che compila, e si può compilare per l'altro sistema (da Linux/WSL si crea anche il `.exe` per Windows).
|
||||
|
||||
**Entrambi in un colpo** (Linux, WSL, macOS):
|
||||
```
|
||||
dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true
|
||||
dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true
|
||||
scripts/publish.sh
|
||||
```
|
||||
Il risultato è in `bin/Release/net10.0/<rid>/publish/` (`agent-wiki-ui.exe` o `agent-wiki-ui`, circa 48 MB). Al primo avvio le librerie native vengono estratte in una cartella temporanea.
|
||||
Risultato:
|
||||
|
||||
| Sistema | File | Dimensione |
|
||||
|---|---|---|
|
||||
| Windows x64 | `dist/win-x64/agent-wiki-ui.exe` | circa 48 MB |
|
||||
| Linux x64 | `dist/linux-x64/agent-wiki-ui` | circa 48 MB |
|
||||
|
||||
Con argomenti si sceglie il sistema: `scripts/publish.sh linux-x64`. Altri identificatori (per esempio `win-arm64`, `linux-arm64`) si possono provare allo stesso modo, ma non sono verificati.
|
||||
|
||||
**A mano** (anche da PowerShell su Windows, stessi comandi):
|
||||
```
|
||||
dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o dist/win-x64
|
||||
dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true -o dist/linux-x64
|
||||
```
|
||||
Senza `-o` il risultato è in `bin/Release/net10.0/<rid>/publish/`.
|
||||
|
||||
**Usarli**
|
||||
- Windows: doppio clic su `agent-wiki-ui.exe` per la GUI, oppure da terminale `agent-wiki-ui.exe "prompt"` per la CLI. Il file non è firmato: Windows può mostrare un avviso di sicurezza al primo avvio.
|
||||
- Linux: `chmod +x agent-wiki-ui` (se serve) e poi `./agent-wiki-ui`. La GUI richiede un desktop con X11 o XWayland.
|
||||
- Al primo avvio le librerie native (Skia, HarfBuzz) vengono estratte in una cartella temporanea: il primo avvio è un po' più lento.
|
||||
- I motori (`claude`, `codex`) devono essere installati e nel PATH dello stesso sistema: vedi [docs/INSTALL.md](docs/INSTALL.md).
|
||||
|
||||
## Piattaforme
|
||||
Windows e Linux con lo stesso codice ([ADR-0001](docs/adr/0001-gui-multipiattaforma-avalonia.md)). Motori supportati: Claude Code e Codex CLI, già installati da terminale; Antigravity CLI è pianificato: [ADR-0002](docs/adr/0002-motori-cli-claude-codex-antigravity.md).
|
||||
|
||||
+2
-2
@@ -24,9 +24,9 @@ Senza argomenti si apre una finestra Avalonia (C# + XAML, nessun HTML) in stile
|
||||
- **Conversazione**: messaggi alternati utente/Claude. Le risposte sono renderizzate in markdown: titoli, liste, tabelle, citazioni, blocchi di codice, grassetto/corsivo/barrato, codice inline, link. Il rendering è un renderer proprio ([MarkdownView.cs](../Gui/MarkdownView.cs)) che trasforma l'albero di Markdig in controlli Avalonia; l'HTML grezzo è disabilitato. Il testo è selezionabile. Sulle risposte il pulsante **Copia** copia il markdown; sui blocchi di codice copia il codice.
|
||||
- **Schermata iniziale** (chat vuota): solo logo, titolo e sottotitolo (nessun suggerimento precompilato).
|
||||
- **Composer** (in basso, scheda arrotondata): campo di testo che cresce fino a ~8 righe e pulsante Invia circolare con icona. `Invio` invia, `Maiusc+Invio` va a capo. Hint sulla tastiera sotto la scheda. Non contiene più i selettori di modello ed effort.
|
||||
- **Impostazioni** (in alto a destra, pulsante con icona a cursori, simmetrico a quello della barra laterale): aprono un riquadro a comparsa con l'interruttore **CLI** (Claude Code, Codex; un motore non installato è mostrato "non installato" e non è selezionabile; disabilitato durante l'attesa), poi **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). Si chiude con `Esc` o con un clic fuori; le scelte restano valide per i messaggi successivi (non sono ancora salvate su disco). Passati come `--model` / `--effort`; con "Predefinito" il flag viene omesso. Solo GUI.
|
||||
- **Impostazioni** (in alto a destra, pulsante con icona a cursori, simmetrico a quello della barra laterale): aprono un riquadro a comparsa con l'interruttore **CLI** (Claude Code, Codex; un motore non installato è mostrato "non installato" e non è selezionabile; disabilitato durante l'attesa), poi **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). **Valori iniziali**: il modello più piccolo del motore (Claude Code: Haiku 5.5; Codex: GPT-5.6 Luna) ed effort `low`, per risposte rapide e poco costose; sono quelli che si ritrovano all'avvio e a ogni cambio di CLI. Si chiude con `Esc` o con un clic fuori; le scelte restano valide per i messaggi successivi (non sono ancora salvate su disco). Passati come `--model` / `--effort`; con "Predefinito" il flag viene omesso. Solo GUI.
|
||||
- **Aggiornamenti** (nello stesso riquadro, sotto le impostazioni): una riga per ogni CLI installato con nome, versione e pulsante **Aggiorna**. L'app **controlla prima** se esiste una versione più recente (all'avvio, all'apertura del riquadro se l'ultimo controllo ha più di 5 minuti, e dopo ogni aggiornamento): se c'è, la riga dice "Aggiornamento disponibile: X", il pulsante è evidenziato e un puntino compare sul pulsante Impostazioni; se no, la riga dice "Aggiornato" e nulla è evidenziato; senza rete "Controllo non riuscito". Il pulsante esegue il comando ufficiale `<cli> update` e mostra l'esito sulla riga: "Aggiornato da X a Y", "Già aggiornato (X)" o l'errore con il comando manuale adatto al metodo di installazione (npm, Homebrew, WinGet, nativo). Un solo aggiornamento alla volta; i pulsanti sono disabilitati durante una risposta. Nessun aggiornamento parte da solo. Vedi [ADR-0004](adr/0004-aggiornamento-dei-cli.md).
|
||||
- **Motori** ([ADR-0002](adr/0002-motori-cli-claude-codex-antigravity.md)): una chat usa un solo motore. Cambiare **CLI** apre una nuova chat con quel motore; modello ed effort tornano a "Predefinito" e le liste dipendono dal motore (Codex: modelli GPT-5.6 Sol/Terra/Luna, stessi livelli di effort). Aprendo una chat salvata il selettore passa al motore di quella chat. L'etichetta sulle risposte, il segnaposto del composer e il messaggio d'attesa usano il nome del motore, e l'elenco chat lo indica sotto il titolo. Con Codex la sessione è letta dall'output (`thread_id`) e usata per riprendere la chat; i permessi sono di sola lettura.
|
||||
- **Motori** ([ADR-0002](adr/0002-motori-cli-claude-codex-antigravity.md)): una chat usa un solo motore. Cambiare **CLI** apre una nuova chat con quel motore; modello ed effort tornano ai valori iniziali del nuovo motore (il modello più piccolo ed effort `low`) e le liste dipendono dal motore (Codex: modelli GPT-5.6 Sol/Terra/Luna, stessi livelli di effort). Aprendo una chat salvata il selettore passa al motore di quella chat. L'etichetta sulle risposte, il segnaposto del composer e il messaggio d'attesa usano il nome del motore, e l'elenco chat lo indica sotto il titolo. Con Codex la sessione è letta dall'output (`thread_id`) e usata per riprendere la chat; i permessi sono di sola lettura.
|
||||
- **Contesto**: `claude -p --session-id <guid>` al primo messaggio, `--resume <guid>` ai successivi. "Nuova chat" svuota la vista e genera un nuovo guid.
|
||||
- **Cronologia**: dopo ogni scambio la chat è salvata in `<cartella dati>/<nome-app>/chats/<guid>.json`, dove la cartella dati è `Environment.SpecialFolder.LocalApplicationData` (`%LOCALAPPDATA%` su Windows, `~/.local/share` su Linux; vedi [Nome del progetto](README.md#nome-del-progetto)). Il file contiene guid (= id di sessione di `claude`), titolo, data, flag `started`, messaggi con ruolo e testo, motore (`Engine`) e id di sessione del motore (`SessionId`); i file senza questi campi sono chat di Claude Code. Riaprendo una chat si rimostra la conversazione e si prosegue con `--resume <guid>`, 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.
|
||||
|
||||
+2
-1
@@ -137,6 +137,7 @@ Si provano con `FakeClaude`/`FakeCodex` che rispondono a `--version` e `update`;
|
||||
| VM-08 | Durante l'attesa: Invia e Nuova chat disabilitati; aprire/eliminare è ignorato | U | `Occupato_blocca_azioni` | [ ] |
|
||||
| VM-09 | Modello: "Predefinito" ⇒ nessun flag; modello scelto ⇒ ID; "Altro ID…" ⇒ testo libero ripulito | U | `Scelta_modello` | [ ] |
|
||||
| VM-10 | Effort: "Predefinito" ⇒ nessun flag; altrimenti il valore | U | `Scelta_effort` | [ ] |
|
||||
| VM-20 | Valori iniziali: modello più piccolo del motore (Claude Code: Haiku 5.5; Codex: GPT-5.6 Luna) ed effort `low`; il primo invio passa `--model`/`--effort` (o `-m`/`-c model_reasoning_effort`) con quei valori | U | `Valori_iniziali` | [ ] |
|
||||
| VM-11 | Nuova chat: svuota la vista, nuovo guid, `started` falso, elenco aggiornato | U | `Nuova_chat` | [ ] |
|
||||
| VM-12 | Errore di I/O nel salvataggio non interrompe l'invio né cancella i messaggi | U | `Salvataggio_fallito_non_perde_chat` | [ ] |
|
||||
| VM-13 | Apertura chat: carica messaggi, `started` e id; chat inesistente ⇒ elenco ricaricato | U | `Apri_chat` | [ ] |
|
||||
@@ -211,7 +212,7 @@ Per **ogni** motore, la stessa batteria di contratto:
|
||||
| EN-08 | Impostazioni persistite e rilette | U | [ ] |
|
||||
| EN-09 | Gestione del blocco di `agy -p` con output rediretto (timeout, errore chiaro) | P | [ ] |
|
||||
| EN-10 | `Engines.Find` per id (`claude`, `codex`, sconosciuto ⇒ nullo); l'id salvato nei JSON resta stabile | U | [ ] |
|
||||
| EN-11 | Cambiare CLI nelle Impostazioni apre una nuova chat con quel motore; modello ed effort tornano a "Predefinito"; liste secondo il motore | U | [ ] |
|
||||
| EN-11 | Cambiare CLI nelle Impostazioni apre una nuova chat con quel motore; modello ed effort tornano ai valori iniziali del nuovo motore (modello più piccolo, `low`); liste secondo il motore | U | [ ] |
|
||||
| EN-12 | Motore non installato: etichetta "non installato", non selezionabile; il VM rifiuta la selezione | U/G | [ ] |
|
||||
| EN-13 | L'interruttore CLI è disabilitato durante l'attesa | U/G | [ ] |
|
||||
| EN-14 | Aprendo una chat salvata il selettore passa al motore della chat; sessione e `started` coerenti | U | [ ] |
|
||||
|
||||
@@ -17,7 +17,7 @@ L'app lancia solo `claude -p`. Si vuole usare dalla stessa chat anche **OpenAI C
|
||||
- **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` è diventato `EngineRunner` con il motore come parametro.
|
||||
- **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: interruttore **CLI** (motore attivo), modello, effort. Cambiare motore apre una nuova chat; modello ed effort tornano a "Predefinito" e le liste sono quelle del motore. La persistenza su disco delle impostazioni è rinviata. La CLI ottiene `--engine <id>` (`claude`, `codex`).
|
||||
- **Impostazioni** nella GUI: interruttore **CLI** (motore attivo), modello, effort. Cambiare motore apre una nuova chat; modello ed effort tornano ai valori iniziali del motore (il modello più piccolo ed effort `low`; "Predefinito" resta selezionabile) e le liste sono quelle del motore. La persistenza su disco delle impostazioni è rinviata. La CLI ottiene `--engine <id>` (`claude`, `codex`).
|
||||
- **Sessione**: per Claude Code l'id lo sceglie l'app; per Codex lo genera Codex e l'app lo legge dall'output (`thread_id`). Il JSON della chat ha quindi un campo `Engine` e un campo `SessionId` separato dall'id della chat (che resta il nome del file). I file scritti prima (senza questi campi) si leggono come chat di Claude Code con `SessionId` = id della chat.
|
||||
- **Autore dei messaggi**: l'etichetta sulle risposte e i segnaposto del composer usano il nome del motore della chat; l'elenco chat indica il motore.
|
||||
- **Permessi**: di default sola lettura / nessun bypass dei controlli; concedere di più è un'opzione esplicita.
|
||||
@@ -43,6 +43,7 @@ Claude Code e Codex sono verificati con prove reali (Codex 0.144.3, 2026-10-15,
|
||||
- `--` prima del prompt evita che un prompt che inizia con `-` sia letto come opzione (verificato).
|
||||
- Lo stdin va chiuso subito, come per Claude Code: altrimenti Codex stampa "Reading additional input from stdin…" e attende.
|
||||
- Il modello predefinito è quello di `~/.codex/config.toml`. Se richiede una versione più recente di Codex l'errore è chiaro (`requires a newer version of Codex`): l'app lo mostra e [INSTALL.md](../INSTALL.md) indica `codex update`.
|
||||
- Il modello più piccolo di Codex è assunto essere GPT-5.6 Luna (nome e supporto agli effort inferiori: non dichiarato da OpenAI nelle prove); da rivedere quando cambia il catalogo.
|
||||
- Il catalogo modelli di Codex è dinamico (`~/.codex/models_cache.json`); l'app ne usa uno fisso, da aggiornare, con "Predefinito" e "Altro ID…" sempre disponibili.
|
||||
|
||||
## Conseguenze
|
||||
|
||||
Reference in new issue
Block a user