Path: blob/main/extensions/copilot/src/extension/chatSessions/claude/node/claudeProjectFolders.ts
13405 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { IWorkspaceService } from '../../../../platform/workspace/common/workspaceService';6import { URI } from '../../../../util/vs/base/common/uri';7import { IFolderRepositoryManager } from '../../../chatSessions/common/folderRepositoryManager';89// #region Slug Computation1011/**12* Compute the workspace slug from a folder URI.13* Matches the Claude Code slug format.14*15* @example16* // Windows: drive letter is uppercased, path separators become hyphens17* '/c:/Users/test/project' → 'C--Users-test-project'18*19* // macOS/Linux: leading slash becomes hyphen, path separators become hyphens20* '/Users/test/project' → '-Users-test-project'21*/22export function computeFolderSlug(folderUri: URI): string {23return folderUri.path24.replace(/^\/([a-z]):/i, (_, driveLetter: string) => driveLetter.toUpperCase() + '-')25.replace(/[\/ .]/g, '-');26}2728// #endregion2930// #region Project Folder Discovery3132export interface ProjectFolder {33readonly slug: string;34readonly folderUri: URI;35}3637/**38* Get the project directory slugs to scan for sessions, along with their39* original folder URIs (needed for badge display).40*41* - Single-root: slug for that one folder42* - Multi-root: slug for every workspace folder43* - Empty workspace: slug for every folder known to the folder repository manager44*/45export async function getProjectFolders(46workspace: IWorkspaceService,47folderRepositoryManager: IFolderRepositoryManager48): Promise<ProjectFolder[]> {49const folders = workspace.getWorkspaceFolders();5051if (folders.length > 0) {52return folders.map(folder => ({ slug: computeFolderSlug(folder), folderUri: folder }));53}5455// Empty workspace: use all known folders from the folder repository manager56const mruEntries = await folderRepositoryManager.getFolderMRU();57if (mruEntries.length > 0) {58return mruEntries.map(entry => ({ slug: computeFolderSlug(entry.folder), folderUri: entry.folder }));59}6061return [];62}6364// #endregion656667