3600ec6897
The plane-2 tool-call assessor records verified preconditions
("[PATH_OUTSIDE_WORKSPACE] …") and the server already ships them in
RiskSummaryDto.rationale, but the Go TUI's RiskSummaryDto had no
Rationale field — so the justification was silently dropped at decode
and the gate showed only an opaque tier.
Decode the rationale, carry it on Approval, and render it under the
header in the approval band (warn-marked, above the diff). This closes
the last deferred item of the plane-2 slice-1 plan: the assessment
surfaced to the approval UX. Golden test pins the rationale decode.
148 lines
5.1 KiB
Go
148 lines
5.1 KiB
Go
package app
|
|
|
|
// 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{
|
|
{"user", "write a healthcheck script for the api"},
|
|
{"router", "I'll create a script that pings /health and checks the status code, then writes the results to a timestamped file."},
|
|
{"tool", "--- 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()
|
|
}
|
|
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.Events = sampleEvents()
|
|
s.Pending = &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 "diff":
|
|
m.connected = true
|
|
m.currentModel = "llama-cpp:default"
|
|
m.sessions = sampleSessions()
|
|
m.selectedID = "04a546aa"
|
|
m.sessionEntered = true
|
|
m.routerMessages["04a546aa"] = []RouterEntry{
|
|
{"tool", "--- 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"
|
|
}
|
|
return m.View()
|
|
}
|
|
|
|
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"},
|
|
}
|
|
}
|