diff --git a/agentname.go b/agentname.go index bce00b4..5f95437 100644 --- a/agentname.go +++ b/agentname.go @@ -3,6 +3,8 @@ package main +import "strings" + // ---- what the running backend is called on screen ---- // // Every user-visible mention of the agent goes through here. Before this, the @@ -34,6 +36,14 @@ func agentTagline(backend string) string { return "claude on your Max plan" } +// agentDialString is the splash screen's dial-up line. Pure BBS flavour — ATDT +// was the Hayes modem command to dial — but it names the agent, so it belongs +// with the rest of the copy that does. Upper case because a 1980s board would +// have printed it that way, and because the number is a joke about the name. +func agentDialString(backend string) string { + return "ATDT 1-800-" + strings.ToUpper(agentName(backend)) + " . . ." +} + // promptPlaceholder is the empty-input hint. func promptPlaceholder(backend string) string { return "Ask " + agentName(backend) + "… (enter sends · alt+enter / ctrl+j / \\↵ for a new line)" diff --git a/agentname_test.go b/agentname_test.go index a860e17..c8f51c5 100644 --- a/agentname_test.go +++ b/agentname_test.go @@ -27,6 +27,12 @@ func TestAgentLabelsFollowTheBackend(t *testing.T) { if got := agentTagline(c.backend); !strings.Contains(got, c.want) { t.Errorf("tagline for %q = %q, want it to name %q", c.backend, got, c.want) } + // The splash dials the agent by name, in caps. It reached this test late: + // a sweep for [Cc]laude cannot match CLAUDE, so the one all-caps mention + // in the program survived two passes that were looking straight at it. + if got := agentDialString(c.backend); !strings.Contains(got, strings.ToUpper(c.want)) { + t.Errorf("dial string for %q = %q, want it to name %q", c.backend, got, strings.ToUpper(c.want)) + } } // The taglines name different plans, so one is not silently reused. if agentTagline(backendClaude) == agentTagline(backendCodex) { @@ -81,3 +87,15 @@ func TestCodexModelsFrameFillsThePicker(t *testing.T) { t.Errorf("picker rows = %+v, want the reported model", items) } } + +// The splash actually renders the dial line, so the helper cannot drift from +// what is drawn. +func TestSplashDialsTheRunningBackend(t *testing.T) { + out := stripANSI(splashScreen(90, 0, splashFinalFrame, 0, backendCodex)) + if !strings.Contains(out, "1-800-CODEX") { + t.Errorf("codex splash should dial CODEX, got:\n%s", out) + } + if strings.Contains(out, "CLAUDE") { + t.Errorf("codex splash still names claude:\n%s", out) + } +} diff --git a/asset_gen_test.go b/asset_gen_test.go index c4f3313..4e0fc01 100644 --- a/asset_gen_test.go +++ b/asset_gen_test.go @@ -80,7 +80,7 @@ func TestGenerateThemeAssets(t *testing.T) { // genSplashScreen renders the boot screen at its final reveal frame. height 0 // returns the bare content (no vertical centering), so the image is compact. func genSplashScreen() string { - return splashScreen(90, 0, splashFinalFrame, 0) + return splashScreen(90, 0, splashFinalFrame, 0, backendClaude) } // previewModel builds a real model mid-turn — a user request, a plain reply, diff --git a/splash.go b/splash.go index c061de1..40e26f6 100644 --- a/splash.go +++ b/splash.go @@ -84,7 +84,7 @@ func centerBlock(lines []string, width int, style lipgloss.Style) []string { // modem handshake, a scene divider, a SAUCE-style credit, and a logon prompt. // Sections reveal one frame at a time so the boot looks like a real modem // negotiation; the first keypress dismisses it regardless of progress. -func splashScreen(width, height, frame, logoIdx int) string { +func splashScreen(width, height, frame, logoIdx int, backend string) string { if width < 44 { width = 44 } @@ -102,7 +102,7 @@ func splashScreen(width, height, frame, logoIdx int) string { ) } if frame >= 3 { - lines = append(lines, center(cDim.Render("ATDT 1-800-CLAUDE . . ."))) + lines = append(lines, center(cDim.Render(agentDialString(backend)))) } if frame >= 4 { lines = append(lines, center(dAdd.Render("CONNECT 57600/ARQ/V.42bis/LAPM"))) diff --git a/view.go b/view.go index 465d066..e3ddc29 100644 --- a/view.go +++ b/view.go @@ -17,7 +17,7 @@ func (m model) View() string { return "starting…" } if m.splash { - return splashScreen(m.w, m.h, m.splashFrame, m.logoIdx) + return splashScreen(m.w, m.h, m.splashFrame, m.logoIdx, m.backend) } bg := m.renderBackground() // Modal overlays float on top of the live transcript via placeOverlay