From f26c6baa652079f618aa48f53d44364b83a5e2b5 Mon Sep 17 00:00:00 2001 From: Pi on Code Agent <313040514+pi-on-code-agent[bot]@users.noreply.github.com> Date: Wed, 9 Sep 2026 02:30:29 +0000 Subject: [PATCH 1/2] fix: remove duplicate panel location setting --- package.json | 15 +++------ src/chat-panel-location.ts | 4 +-- src/extension.ts | 4 +-- src/test/chat-panel-location.test.ts | 48 +++++++++++++--------------- 4 files changed, 31 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index e625e38..8d7b9d3 100644 --- a/package.json +++ b/package.json @@ -331,22 +331,15 @@ "pi-on-code.newChatPanelLocation": { "type": "string", "default": "panel", - "enum": ["panel", "splitPanel"], + "enum": [ + "panel", + "splitPanel" + ], "enumDescriptions": [ "Open brand-new Pi chats as tabs in the active editor group without splitting the editor area.", "Open brand-new Pi chats in a new editor group split to the right of the active group." ], "description": "Where brand-new Pi chats open in the editor." - }, - "pi-on-code.chatPanelLocation": { - "type": "string", - "default": "splitPanel", - "enum": ["panel", "splitPanel"], - "enumDescriptions": [ - "Open resumed/forked Pi chats as tabs in the active editor group without splitting the editor area.", - "Open resumed/forked Pi chats in a new editor group split to the right of the active group (historical default)." - ], - "description": "Where resumed and forked Pi chats open in the editor." } } }, diff --git a/src/chat-panel-location.ts b/src/chat-panel-location.ts index a72a148..161d7a5 100644 --- a/src/chat-panel-location.ts +++ b/src/chat-panel-location.ts @@ -4,11 +4,11 @@ * - `"panel"` — the chat opens as a tab in the active editor group; the editor * area is never split for it. * - `"splitPanel"` — the chat opens in a new editor group split to the right - * of the active group (historical default behavior). + * of the active group. */ export type ChatPanelLocation = "panel" | "splitPanel"; -export const DEFAULT_CHAT_PANEL_LOCATION: ChatPanelLocation = "splitPanel"; +export const DEFAULT_CHAT_PANEL_LOCATION: ChatPanelLocation = "panel"; export function parseChatPanelLocation(raw: unknown): ChatPanelLocation { return raw === "panel" || raw === "splitPanel" diff --git a/src/extension.ts b/src/extension.ts index b387422..2478403 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1128,7 +1128,7 @@ export async function activate(context: vscode.ExtensionContext): Promise ): Promise { const newSw = createSessionWindow(context, { path: forkedPath }, false, cwd); setActiveSession(newSw); - void newSw.webviewPanel.show(chatShowColumn("chatPanelLocation")); + void newSw.webviewPanel.show(); sessionTreeProvider?.refresh(); await initSessionInBackground(context, newSw, { openPath: forkedPath }); @@ -1374,7 +1374,7 @@ export async function activate(context: vscode.ExtensionContext): Promise title: summary?.name ?? summary?.firstMessage, }, false, summary?.cwd ?? getWorkspaceCwd()); setActiveSession(sw); - await sw.webviewPanel.show(chatShowColumn("chatPanelLocation")); + await sw.webviewPanel.show(); setSessionResultUnread(sw, false); sessionTreeProvider?.refresh(); void initSessionInBackground(context, sw, { openPath: resolved }); diff --git a/src/test/chat-panel-location.test.ts b/src/test/chat-panel-location.test.ts index dcf0dc5..ed8853e 100644 --- a/src/test/chat-panel-location.test.ts +++ b/src/test/chat-panel-location.test.ts @@ -6,50 +6,48 @@ import { } from "../chat-panel-location.js"; suite("Chat panel location", () => { - test("defaults to splitPanel for missing or invalid values", () => { - assert.strictEqual(DEFAULT_CHAT_PANEL_LOCATION, "splitPanel"); - assert.strictEqual(parseChatPanelLocation(undefined), "splitPanel"); - assert.strictEqual(parseChatPanelLocation("sidebar-left"), "splitPanel"); - assert.strictEqual(parseChatPanelLocation(42), "splitPanel"); + test("defaults to panel for missing or invalid values", () => { + assert.strictEqual(DEFAULT_CHAT_PANEL_LOCATION, "panel"); + assert.strictEqual(parseChatPanelLocation(undefined), "panel"); + assert.strictEqual(parseChatPanelLocation("sidebar-left"), "panel"); + assert.strictEqual(parseChatPanelLocation(42), "panel"); }); - test("accepts the two documented locations", () => { + test("accepts the two editor placements", () => { assert.strictEqual(parseChatPanelLocation("panel"), "panel"); assert.strictEqual(parseChatPanelLocation("splitPanel"), "splitPanel"); }); - test("publishes new (panel) and resume/fork (splitPanel) properties", () => { + test("publishes only the single newChatPanelLocation property", () => { const manifest = JSON.parse( readFileSync(new URL("../../package.json", import.meta.url), "utf8"), ) as { contributes: { configuration: { - properties: Record; + properties: Record; }; }; }; - const newProp = manifest.contributes.configuration.properties["pi-on-code.newChatPanelLocation"]; - const resumeProp = manifest.contributes.configuration.properties["pi-on-code.chatPanelLocation"]; - assert.ok(newProp, "pi-on-code.newChatPanelLocation property is missing"); - assert.strictEqual(newProp.default, "panel"); - assert.deepStrictEqual(newProp.enum, ["panel", "splitPanel"]); - assert.ok(resumeProp, "pi-on-code.chatPanelLocation property is missing"); - assert.strictEqual(resumeProp.default, "splitPanel"); - assert.deepStrictEqual(resumeProp.enum, ["panel", "splitPanel"]); + const property = manifest.contributes.configuration.properties["pi-on-code.newChatPanelLocation"]; + assert.ok(property, "pi-on-code.newChatPanelLocation property is missing"); + assert.strictEqual(property.default, "panel"); + assert.deepStrictEqual(property.enum, ["panel", "splitPanel"]); + assert.ok( + !("pi-on-code.chatPanelLocation" in manifest.contributes.configuration.properties), + "the duplicate chatPanelLocation property must be gone", + ); }); - test("routes new chats through newChatPanelLocation and resumes/forks through chatPanelLocation", () => { + test("new chats honor newChatPanelLocation; resume/fork use the default column", () => { const extension = readFileSync( new URL("../../src/extension.ts", import.meta.url), "utf8", ); - assert.match(extension, /function chatShowColumn\(key: string\)/); - assert.match(extension, /sw\.webviewPanel\.show\(chatShowColumn\("newChatPanelLocation"\)\)/); - assert.match(extension, /newSw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\)/); - assert.match(extension, /await sw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\)/); + assert.match(extension, /chatShowColumn\("newChatPanelLocation"\)/); + assert.doesNotMatch(extension, /chatShowColumn\("chatPanelLocation"\)/); + assert.doesNotMatch(extension, /"chatPanelLocation"/); + // Resume and fork fall back to the plain historical default show(). + assert.match(extension, /void newSw\.webviewPanel\.show\(\);/); + assert.match(extension, /await sw\.webviewPanel\.show\(\);/); }); }); From 0256e738ccc697aadd77c5f925e8601c5b60e9cb Mon Sep 17 00:00:00 2001 From: Pi on Code Agent <313040514+pi-on-code-agent[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:33:06 +0000 Subject: [PATCH 2/2] fix: unify panel location under chatPanelLocation --- package.json | 8 ++++---- src/extension.ts | 6 +++--- src/test/chat-panel-location.test.ts | 25 +++++++++++++------------ 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 8d7b9d3..f66a3d4 100644 --- a/package.json +++ b/package.json @@ -328,7 +328,7 @@ "default": false, "description": "Automatically reveal a new Pi chat tab when the extension activates. Previously open Pi session tabs are always restored." }, - "pi-on-code.newChatPanelLocation": { + "pi-on-code.chatPanelLocation": { "type": "string", "default": "panel", "enum": [ @@ -336,10 +336,10 @@ "splitPanel" ], "enumDescriptions": [ - "Open brand-new Pi chats as tabs in the active editor group without splitting the editor area.", - "Open brand-new Pi chats in a new editor group split to the right of the active group." + "Open Pi chats (new, resumed, and forked) as tabs in the active editor group without splitting the editor area.", + "Open Pi chats (new, resumed, and forked) in a new editor group split to the right of the active group." ], - "description": "Where brand-new Pi chats open in the editor." + "description": "Where Pi chats open in the editor: as a tab in the active group, or split to the right." } } }, diff --git a/src/extension.ts b/src/extension.ts index 2478403..eb4c6a9 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1128,7 +1128,7 @@ export async function activate(context: vscode.ExtensionContext): Promise ): Promise { const newSw = createSessionWindow(context, { path: forkedPath }, false, cwd); setActiveSession(newSw); - void newSw.webviewPanel.show(); + void newSw.webviewPanel.show(chatShowColumn("chatPanelLocation")); sessionTreeProvider?.refresh(); await initSessionInBackground(context, newSw, { openPath: forkedPath }); @@ -1374,7 +1374,7 @@ export async function activate(context: vscode.ExtensionContext): Promise title: summary?.name ?? summary?.firstMessage, }, false, summary?.cwd ?? getWorkspaceCwd()); setActiveSession(sw); - await sw.webviewPanel.show(); + await sw.webviewPanel.show(chatShowColumn("chatPanelLocation")); setSessionResultUnread(sw, false); sessionTreeProvider?.refresh(); void initSessionInBackground(context, sw, { openPath: resolved }); @@ -1971,7 +1971,7 @@ function addSession(context: vscode.ExtensionContext, cwd = getWorkspaceCwd()): void saveOpenSessionPaths(); }; setActiveSession(sw); - void sw.webviewPanel.show(chatShowColumn("newChatPanelLocation")); + void sw.webviewPanel.show(chatShowColumn("chatPanelLocation")); void initSessionInBackground(context, sw, { fresh: true }); } diff --git a/src/test/chat-panel-location.test.ts b/src/test/chat-panel-location.test.ts index ed8853e..8cd45b8 100644 --- a/src/test/chat-panel-location.test.ts +++ b/src/test/chat-panel-location.test.ts @@ -18,7 +18,7 @@ suite("Chat panel location", () => { assert.strictEqual(parseChatPanelLocation("splitPanel"), "splitPanel"); }); - test("publishes only the single newChatPanelLocation property", () => { + test("publishes exactly one chatPanelLocation property defaulting to panel", () => { const manifest = JSON.parse( readFileSync(new URL("../../package.json", import.meta.url), "utf8"), ) as { @@ -28,26 +28,27 @@ suite("Chat panel location", () => { }; }; }; - const property = manifest.contributes.configuration.properties["pi-on-code.newChatPanelLocation"]; - assert.ok(property, "pi-on-code.newChatPanelLocation property is missing"); + const properties = manifest.contributes.configuration.properties; + const property = properties["pi-on-code.chatPanelLocation"]; + assert.ok(property, "pi-on-code.chatPanelLocation property is missing"); assert.strictEqual(property.default, "panel"); assert.deepStrictEqual(property.enum, ["panel", "splitPanel"]); assert.ok( - !("pi-on-code.chatPanelLocation" in manifest.contributes.configuration.properties), - "the duplicate chatPanelLocation property must be gone", + !("pi-on-code.newChatPanelLocation" in properties), + "the duplicate newChatPanelLocation property must be gone", ); }); - test("new chats honor newChatPanelLocation; resume/fork use the default column", () => { + test("new, resumed, and forked chats all follow chatPanelLocation", () => { const extension = readFileSync( new URL("../../src/extension.ts", import.meta.url), "utf8", ); - assert.match(extension, /chatShowColumn\("newChatPanelLocation"\)/); - assert.doesNotMatch(extension, /chatShowColumn\("chatPanelLocation"\)/); - assert.doesNotMatch(extension, /"chatPanelLocation"/); - // Resume and fork fall back to the plain historical default show(). - assert.match(extension, /void newSw\.webviewPanel\.show\(\);/); - assert.match(extension, /await sw\.webviewPanel\.show\(\);/); + assert.match(extension, /void sw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\);/); + assert.match(extension, /void newSw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\);/); + assert.match(extension, /await sw\.webviewPanel\.show\(chatShowColumn\("chatPanelLocation"\)\);/); + assert.doesNotMatch(extension, /newChatPanelLocation/); + const occurrences = extension.match(/chatShowColumn\("chatPanelLocation"\)/g)?.length ?? 0; + assert.strictEqual(occurrences, 3, "new, resume, and fork must share the single setting"); }); });