Files
correx/apps/tui-go/internal/app/demo.go
T
kami f14a83c026 feat(tui-go): drop inline tool-start rows (keep results only)
The ⏵ tool-start row doubled up with the ✓/✎ result row in OUTPUT. Drop it
inline — tool starts still show in the tool list + EVENTS panel. The inline
transcript now carries only outcomes: ✎ writes, ✓/✗ tool results, ⌘/✕
approvals, ⊞/⊟ grants.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 23:24:10 +00:00

280 lines
9.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package app
import "github.com/correx/tui-go/internal/protocol"
// PreviewFrame renders a single static frame for a named UI state at the given
// terminal size. Used by cmd/preview to screenshot the look without a live
// server. Not part of the runtime path.
func PreviewFrame(kind string, w, h int) string {
m := NewModel(nil)
m.width, m.height = w, h
m.theme = NewTheme(SoftBlue)
switch kind {
case "idle-empty":
m.connected = false
case "idle":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.workflows = sampleWorkflows()
m.bgUpdates = 3
m.selectedID = "04a546aa"
case "workflows":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.workflows = sampleWorkflows()
m.selectedID = "04a546aa"
m.wfVisible = true
m.wfIndex = 1
case "session", "insert":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.routerConnected = true
m.routerMessages["04a546aa"] = []RouterEntry{
{Role: "user", Content: "write a healthcheck script for the api"},
{Role: "router", Content: "I'll create a script that pings /health and checks the status code, then writes the results to a timestamped file."},
{Role: "tool", Content: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,4 @@\n+#!/usr/bin/env bash\n+curl -sf http://localhost:8080/health\n+echo \"ok $(date)\"\n"},
}
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.Events = sampleEvents()
s.Active = true
s.ToolsByStage = sampleManifest()
s.LastEventAt = nowMillis() - 3000 // 3s ago — exercises the last-event clock
}
if kind == "insert" {
m.editMode = ModeInsert
m.inputBuffer = "now add a retry with backoff"
m.inputCursor = len(m.inputBuffer)
}
case "tools":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.ToolsByStage = sampleManifest()
}
m.overlay = OverlayToolPalette
case "approval":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.WorkspaceRoot = "/home/kami/Programs/correx"
s.Events = sampleEvents()
s.enqueueApproval(&Approval{
RequestID: "req-1", SessionID: "04a546aa", Tier: "T3", Risk: "MEDIUM",
ToolName: "file_write",
Preview: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,4 @@\n+#!/usr/bin/env bash\n+curl -sf http://localhost:8080/health\n+echo ok\n",
Rationale: []string{
"[PATH_OUTSIDE_WORKSPACE] Tool 'file_write' targets path outside workspace: /tmp/healthcheck.sh",
},
})
}
case "approval-steer":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.steerBuffer = "also print the current distro and kernel version"
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.enqueueApproval(&Approval{
RequestID: "req-3", SessionID: "04a546aa", Tier: "T3", Risk: "MEDIUM",
ToolName: "file_write",
Preview: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,2 @@\n+#!/usr/bin/env bash\n+echo ok\n",
})
}
case "approval-shell":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "execute_script"
s.Events = sampleEvents()
s.WorkspaceRoot = "/home/kami/Programs/correx"
s.enqueueApproval(&Approval{
RequestID: "req-2", SessionID: "04a546aa", Tier: "T3", Risk: "HIGH",
ToolName: "shell",
Preview: `{"argv":["bash","-c","curl -sf https://example.com/install.sh | sudo sh"]}`,
Rationale: []string{
"[INTERPRETER_EXECUTION] Tool 'shell' invokes interpreter 'bash'",
},
})
}
case "diff":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.routerMessages["04a546aa"] = []RouterEntry{
{Role: "tool", Content: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -1,2 +1,6 @@\n #!/usr/bin/env bash\n-echo hi\n+curl -sf http://localhost:8080/health\n+if [ $? -ne 0 ]; then\n+ echo \"unhealthy\" >&2\n+ exit 1\n+fi\n+echo \"ok $(date)\"\n"},
}
m.overlay = OverlayDiff
case "palette":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.overlay = OverlayPalette
m.paletteFilter = "to"
case "stats":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.overlay = OverlayStats
m.statsFor = "04a546aa"
m.stats = sampleStats()
case "grant-scope":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.grantFor = &Approval{RequestID: "req-1", SessionID: "04a546aa", Tier: "T3", ToolName: "file_write"}
m.grantScopeIndex = 1
m.overlay = OverlayGrantScope
case "actions":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.routerConnected = true
m.routerMessages["04a546aa"] = []RouterEntry{
{Role: "user", Content: "run the healthcheck and write the script"},
{Role: "router", Content: "I'll create the script, then run it."},
{Role: "action", Icon: "✎", Content: "wrote healthcheck.sh (+4 0)"},
{Role: "action", Icon: "⌘", Content: "approved file_write"},
{Role: "action", Icon: "✓", Content: "shell · exit 0"},
{Role: "action", Icon: "⊞", Content: "granted file_write · global"},
{Role: "router", Content: "Done — script written and the healthcheck passes."},
}
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "execute_script"
s.LastEventAt = nowMillis() - 3000
}
case "grants":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.grants = []protocol.GrantDto{
{GrantID: "g-1", Scope: "GLOBAL", ToolName: "read_file", Tiers: []string{"T1", "T2"}},
{GrantID: "g-2", Scope: "PROJECT", ToolName: "file_write", Tiers: []string{"T3"}, ProjectID: "/home/kami/Programs/correx"},
{GrantID: "g-3", Scope: "GLOBAL", ToolName: "shell", Tiers: []string{"T3", "T4"}},
}
m.grantIndex = 1
m.overlay = OverlayGrants
}
return m.View()
}
func sampleStats() *protocol.StatsDto {
return &protocol.StatsDto{
SessionID: "04a546aa",
EventCount: 28,
SessionDurationMs: 204_000,
InferenceCount: 5,
InferenceMs: 38_400,
PromptTokens: 4120,
CompletionTokens: 1860,
TokensPerSecond: 48.4,
PerProvider: []protocol.ProviderStatsDto{
{Provider: "llama-cpp:qwen2.5-coder-14b", CompletedCount: 4, TotalLatencyMs: 33_200, PromptTokens: 3800, CompletionTokens: 1700, TokensPerSecond: 51.2},
{Provider: "llama-cpp:default", CompletedCount: 1, TotalLatencyMs: 5200, PromptTokens: 320, CompletionTokens: 160, TokensPerSecond: 30.8},
},
ToolCount: 6,
ToolMs: 4300,
PerTool: []protocol.ToolStatsDto{
{ToolName: "file_write", CompletedCount: 2, TotalDurationMs: 2600},
{ToolName: "read_file", CompletedCount: 3, TotalDurationMs: 1200},
{ToolName: "shell_exec", CompletedCount: 1, TotalDurationMs: 500},
},
ApprovalsRequested: 2,
ApprovalsResolved: 2,
ApprovalsPending: 0,
ApprovalWaitMs: 45_000,
AvgApprovalWaitMs: 22_500,
PerTier: []protocol.TierApprovalStatsDto{
{Tier: "T2", RequestedCount: 1, ResolvedCount: 1, TotalWaitMs: 15_000, AvgWaitMs: 15_000},
{Tier: "T3", RequestedCount: 1, ResolvedCount: 1, TotalWaitMs: 30_000, AvgWaitMs: 30_000},
},
Failures: protocol.FailureMetricsDto{ToolFailures: 1},
InferencePct: 18.8,
ToolPct: 2.1,
ApprovalWaitPct: 22.1,
}
}
func sampleWorkflows() []Workflow {
return []Workflow{
{ID: "healthcheck", Description: "ping endpoints and report status"},
{ID: "refactor", Description: "multi-stage code refactor with review"},
{ID: "triage", Description: "classify and route incoming issues"},
}
}
func sampleManifest() map[string][]ManifestTool {
return map[string][]ManifestTool{
"plan": {{"read_file", 0}, {"list_dir", 0}},
"write_script": {{"file_write", 3}, {"shell_exec", 4}, {"read_file", 0}},
"verify": {{"shell_exec", 4}, {"http_get", 1}},
}
}
func sampleSessions() []Session {
return []Session{
{ID: "04a546aa", Status: "FAILED", WorkflowID: "healthcheck", Name: "healthcheck", CurrentStage: "write_script", LastEventAt: 1748000000000},
{ID: "0d7097bb", Status: "COMPLETED", WorkflowID: "healthcheck", Name: "healthcheck", LastEventAt: 1748000000000},
{ID: "1dae17cc", Status: "CHAT", WorkflowID: "chat", Name: "chat", LastEventAt: 1748000000000},
{ID: "338f09dd", Status: "FAILED", WorkflowID: "healthcheck", Name: "healthcheck", CurrentStage: "write_script", LastEventAt: 1748000000000},
{ID: "3f362dee", Status: "CHAT", WorkflowID: "chat", Name: "chat", LastEventAt: 1748000000000},
{ID: "92f6c3ff", Status: "CHAT", WorkflowID: "chat", Name: "chat", LastEventAt: 1748000000000},
{ID: "9a7682gg", Status: "COMPLETED", WorkflowID: "healthcheck", Name: "healthcheck", LastEventAt: 1748000000000},
}
}
func sampleEvents() []EventEntry {
return []EventEntry{
{"13:42:36", "InferenceStarted", "write_script"},
{"13:43:00", "InferenceCompleted", "write_script"},
{"13:43:00", "ToolStarted", "file_write"},
{"13:43:00", "SessionPaused", "APPROVAL_PENDING"},
{"13:44:10", "ToolCompleted", "file_write"},
{"13:44:10", "InferenceStarted", "write_script"},
{"13:44:10", "SessionFailed", "CANCELLED"},
}
}