Skip to content
This repository was archived by the owner on May 20, 2026. It is now read-only.

Commit 22317e7

Browse files
authored
Background - store repository folder information for workspace sessions (#4857)
* Revert "Background - include repositoryPath for folder sessions (#4829)" This reverts commit b3af503. * Background - store workspace folder information
1 parent 8d6dd98 commit 22317e7

9 files changed

Lines changed: 30 additions & 22 deletions

src/extension/chatSessions/common/chatSessionMetadataStore.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { IWorkspaceInfo } from './workspaceInfo';
1111

1212
export interface WorkspaceFolderEntry {
1313
readonly folderPath: string;
14+
readonly repositoryPath?: string;
1415
readonly timestamp: number;
1516
}
1617

@@ -78,6 +79,7 @@ export interface IChatSessionMetadataStore {
7879
getWorktreeProperties(sessionId: string): Promise<ChatSessionWorktreeProperties | undefined>;
7980
getWorktreeProperties(folder: Uri): Promise<ChatSessionWorktreeProperties | undefined>;
8081
getSessionWorkspaceFolder(sessionId: string): Promise<vscode.Uri | undefined>;
82+
getSessionWorkspaceFolderEntry(sessionId: string): Promise<WorkspaceFolderEntry | undefined>;
8183
getUsedWorkspaceFolders(): Promise<WorkspaceFolderEntry[]>;
8284
getAdditionalWorkspaces(sessionId: string): Promise<IWorkspaceInfo[]>;
8385
setAdditionalWorkspaces(sessionId: string, workspaces: IWorkspaceInfo[]): Promise<void>;

src/extension/chatSessions/common/chatSessionWorkspaceFolderService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface IChatSessionWorkspaceFolderService {
2525
/**
2626
* Track workspace folder selection for a session (for folders without git repos in multi-root workspaces)
2727
*/
28-
trackSessionWorkspaceFolder(sessionId: string, workspaceFolderUri: string): Promise<void>;
28+
trackSessionWorkspaceFolder(sessionId: string, workspaceFolderUri: string, repositoryFolderUri?: string): Promise<void>;
2929

3030
/**
3131
* Get the workspace folder associated with a session (if a workspace folder without git repo was selected)

src/extension/chatSessions/common/test/mockChatSessionMetadataStore.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export class MockChatSessionMetadataStore implements IChatSessionMetadataStore {
5757
return undefined;
5858
}
5959

60+
async getSessionWorkspaceFolderEntry(sessionId: string): Promise<WorkspaceFolderEntry | undefined> {
61+
return undefined;
62+
}
63+
6064
async getUsedWorkspaceFolders(): Promise<WorkspaceFolderEntry[]> {
6165
return Array.from(this._workspaceFolders.values());
6266
}

src/extension/chatSessions/copilotcli/node/copilotcliSessionService.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ export interface ICopilotCLISessionItem {
5959
readonly timing: ChatSessionItem['timing'];
6060
readonly status?: ChatSessionStatus;
6161
readonly workingDirectory?: Uri;
62-
readonly repositoryDirectory?: Uri;
6362
}
6463

6564
export type ExtendedChatRequest = ChatRequest & { prompt: string };
@@ -392,7 +391,6 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
392391
const diskSessions: ICopilotCLISessionItem[] = coalesce(await Promise.all(
393392
sessionMetadataList.map(async (metadata): Promise<ICopilotCLISessionItem | undefined> => {
394393
const workingDirectory = metadata.context?.cwd ? URI.file(metadata.context.cwd) : undefined;
395-
const repositoryDirectory = metadata.context?.gitRoot ? URI.file(metadata.context.gitRoot) : undefined;
396394
this._sessionWorkingDirectories.set(metadata.sessionId, workingDirectory);
397395
if (!await this.shouldShowSession(metadata.sessionId, metadata.context)) {
398396
return;
@@ -409,8 +407,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
409407
id,
410408
label,
411409
timing: { created: startTime, startTime, endTime },
412-
workingDirectory,
413-
repositoryDirectory
410+
workingDirectory
414411
};
415412
}
416413

@@ -425,8 +422,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
425422
id,
426423
label,
427424
timing: { created: startTime, startTime, endTime },
428-
workingDirectory,
429-
repositoryDirectory
425+
workingDirectory
430426
};
431427
} catch (error) {
432428
this.logService.warn(`Failed to load session ${metadata.sessionId}: ${error}`);
@@ -452,7 +448,6 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
452448
label,
453449
status: session.object.status,
454450
timing: { created: createTime, startTime: createTime },
455-
repositoryDirectory: session.object.workspace.repository,
456451
};
457452
})));
458453

@@ -491,13 +486,11 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
491486
label,
492487
status: session.object.status,
493488
timing: this._cachedSessionItems.get(session.object.sessionId)?.timing ?? { created: createTime, startTime: createTime },
494-
repositoryDirectory: session.object.workspace.repository,
495489
};
496490
}
497491

498492
private async constructSessionItemImpl(metadata: LocalSessionMetadata, token: CancellationToken): Promise<ICopilotCLISessionItem | undefined> {
499493
const workingDirectory = metadata.context?.cwd ? URI.file(metadata.context.cwd) : undefined;
500-
const repositoryDirectory = metadata.context?.gitRoot ? URI.file(metadata.context.gitRoot) : undefined;
501494
this._sessionWorkingDirectories.set(metadata.sessionId, workingDirectory);
502495
const shouldShowSession = await this.shouldShowSession(metadata.sessionId, metadata.context);
503496
if (!shouldShowSession) {
@@ -515,7 +508,6 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
515508
label,
516509
timing: { created: startTime, startTime, endTime },
517510
workingDirectory,
518-
repositoryDirectory,
519511
status: this._sessionWrappers.get(id)?.object?.status
520512
};
521513
}
@@ -832,8 +824,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
832824
id: newSessionId,
833825
label: customTitle,
834826
timing: { created: Date.now(), startTime: Date.now() },
835-
workingDirectory: getWorkingDirectory(workspaceInfo),
836-
repositoryDirectory: workspaceInfo.repository
827+
workingDirectory: getWorkingDirectory(workspaceInfo)
837828
});
838829
return newSessionId;
839830
}
@@ -1191,7 +1182,7 @@ async function copySessionFilesForForking(sessionId: string, targetSessionId: st
11911182
if (workspaceInfo.worktreeProperties) {
11921183
await _chatSessionMetadataStore.storeWorktreeInfo(targetSessionId, workspaceInfo.worktreeProperties);
11931184
} else if (workspaceInfo.folder) {
1194-
await _chatSessionMetadataStore.storeWorkspaceFolderInfo(targetSessionId, { folderPath: workspaceInfo.folder.fsPath, timestamp: Date.now() });
1185+
await _chatSessionMetadataStore.storeWorkspaceFolderInfo(targetSessionId, { folderPath: workspaceInfo.folder.fsPath, repositoryPath: workspaceInfo.repository?.fsPath, timestamp: Date.now() });
11951186
}
11961187
})(),
11971188
]), token);

src/extension/chatSessions/vscode-node/chatSessionMetadataStoreImpl.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ export class ChatSessionMetadataStore extends Disposable implements IChatSession
237237
return metadata.workspaceFolder?.folderPath ? Uri.file(metadata.workspaceFolder.folderPath) : undefined;
238238
}
239239

240+
async getSessionWorkspaceFolderEntry(sessionId: string): Promise<WorkspaceFolderEntry | undefined> {
241+
const metadata = await this.getSessionMetadata(sessionId);
242+
if (!metadata) {
243+
return undefined;
244+
}
245+
return metadata.workspaceFolder;
246+
}
247+
240248
async getUsedWorkspaceFolders(): Promise<WorkspaceFolderEntry[]> {
241249
await this._intialize.value;
242250
const entries = new ResourceMap<number>();

src/extension/chatSessions/vscode-node/chatSessionWorkspaceFolderServiceImpl.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ export class ChatSessionWorkspaceFolderService extends Disposable implements ICh
7070
await this.metadataStore.deleteSessionMetadata(sessionId);
7171
}
7272

73-
async trackSessionWorkspaceFolder(sessionId: string, workspaceFolderUri: string): Promise<void> {
73+
async trackSessionWorkspaceFolder(sessionId: string, workspaceFolderUri: string, repositoryFolderUri?: string): Promise<void> {
7474
const entry: WorkspaceFolderEntry = {
7575
folderPath: workspaceFolderUri,
76+
repositoryPath: repositoryFolderUri,
7677
timestamp: Date.now()
7778
};
7879
this.workspaceState.set(sessionId, entry);

src/extension/chatSessions/vscode-node/copilotCLIChatSessions.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ export class CopilotCLIChatSessionContentProvider extends Disposable implements
439439
} else {
440440
// Workspace
441441
const sessionRequestDetails = await this.chatSessionMetadataStore.getRequestDetails(session.id);
442+
const workspaceFolderEntry = await this.chatSessionMetadataStore.getSessionWorkspaceFolderEntry(session.id);
442443

443444
let lastCheckpointRef: string | undefined;
444445
for (let i = sessionRequestDetails.length - 1; i >= 0; i--) {
@@ -455,7 +456,7 @@ export class CopilotCLIChatSessionContentProvider extends Disposable implements
455456

456457
metadata = {
457458
isolationMode: IsolationMode.Workspace,
458-
repositoryPath: session.repositoryDirectory?.fsPath,
459+
repositoryPath: workspaceFolderEntry?.repositoryPath,
459460
workingDirectoryPath: workingDirectory?.fsPath,
460461
firstCheckpointRef,
461462
lastCheckpointRef
@@ -1382,7 +1383,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
13821383
}
13831384
const sessionWorkingDirectory = getWorkingDirectory(session.object.workspace);
13841385
if (sessionWorkingDirectory && !isIsolationEnabled(session.object.workspace)) {
1385-
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, sessionWorkingDirectory.fsPath);
1386+
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, sessionWorkingDirectory.fsPath, session.object.workspace.repository?.fsPath);
13861387
}
13871388
disposables.add(session.object.attachStream(stream));
13881389
const permissionLevel = request.permissionLevel;
@@ -1538,7 +1539,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
15381539
void this.copilotCLIWorktreeManagerService.setWorktreeProperties(session.object.sessionId, worktreeProperties);
15391540
}
15401541
if (workingDirectory && !isIsolationEnabled(workspaceInfo)) {
1541-
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, workingDirectory.fsPath);
1542+
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, workingDirectory.fsPath, workspaceInfo.repository?.fsPath);
15421543
}
15431544

15441545
try {

src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc
324324
} else {
325325
// Workspace
326326
const sessionRequestDetails = await this.chatSessionMetadataStore.getRequestDetails(session.id);
327+
const workspaceFolderEntry = await this.chatSessionMetadataStore.getSessionWorkspaceFolderEntry(session.id);
327328

328329
let lastCheckpointRef: string | undefined;
329330
for (let i = sessionRequestDetails.length - 1; i >= 0; i--) {
@@ -340,7 +341,7 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc
340341

341342
metadata = {
342343
isolationMode: IsolationMode.Workspace,
343-
repositoryPath: session.repositoryDirectory?.fsPath,
344+
repositoryPath: workspaceFolderEntry?.repositoryPath,
344345
workingDirectoryPath: workingDirectory?.fsPath,
345346
firstCheckpointRef,
346347
lastCheckpointRef
@@ -1706,7 +1707,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
17061707
}
17071708
const sessionWorkingDirectory = getWorkingDirectory(session.object.workspace);
17081709
if (sessionWorkingDirectory && !isIsolationEnabled(session.object.workspace)) {
1709-
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, sessionWorkingDirectory.fsPath);
1710+
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, sessionWorkingDirectory.fsPath, session.object.workspace.repository?.fsPath);
17101711
}
17111712
disposables.add(session.object.attachStream(stream));
17121713
const permissionLevel = request.permissionLevel;
@@ -1846,7 +1847,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
18461847
void this.copilotCLIWorktreeManagerService.setWorktreeProperties(session.object.sessionId, worktreeProperties);
18471848
}
18481849
if (workingDirectory && !isIsolationEnabled(workspaceInfo)) {
1849-
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, workingDirectory.fsPath);
1850+
void this.workspaceFolderService.trackSessionWorkspaceFolder(session.object.sessionId, workingDirectory.fsPath, workspaceInfo.repository?.fsPath);
18501851
}
18511852

18521853
try {

src/extension/chatSessions/vscode-node/test/folderRepositoryManager.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class FakeChatSessionWorkspaceFolderService extends mock<IChatSessionWorkspaceFo
6161
private _recentFolders: { folder: vscode.Uri; lastAccessTime: number }[] = [];
6262
private _workspaceChanges = new Map<string, readonly ChatSessionWorktreeFile[] | undefined>();
6363

64-
override trackSessionWorkspaceFolder = vi.fn(async (sessionId: string, workspaceFolderUri: string): Promise<void> => {
64+
override trackSessionWorkspaceFolder = vi.fn(async (sessionId: string, workspaceFolderUri: string, _repositoryPath?: string): Promise<void> => {
6565
this._sessionWorkspaceFolders.set(sessionId, vscode.Uri.file(workspaceFolderUri));
6666
});
6767

0 commit comments

Comments
 (0)