Modello ed effort lasciano il composer e passano in un riquadro a comparsa aperto dal pulsante in alto a destra, simmetrico a quello della barra laterale. Il composer resta con campo di testo e pulsante Invia sulla stessa riga. Eliminati i suggerimenti della schermata iniziale. MVP.md e la matrice di TESTING.md sono aggiornati di conseguenza. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
7.5 KiB
MVP (doc-first)
Obiettivo
Eseguibile C# a riga di comando che inoltra un prompt a Claude Code (claude) lanciandolo nella directory dell'eseguibile, e ne mostra l'output.
Uso
<nome-app> "spiega questo progetto"
Tutti gli argomenti sono uniti in un unico prompt.
Comportamento
- Se non ci sono argomenti: stampa l'uso ed esce con codice 2.
- Avvia
claude -p <prompt>(modalità non interattiva) conWorkingDirectory = AppContext.BaseDirectory. - Ritrasmette stdout e stderr del processo figlio in tempo reale.
- Esce con lo stesso exit code di
claude. - Se
claudenon è trovato: messaggio chiaro ed exit code 127.
GUI (chat)
Senza argomenti si apre una finestra Avalonia (C# + XAML, nessun HTML) in stile claude.ai/ChatGPT, identica su Windows e Linux. Con argomenti resta la CLI. Decisione e motivazioni: ADR-0001.
Struttura della finestra
- Barra laterale (sinistra, comprimibile con il pulsante a tre linee): logo e nome dell'app, pulsante Nuova chat, elenco delle chat salvate (titolo = inizio del primo messaggio, data/ora dell'ultimo scambio; la chat aperta è evidenziata). Un clic su una chat la riapre; la ✕ (con conferma) la elimina. Elenco vuoto: "Nessuna chat salvata".
- 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) 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.
Invioinvia,Maiusc+Inviova 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 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
Esco 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. Il riquadro è il punto in cui in futuro compariranno le impostazioni del motore (ADR-0002). Solo GUI. - 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/sharesu Linux; vedi Nome del progetto). Il file contiene guid (= id di sessione diclaude), titolo, data, flagstarted, messaggi con ruolo e testo. Riaprendo una chat si rimostra la conversazione e si prosegue con--resume <guid>, quindiclaudericorda 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 diclaude. 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--resumenon ritrova il contesto. - La risposta compare a fine generazione (nessuno streaming); durante l'attesa un indicatore di avanzamento e Invia disabilitato. Se
claudeesce con errore, lo stderr appare come messaggio di errore. - I link
http(s)si aprono nel browser di sistema. - Finestra orizzontale con proporzioni 16:10: larga il 75% dell'area utile dello schermo (max 1440 px logici), altezza di conseguenza (max 90% dell'area utile), centrata; minimo 900x600. Su un monitor Full HD 1920x1080 risulta circa 1440x900.
Design (UI/UX)
Sorgente di verità per l'aspetto, derivato dalla skill ui-ux-pro-max (stile "strumento per sviluppatori": slate + accento verde). I token vivono come risorse di tema in Gui/App.axaml.
- Tema: segue il sistema (chiaro/scuro) tramite
RequestedThemeVariant="Default". - Token (chiaro / scuro): sfondo
#FFFFFF/#0F172A, superficie composer#FFFFFF/#1E293B, testo#0F172A/#F8FAFC, testo secondario#475569/#94A3B8, bordi#CBD5E1/#334155, accento#15803D/#22C55E, errore#B91C1C/#F87171. Contrasto testo ≥ 4.5:1. - Tipografia: font di sistema (Segoe UI Variable/Segoe UI su Windows; Inter, Ubuntu, Cantarell, Noto Sans, DejaVu Sans su Linux; corpo 15.5, titoli fino a 24), Cascadia Code/Consolas/DejaVu Sans Mono per il codice. Nessun font incorporato (funziona offline).
- Forma: raggi 10–20, bordi sottili, pulsante d'invio circolare.
- Barra laterale: sfondo
Muted, 272 px; voce attiva con barra d'accento a sinistra; ✕ per eliminare. - Accessibilità: focus visibile (il composer prende il bordo d'accento),
AutomationProperties.Namesui pulsanti a sola icona e sul campo messaggio, target ≥ 30 px, icone vettoriali (nessuna emoji). - Non incluso: evidenziazione sintattica del codice.
Scelte tecniche
Le scelte architetturali sono negli ADR. Sintesi:
- .NET 10, un solo progetto
net10.0per Windows e Linux. Avalonia (GUI), Markdig (parsing markdown). Il codice è diviso inCore/(avvio diclaude, cronologia, nome app) eGui/(finestra, ViewModel, renderer markdown);Program.cssceglie CLI o GUI. ProcessStartInfo.ArgumentListper passare il prompt (niente problemi di quoting).claudeè un eseguibile nativo (~/.local/bin): si avvia direttamente, senzacmd /c. Lo stdin è chiuso subito per evitare l'attesa di 3s di claude.- Working dir:
AppContext.BaseDirectory, non la cwd del chiamante. - L'avvio di
claudeè in un solo punto (Core/Claude.cs), usato da CLI e GUI.
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 ADR-0002), logging su file, supporto macOS. I test automatici sono pianificati: TESTING.md.
Criteri di accettazione
Ogni criterio ha test automatici nella matrice di TESTING.md (CL-04, CL-08, CL-06, CL-01).
- Eseguito da un'altra cartella,
claudeparte nella cartella dell'exe (verificabile chiedendo "pwd"). - L'output appare in streaming, non solo alla fine.
- L'exit code è propagato.
- Un prompt con virgolette e spazi arriva intatto.
Domande aperte
- Permessi: serve
--allowedToolso--permission-modeper l'uso non interattivo? - Formato output: testo semplice o
--output-format stream-json?