Skip to content

Commit 966014e

Browse files
committed
fix: clear pending chat ID when open flow is abandoned
If commands.open() returns without actually opening a window (e.g. the user cancels a workspace, agent, or folder prompt), clear the pending chat ID from memento so it does not leak into a future, unrelated reload. - commands.open() and openWorkspace() now return boolean indicating whether a window was actually opened. - handleOpen() clears the pending chat ID when open() returns false. - Add clearPendingChatId() to MementoManager.
1 parent 3448126 commit 966014e

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

src/commands.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ export class Commands {
430430
431431
* Throw if not logged into a deployment.
432432
*/
433-
public async openFromSidebar(item: OpenableTreeItem) {
433+
public async openFromSidebar(item: OpenableTreeItem): Promise<void> {
434434
if (item) {
435435
const baseUrl = this.extensionClient.getAxiosInstance().defaults.baseURL;
436436
if (!baseUrl) {
@@ -463,9 +463,8 @@ export class Commands {
463463
}
464464
} else {
465465
// If there is no tree item, then the user manually ran this command.
466-
// Default to the regular open instead.
467-
return this.open();
468-
}
466+
// Default to the regular open instead.
467+
await this.open(); }
469468
}
470469

471470
public async openAppStatus(app: {
@@ -529,7 +528,7 @@ export class Commands {
529528
agentName?: string,
530529
folderPath?: string,
531530
openRecent?: boolean,
532-
): Promise<void> {
531+
): Promise<boolean> {
533532
const baseUrl = this.extensionClient.getAxiosInstance().defaults.baseURL;
534533
if (!baseUrl) {
535534
throw new Error("You are not logged in");
@@ -545,18 +544,24 @@ export class Commands {
545544
workspace = await this.pickWorkspace();
546545
if (!workspace) {
547546
// User declined to pick a workspace.
548-
return;
547+
return false;
549548
}
550549
}
551550

552551
const agents = await this.extractAgentsWithFallback(workspace);
553552
const agent = await maybeAskAgent(agents, agentName);
554553
if (!agent) {
555554
// User declined to pick an agent.
556-
return;
555+
return false;
557556
}
558557

559-
await this.openWorkspace(baseUrl, workspace, agent, folderPath, openRecent);
558+
return this.openWorkspace(
559+
baseUrl,
560+
workspace,
561+
agent,
562+
folderPath,
563+
openRecent,
564+
);
560565
}
561566

562567
/**
@@ -745,7 +750,7 @@ export class Commands {
745750
agent: WorkspaceAgent,
746751
folderPath: string | undefined,
747752
openRecent = false,
748-
) {
753+
): Promise<boolean> {
749754
const remoteAuthority = toRemoteAuthority(
750755
baseUrl,
751756
workspace.owner_name,
@@ -788,7 +793,7 @@ export class Commands {
788793
});
789794
if (!folderPath) {
790795
// User aborted.
791-
return;
796+
return false;
792797
}
793798
}
794799
}
@@ -806,14 +811,15 @@ export class Commands {
806811
// Open this in a new window!
807812
newWindow,
808813
);
809-
return;
814+
return true;
810815
}
811816

812817
// This opens the workspace without an active folder opened.
813818
await vscode.commands.executeCommand("vscode.newWindow", {
814819
remoteAuthority: remoteAuthority,
815820
reuseWindow: !newWindow,
816821
});
822+
return true;
817823
}
818824
}
819825

src/core/mementoManager.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,13 @@ export class MementoManager {
8181
}
8282
return chatId;
8383
}
84+
85+
/**
86+
* Clear the pending chat ID without reading it. Used when
87+
* the open flow is abandoned (e.g. user cancels a prompt)
88+
* so the stale ID does not leak into a future reload.
89+
*/
90+
public async clearPendingChatId(): Promise<void> {
91+
await this.memento.update("pendingChatId", undefined);
92+
}
8493
}

src/uri/uriHandler.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,27 @@ async function handleOpen(ctx: UriRouteContext): Promise<void> {
9393
// a remote-authority reload that wipes in-memory state.
9494
// The extension picks this up after the reload in activate().
9595
const chatId = params.get("chatId");
96+
const mementoManager = serviceContainer.getMementoManager();
9697
if (chatId) {
97-
const mementoManager = serviceContainer.getMementoManager();
9898
await mementoManager.setPendingChatId(chatId);
9999
}
100100

101101
await setupDeployment(params, serviceContainer, deploymentManager);
102102

103-
await commands.open(
103+
const opened = await commands.open(
104104
owner,
105105
workspace,
106106
agent ?? undefined,
107107
folder ?? undefined,
108108
openRecent,
109109
);
110+
111+
// If commands.open() returned without opening a window (e.g. the
112+
// user cancelled a prompt), clear the pending chat ID so it does
113+
// not leak into a future, unrelated reload.
114+
if (!opened && chatId) {
115+
await mementoManager.clearPendingChatId();
116+
}
110117
}
111118

112119
async function handleOpenDevContainer(ctx: UriRouteContext): Promise<void> {

0 commit comments

Comments
 (0)