From 79df8f7790bd3bd13600a762423a68bd72421d03 Mon Sep 17 00:00:00 2001 From: Adam Cheng <63501289+627150795@users.noreply.github.com> Date: Tue, 1 Sep 2026 19:09:46 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(ui):=20=E4=BF=AE=E5=A4=8D=20Windows=20H?= =?UTF-8?q?ome=20=E8=B7=AF=E5=BE=84=E7=BC=A9=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/ui-customization/footer.ts | 11 +++++++---- .../extensions/ui-customization/footer.test.ts | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/extensions/ui-customization/footer.ts b/extensions/ui-customization/footer.ts index dd19606e..524f52a9 100644 --- a/extensions/ui-customization/footer.ts +++ b/extensions/ui-customization/footer.ts @@ -1,5 +1,4 @@ import { homedir } from "node:os"; -import { relative } from "node:path"; import type { Theme } from "@earendil-works/pi-coding-agent"; import { getCapabilities, @@ -117,10 +116,14 @@ export function formatTokens(tokens: number) { return `${(tokens / 1_000_000).toFixed(1)}m`; } -export function formatDirectory(cwd: string) { - const home = homedir(); +export function formatDirectory(cwd: string, home = homedir()) { if (cwd === home) return "~"; - const display = cwd.startsWith(`${home}/`) ? `~/${relative(home, cwd)}` : cwd; + const separator = cwd.startsWith(home) ? cwd[home.length] : undefined; + const child = separator === "/" || separator === "\\"; + const relativePath = child ? cwd.slice(home.length + 1) : ""; + const display = child + ? `~/${separator === "\\" ? relativePath.replaceAll("\\", "/") : relativePath}` + : cwd; return sanitizeTerminalLabel(display); } diff --git a/tests/extensions/ui-customization/footer.test.ts b/tests/extensions/ui-customization/footer.test.ts index 9ec257f9..ab672ec4 100644 --- a/tests/extensions/ui-customization/footer.test.ts +++ b/tests/extensions/ui-customization/footer.test.ts @@ -9,6 +9,7 @@ import { import { buildSegmentCatalog, fitSegmentsToWidth, + formatDirectory, renderFooter, resolveLineSegments, type FooterSegment, @@ -43,6 +44,22 @@ const gitInfo: GitInfoState = { pullRequest: { number: 42, url: "https://example.com/pr/42", isDraft: false }, }; +test("formatDirectory shortens Windows Home paths", () => { + assert.equal( + formatDirectory("C:\\Users\\Adam\\project", "C:\\Users\\Adam"), + "~/project", + ); + assert.equal(formatDirectory("C:\\Users\\Adam", "C:\\Users\\Adam"), "~"); + assert.equal( + formatDirectory("C:\\Users\\Adam2\\project", "C:\\Users\\Adam"), + "C:\\Users\\Adam2\\project", + ); + assert.equal( + formatDirectory("/Users/adam/project", "/Users/adam"), + "~/project", + ); +}); + test("default one-line layout leads with model context and ends with cwd", () => { const lines = renderFooter({ cwd: "/Users/me/project", From 36f52eb78e388794575d067a0f15ea790cf2425b Mon Sep 17 00:00:00 2001 From: Adam Cheng <63501289+627150795@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:26:59 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix(ui):=20=E6=8C=89=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E9=A3=8E=E6=A0=BC=E5=88=A4=E6=96=AD=20Home=20=E7=9B=AE?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/ui-customization/footer.ts | 24 ++++++++++++------- .../ui-customization/footer.test.ts | 15 ++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/extensions/ui-customization/footer.ts b/extensions/ui-customization/footer.ts index 524f52a9..9fd5d377 100644 --- a/extensions/ui-customization/footer.ts +++ b/extensions/ui-customization/footer.ts @@ -1,4 +1,5 @@ import { homedir } from "node:os"; +import { posix, win32 } from "node:path"; import type { Theme } from "@earendil-works/pi-coding-agent"; import { getCapabilities, @@ -116,14 +117,21 @@ export function formatTokens(tokens: number) { return `${(tokens / 1_000_000).toFixed(1)}m`; } -export function formatDirectory(cwd: string, home = homedir()) { - if (cwd === home) return "~"; - const separator = cwd.startsWith(home) ? cwd[home.length] : undefined; - const child = separator === "/" || separator === "\\"; - const relativePath = child ? cwd.slice(home.length + 1) : ""; - const display = child - ? `~/${separator === "\\" ? relativePath.replaceAll("\\", "/") : relativePath}` - : cwd; +export function formatDirectory( + cwd: string, + home = homedir(), + pathModule = process.platform === "win32" ? win32 : posix, +) { + const relativePath = pathModule.relative(home, cwd); + const outsideHome = + relativePath === ".." || + relativePath.startsWith(`..${pathModule.sep}`) || + pathModule.isAbsolute(relativePath); + const display = outsideHome + ? cwd + : relativePath + ? `~/${relativePath.replaceAll(pathModule.sep, "/")}` + : "~"; return sanitizeTerminalLabel(display); } diff --git a/tests/extensions/ui-customization/footer.test.ts b/tests/extensions/ui-customization/footer.test.ts index ab672ec4..be4278c3 100644 --- a/tests/extensions/ui-customization/footer.test.ts +++ b/tests/extensions/ui-customization/footer.test.ts @@ -1,5 +1,6 @@ import assert from "node:assert/strict"; import test from "node:test"; +import { posix, win32 } from "node:path"; import { visibleWidth } from "@earendil-works/pi-tui"; import { DEFAULT_FOOTER_LINES, @@ -60,6 +61,20 @@ test("formatDirectory shortens Windows Home paths", () => { ); }); +test("formatDirectory respects POSIX backslashes as filename characters", () => { + assert.equal( + formatDirectory("/Users/adam\\project", "/Users/adam", posix), + "/Users/adam\\project", + ); +}); + +test("formatDirectory compares Windows paths case-insensitively", () => { + assert.equal( + formatDirectory("c:\\users\\adam\\project", "C:\\Users\\Adam", win32), + "~/project", + ); +}); + test("default one-line layout leads with model context and ends with cwd", () => { const lines = renderFooter({ cwd: "/Users/me/project", From 6bfeea4a2e8ea2e032b54e42217fa399e885a667 Mon Sep 17 00:00:00 2001 From: Adam Cheng <63501289+627150795@users.noreply.github.com> Date: Wed, 2 Sep 2026 23:00:07 +0800 Subject: [PATCH 3/3] =?UTF-8?q?test(ui):=20=E5=9B=BA=E5=AE=9A=20Windows=20?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E6=B5=8B=E8=AF=95=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/extensions/ui-customization/footer.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/extensions/ui-customization/footer.test.ts b/tests/extensions/ui-customization/footer.test.ts index be4278c3..6be0465e 100644 --- a/tests/extensions/ui-customization/footer.test.ts +++ b/tests/extensions/ui-customization/footer.test.ts @@ -47,12 +47,15 @@ const gitInfo: GitInfoState = { test("formatDirectory shortens Windows Home paths", () => { assert.equal( - formatDirectory("C:\\Users\\Adam\\project", "C:\\Users\\Adam"), + formatDirectory("C:\\Users\\Adam\\project", "C:\\Users\\Adam", win32), "~/project", ); - assert.equal(formatDirectory("C:\\Users\\Adam", "C:\\Users\\Adam"), "~"); assert.equal( - formatDirectory("C:\\Users\\Adam2\\project", "C:\\Users\\Adam"), + formatDirectory("C:\\Users\\Adam", "C:\\Users\\Adam", win32), + "~", + ); + assert.equal( + formatDirectory("C:\\Users\\Adam2\\project", "C:\\Users\\Adam", win32), "C:\\Users\\Adam2\\project", ); assert.equal(