feat(shell): yellow active session, growing composer, phase title, refined activity log, arrow panel toggle

Fix six GUI defects, verified live against the real stack:

- NavSessions: mark the in-progress (active) session in yellow (warning
  token) — both its status dot and its row background.
- SteerInput: the composer is now an auto-growing textarea that wraps and
  grows vertically (caps at 160px, then scrolls); Enter sends, Shift+Enter
  inserts a newline.
- WorkflowBar: show a synthetic title of the current phase under the 8 dots
  from static EN/IT strings (no LLM); English is displayed to match the chrome.
- CentralStatus: reformat the 5-line system-message tail as a structured,
  monospace list with per-line markers and an emphasized last line.
- AppShell + CentralStatus: move the left Model-activity panel toggle off the
  working spinner (now a pure status indicator) onto a dedicated arrow button
  (→ opens, ← closes).
- gate: rename the phase-confirm button "Conferma e prosegui" → "Salva e
  procedi" (builders.js + its L1 test).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 14:32:01 +02:00
co-authored by Claude Opus 4.8
parent 1f9818c50f
commit d6b4729ddf
8 changed files with 132 additions and 59 deletions
+15 -4
View File
@@ -11,7 +11,7 @@ import { DeleteConfirmDialog } from "./DeleteConfirmDialog";
import { StopConfirmDialog } from "./StopConfirmDialog";
import { SteerInput, ComposerFooter } from "./SteerInput";
import { WorkflowBar } from "./WorkflowBar";
import { Pencil } from "lucide-react";
import { Pencil, ArrowLeft, ArrowRight } from "lucide-react";
import { Button } from "../components/ui/button";
import { Toaster } from "../components/ui/sonner";
import { toast } from "sonner";
@@ -34,7 +34,7 @@ export function AppShell() {
const { data: sessions = [] } = useQuery<SessionSummary[]>({
queryKey: ["sessions"], queryFn: listSessions, refetchInterval: 10_000,
});
const composerRef = useRef<HTMLInputElement>(null);
const composerRef = useRef<HTMLTextAreaElement>(null);
const queryClient = useQueryClient();
const [panelSession, setPanelSession] = useState<SessionSummary | null>(null);
@@ -194,7 +194,18 @@ export function AppShell() {
{/* Conversation column */}
<div className="flex min-w-0 flex-1 flex-col">
{activeSessionId && (
<div className="shrink-0 border-b border-border/70 bg-background/80 px-6 py-2.5 backdrop-blur">
<div className="relative shrink-0 border-b border-border/70 bg-background/80 px-6 py-2.5 backdrop-blur">
{/* Arrow toggle for the left Model-activity panel: → opens it, ← closes it. */}
<button
type="button"
onClick={toggleActivity}
aria-expanded={showActivity}
aria-label={showActivity ? "Hide model activity" : "Show model activity"}
title={showActivity ? "Hide model activity" : "Show model activity"}
className="absolute left-4 top-1/2 grid size-7 -translate-y-1/2 place-items-center rounded-md border border-border text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
>
{showActivity ? <ArrowLeft className="size-4" /> : <ArrowRight className="size-4" />}
</button>
<div className="mx-auto max-w-3xl">
<WorkflowBar
finalized={finalized}
@@ -209,7 +220,7 @@ export function AppShell() {
<div className="mx-auto flex max-w-3xl flex-col gap-6">
{activeSessionId ? (
<>
<CentralStatus working={working} onOpenActivity={toggleActivity} />
<CentralStatus working={working} />
<WidgetHost sessionId={activeSessionId} />
</>
) : (