From ee8b4ec252b61c85d5f9fe138d1926299e587fe1 Mon Sep 17 00:00:00 2001 From: can1357 Date: Sun, 3 May 2026 04:59:43 +0200 Subject: [PATCH] fix(coding-agent): adjusted status-line session accent handling for border gaps - Status-line rendering now treats `statusLine.sessionAccent` as disabled only when explicitly set to false. - Updated status-line overflow tests to assert gap colors use session accent when enabled and theme border when disabled. - Test teardown now restores `WSL_INTEROP` and `WSL_DISTRO_NAME` environment variables after mutation. --- .../src/modes/interactive-mode.ts | 6 ++--- .../test/status-line-overflow.test.ts | 25 ++++++++++++++++--- packages/tui/test/terminal-appearance.test.ts | 14 +++++++++-- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/coding-agent/src/modes/interactive-mode.ts b/packages/coding-agent/src/modes/interactive-mode.ts index 9d21488a1..a1731eb9d 100644 --- a/packages/coding-agent/src/modes/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive-mode.ts @@ -644,10 +644,8 @@ export class InteractiveMode implements InteractiveModeContext { } else if (this.isPythonMode) { this.editor.borderColor = theme.getPythonModeBorderColor(); } else { - const sessionName = - !isSettingsInitialized() || settings.get("statusLine.sessionAccent") - ? this.sessionManager.getSessionName() - : undefined; + const accentEnabled = !isSettingsInitialized() || settings.get("statusLine.sessionAccent") !== false; + const sessionName = accentEnabled ? this.sessionManager.getSessionName() : undefined; const hex = sessionName ? getSessionAccentHex(sessionName) : undefined; const ansi = getSessionAccentAnsi(hex); if (ansi) { diff --git a/packages/coding-agent/test/status-line-overflow.test.ts b/packages/coding-agent/test/status-line-overflow.test.ts index c77ca09de..33ee912ad 100644 --- a/packages/coding-agent/test/status-line-overflow.test.ts +++ b/packages/coding-agent/test/status-line-overflow.test.ts @@ -10,6 +10,7 @@ import { StatusLineComponent } from "../src/modes/components/status-line"; import type { SegmentContext } from "../src/modes/components/status-line/segments"; import { renderSegment } from "../src/modes/components/status-line/segments"; import { initTheme, theme } from "../src/modes/theme/theme"; +import { getSessionAccentAnsi, getSessionAccentHex } from "../src/utils/session-color"; const originalProjectDir = getProjectDir(); @@ -87,19 +88,35 @@ function createStatusLineSession(sessionName: string) { } describe("status line session accent", () => { - it("uses theme border color for the gap when session accent is disabled", () => { + function buildComponent(sessionAccent: boolean) { const component = new StatusLineComponent(createStatusLineSession("Named session")); component.updateSettings({ preset: "custom", leftSegments: ["pi"], rightSegments: ["session_name"], separator: "powerline-thin", - sessionAccent: false, + sessionAccent, }); + return component; + } - const border = component.getTopBorder(80).content; + const accentAnsi = getSessionAccentAnsi(getSessionAccentHex("Named session")); + + it("paints the gap with the session accent when enabled", () => { + expect(accentAnsi).toBeDefined(); + const border = buildComponent(true).getTopBorder(80).content; + expect(border).toContain(`${accentAnsi}${theme.boxRound.horizontal}`); + }); + + it("paints the gap with the border color and omits the session accent when disabled", () => { + expect(accentAnsi).toBeDefined(); + const border = buildComponent(false).getTopBorder(80).content; + // Positive: gap is rendered with the theme border color. expect(border).toContain(`${theme.getFgAnsi("border")}${theme.boxRound.horizontal}`); - expect(border).toContain("Named session"); + // Negative: the gap-painting pattern (accent ANSI directly followed by a horizontal + // glyph) must not appear. The session_name segment may still emit the accent ANSI + // for its own text — we only care that the gap is not accent-painted. + expect(border).not.toContain(`${accentAnsi}${theme.boxRound.horizontal}`); }); }); diff --git a/packages/tui/test/terminal-appearance.test.ts b/packages/tui/test/terminal-appearance.test.ts index 161a2f276..ffd4b12ee 100644 --- a/packages/tui/test/terminal-appearance.test.ts +++ b/packages/tui/test/terminal-appearance.test.ts @@ -5,6 +5,8 @@ const stdinIsTtyDescriptor = Object.getOwnPropertyDescriptor(process.stdin, "isT const stdoutIsTtyDescriptor = Object.getOwnPropertyDescriptor(process.stdout, "isTTY"); const processPlatformDescriptor = Object.getOwnPropertyDescriptor(process, "platform"); const stdinSetRawModeDescriptor = Object.getOwnPropertyDescriptor(process.stdin, "setRawMode"); +const originalWslDistroName = Bun.env.WSL_DISTRO_NAME; +const originalWslInterop = Bun.env.WSL_INTEROP; function restoreProperty(target: object, key: string, descriptor: PropertyDescriptor | undefined): void { if (descriptor) { @@ -14,6 +16,14 @@ function restoreProperty(target: object, key: string, descriptor: PropertyDescri delete (target as Record)[key]; } +function restoreEnv(key: string, original: string | undefined): void { + if (original === undefined) { + delete Bun.env[key]; + return; + } + Bun.env[key] = original; +} + describe("ProcessTerminal OSC 11 appearance detection", () => { beforeEach(() => { Object.defineProperty(process.stdin, "isTTY", { value: true, configurable: true }); @@ -28,8 +38,8 @@ describe("ProcessTerminal OSC 11 appearance detection", () => { restoreProperty(process.stdout, "isTTY", stdoutIsTtyDescriptor); restoreProperty(process.stdin, "setRawMode", stdinSetRawModeDescriptor); restoreProperty(process, "platform", processPlatformDescriptor); - delete Bun.env.WSL_INTEROP; - delete Bun.env.WSL_DISTRO_NAME; + restoreEnv("WSL_INTEROP", originalWslInterop); + restoreEnv("WSL_DISTRO_NAME", originalWslDistroName); }); function setupTerminal() {