Files
agent-wiki-ui/docs/MVP.md
T
davideandClaude Sonnet 5.5 c83d69f435 Cronologia chat: salvataggio su disco, barra laterale e ripresa all'avvio
Ogni chat è salvata come JSON in %LOCALAPPDATA%\LlmRun\chats (nome file =
id di sessione di claude). La barra laterale elenca le chat, permette di
riaprirle con --resume e di eliminarle. Il messaggio dell'utente è
salvato subito, prima della risposta, e all'avvio si riapre l'ultima
conversazione. Documentazione e roadmap aggiornate.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-08 13:49:28 +02:00

6.7 KiB
Raw Blame History

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

llmrun.exe "spiega questo progetto"

Tutti gli argomenti sono uniti in un unico prompt.

Comportamento

  1. Se non ci sono argomenti: stampa l'uso ed esce con codice 2.
  2. Avvia claude -p <prompt> (modalità non interattiva) con WorkingDirectory = AppContext.BaseDirectory.
  3. Ritrasmette stdout e stderr del processo figlio in tempo reale.
  4. Esce con lo stesso exit code di claude.
  5. Se claude non è trovato: messaggio chiaro ed exit code 127.

GUI (chat)

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

  • Barra laterale (sinistra, comprimibile): logo e nome, 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, aggiunti al DOM uno alla volta (nessun ricaricamento, nessuno sfarfallio). Le risposte sono renderizzate in markdown (Markdig, lato C#): titoli, liste, tabelle, citazioni, blocchi di codice. Sulle risposte il pulsante Copia copia il markdown; sui blocchi di codice copia il codice.
  • Schermata iniziale (chat vuota): titolo, sottotitolo e quattro suggerimenti cliccabili che precompilano il campo.
  • 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 <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 %LOCALAPPDATA%\LlmRun\chats\<guid>.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 <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.
  • 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.
  • Finestra orizzontale con proporzioni 16:10: larga il 75% dell'area utile dello schermo (max 1440px), altezza di conseguenza (max 90% dell'area utile), centrata; minimo 900x600. Su un monitor Full HD 1920x1080 risulta circa 1440x900.

Protocollo pagina ↔ C# (WebMessage JSON). Pagina→C#: {type:"send", text, model, effort}, {type:"reset"}, {type:"list"}, {type:"open", id}, {type:"delete", id}. C#→pagina: {type:"ai", html, md}, {type:"err", text}, {type:"done"}, {type:"chats", current, items:[{id,title,updated}]}, {type:"load", messages:[{role,text,html?}]} (sostituisce la conversazione mostrata).

Design (UI/UX)

Sorgente di verità per l'aspetto, derivato dalla skill ui-ux-pro-max (stile "strumento per sviluppatori": slate + accento verde).

  • Tema: segue Windows (chiaro/scuro) via prefers-color-scheme; la barra del titolo segue Application.SetColorMode(SystemColorMode.System); lo sfondo del WebView2 è impostato per evitare il lampo bianco all'avvio.
  • 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: Segoe UI Variable (corpo 15.5px, interlinea 1.65), Cascadia Code/Consolas per il codice. Nessun font web (funziona offline).
  • Forma e movimento: raggi 10–20px, ombra leggera sul composer, transizioni 150ms, comparsa dei messaggi 180ms; con prefers-reduced-motion tutto fermo.
  • Barra laterale: sfondo --muted, 272px; voce attiva con barra d'accento a sinistra; ✕ visibile solo al passaggio/focus.
  • Accessibilità: focus sempre visibile, aria-label sui pulsanti a sola icona, role=log/aria-live sulla conversazione, role=status sull'attesa, target ≥ 36px, nessuna emoji come icona.
  • Non incluso: evidenziazione sintattica del codice (richiederebbe una libreria da incorporare).

Scelte tecniche

  • .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, logging su file, test automatici, supporto Linux/macOS.

Criteri di accettazione

  • Eseguito da un'altra cartella, claude parte 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 --allowedTools o --permission-mode per l'uso non interattivo?
  • Formato output: testo semplice o --output-format stream-json?