diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index fc649ef25..35ee094f5 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -22,6 +22,7 @@ - Fixed MCP servers that ask for more scope (`insufficient_scope`) requesting sign-in over and over. The new sign-in requested only the missing scopes, so the new token lost access the previous one had; it now keeps the granted scopes. - Fixed user messages in the transcript keeping two full-width copies of every rendered line; they keep one, with identical output. - Fixed `/login` and `/logout` labeling every OAuth sign-in, including Radius, as a subscription; only subscription-backed providers say "subscription", other OAuth sign-ins say "account". +- Fixed the startup header logo rendering with gaps in Apple Terminal; it now shows a colored "Pi" with the version instead. - Fixed deferred MCP tools that `tool_search` loaded being dropped on resume and `/reload` even when their server reconnected before the next prompt, because the session restored its tools before the MCP servers reconnected. ## [0.99.2] - 2026-09-30 diff --git a/packages/coding-agent/src/modes/interactive/components/pi-logo.ts b/packages/coding-agent/src/modes/interactive/components/pi-logo.ts index 57381d9aa..cd606a17e 100644 --- a/packages/coding-agent/src/modes/interactive/components/pi-logo.ts +++ b/packages/coding-agent/src/modes/interactive/components/pi-logo.ts @@ -1,4 +1,4 @@ -import { backgroundAnsi, foregroundAnsi, rgbColor } from "@earendil-works/pi-tui"; +import { backgroundAnsi, foregroundAnsi, isAppleTerminalSession, rgbColor } from "@earendil-works/pi-tui"; import { theme } from "../theme/theme.ts"; const CORAL = rgbColor(228, 138, 122); @@ -24,3 +24,17 @@ export function piLogoLines(): [string, string] { const bottom = `${fg(BLUE)}█▀${RESET} ${fg(YELLOW)}█${RESET}`; return [top, bottom]; } + +/** + * Whether the terminal renders the half-block logo correctly. Apple Terminal draws gaps between rows and + * misaligns the half blocks, so it gets the text wordmark instead. + */ +export function supportsPiLogo(): boolean { + return !isAppleTerminalSession(); +} + +/** Text fallback for the logo: "Pi" with the logo's coral and yellow. */ +export function piWordmark(): string { + const mode = theme.getColorMode(); + return `${foregroundAnsi(CORAL, mode)}P${RESET}${foregroundAnsi(YELLOW, mode)}i${RESET}`; +} diff --git a/packages/coding-agent/src/modes/interactive/interactive-mode.ts b/packages/coding-agent/src/modes/interactive/interactive-mode.ts index cd08f6237..158f59e5f 100644 --- a/packages/coding-agent/src/modes/interactive/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive/interactive-mode.ts @@ -158,7 +158,7 @@ import { formatAuthSelectorProviderType, OAuthSelectorComponent, } from "./components/oauth-selector.ts"; -import { piLogoLines } from "./components/pi-logo.ts"; +import { piLogoLines, piWordmark, supportsPiLogo } from "./components/pi-logo.ts"; import { playPiLogoAnimation } from "./components/pi-logo-animation.lazy.ts"; import { createLoginMenuSelector } from "./components/radius-login-selector.ts"; import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.ts"; @@ -996,8 +996,11 @@ export class InteractiveMode { if (this.shouldShowStartupHeader()) { const showDetails = this.shouldShowStartupDetails(); // Built on demand so the header follows theme changes. The logo's first line carries the version, - // its second line the first line of key hints. + // its second line the first line of key hints. Terminals that cannot render the logo get a + // "Pi vX" line instead, with the key hints below it. + const showLogo = supportsPiLogo(); const withLogo = (hints: string) => { + if (!showLogo) return `${piWordmark()} ${theme.fg("dim", `v${this.version}`)}\n${hints}`; const [top, bottom] = piLogoLines(); return `${top} ${theme.fg("dim", `v${this.version}`)}\n${bottom} ${hints}`; }; @@ -1052,7 +1055,7 @@ export class InteractiveMode { 1, 0, ); - header.onLogoClick = (column, row) => playPiLogoAnimation(this.renderer, column, row); + if (showLogo) header.onLogoClick = (column, row) => playPiLogoAnimation(this.renderer, column, row); this.builtInHeader = header; // Setup UI layout diff --git a/packages/tui/src/index.ts b/packages/tui/src/index.ts index 93fb8b727..2ca089006 100644 --- a/packages/tui/src/index.ts +++ b/packages/tui/src/index.ts @@ -108,7 +108,7 @@ export { oklabToOkhslLightness } from "./oklab.ts"; // Input buffering for batch splitting export { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from "./stdin-buffer.ts"; // Terminal interface and implementations -export { ProcessTerminal, type Terminal } from "./terminal.ts"; +export { isAppleTerminalSession, ProcessTerminal, type Terminal } from "./terminal.ts"; // Terminal colors export { parseTerminalColorSchemeReport,