diff --git a/src/vs/workbench/contrib/chat/browser/actions/exportAgentHostDebugLogsAction.ts b/src/vs/workbench/contrib/chat/browser/actions/exportAgentHostDebugLogsAction.ts index 23301dc52fbc7a..af44d3964e6684 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/exportAgentHostDebugLogsAction.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/exportAgentHostDebugLogsAction.ts @@ -24,6 +24,7 @@ import { ILogService } from '../../../../../platform/log/common/log.js'; import { INotificationService, Severity } from '../../../../../platform/notification/common/notification.js'; import { IProductService } from '../../../../../platform/product/common/productService.js'; import { ITextModelService } from '../../../../../editor/common/services/resolverService.js'; +import { IChatEntitlementService } from '../../../../services/chat/common/chatEntitlementService.js'; import { IOutputService } from '../../../../services/output/common/output.js'; import { IPathService } from '../../../../services/path/common/pathService.js'; import { IChatWidgetService } from '../chat.js'; @@ -63,7 +64,7 @@ export const IAgentHostDebugLogsExportService = createDecorator; + save(exportName: string, files: readonly { path: string; contents: string }[]): Promise; } export class BrowserAgentHostDebugLogsExportService implements IAgentHostDebugLogsExportService { @@ -74,8 +75,8 @@ export class BrowserAgentHostDebugLogsExportService implements IAgentHostDebugLo @IFileService private readonly fileService: IFileService, ) { } - async save(exportName: string, files: readonly { path: string; contents: string }[]): Promise { - await exportFilesToLocalFolder(this.fileDialogService, this.fileService, exportName, files); + async save(exportName: string, files: readonly { path: string; contents: string }[]): Promise { + return exportFilesToLocalFolder(this.fileDialogService, this.fileService, exportName, files); } } @@ -334,12 +335,18 @@ export async function exportAgentHostDebugLogs( ): Promise { const exportService = accessor.get(IAgentHostDebugLogsExportService); const notificationService = accessor.get(INotificationService); + const chatEntitlementService = accessor.get(IChatEntitlementService); const logs = await collectAgentHostDebugLogs(accessor, activeSession); if (!logs) { return; } try { - await exportService.save(logs.exportName, logs.files); + const saved = await exportService.save(logs.exportName, logs.files); + if (saved) { + notificationService.warn(chatEntitlementService.isInternal + ? localize('exportDebugLogs.privacyWarning.internal', "Note: This log may contain personal information such as auth tokens, file contents, or terminal output. It MUST be shared privately via Slack or in an issue filed on the microsoft/vscode-internalbacklog repo.") + : localize('exportDebugLogs.privacyWarning', "Note: This log may contain personal information such as auth tokens, file contents, or terminal output. Please consider sharing privately or reviewing the contents carefully before sharing.")); + } } catch (error) { notificationService.notify({ severity: Severity.Error, @@ -410,7 +417,7 @@ async function exportFilesToLocalFolder( fileService: IFileService, exportName: string, files: readonly { path: string; contents: string }[], -): Promise { +): Promise { const folders = await fileDialogService.showOpenDialog({ title: localize('exportDebugLogs.folderDialogTitle', "Select Folder for Agent Host Debug Logs"), canSelectFiles: false, @@ -421,7 +428,7 @@ async function exportFilesToLocalFolder( const parentFolder = folders?.[0]; if (!parentFolder) { - return; + return false; } const exportFolder = joinPath(parentFolder, exportName); @@ -439,6 +446,7 @@ async function exportFilesToLocalFolder( } await fileService.writeFile(joinPath(folder, segments[segments.length - 1]), VSBuffer.fromString(file.contents)); } + return true; } function toSafeRelativePathSegments(path: string): string[] { diff --git a/src/vs/workbench/contrib/chat/electron-browser/actions/exportAgentHostDebugLogsService.ts b/src/vs/workbench/contrib/chat/electron-browser/actions/exportAgentHostDebugLogsService.ts index 1096dc36e45133..ccabb1182e51dc 100644 --- a/src/vs/workbench/contrib/chat/electron-browser/actions/exportAgentHostDebugLogsService.ts +++ b/src/vs/workbench/contrib/chat/electron-browser/actions/exportAgentHostDebugLogsService.ts @@ -19,7 +19,7 @@ class NativeAgentHostDebugLogsExportService implements IAgentHostDebugLogsExport @INativeHostService private readonly nativeHostService: INativeHostService, ) { } - async save(exportName: string, files: readonly { path: string; contents: string }[]): Promise { + async save(exportName: string, files: readonly { path: string; contents: string }[]): Promise { const defaultUri = joinPath(await this.fileDialogService.preferredHome(Schemas.file), `${exportName}.zip`); const saveUri = await this.fileDialogService.showSaveDialog({ title: localize('exportDebugLogs.saveDialogTitle', "Export Agent Host Debug Logs"), @@ -29,10 +29,11 @@ class NativeAgentHostDebugLogsExportService implements IAgentHostDebugLogsExport }); if (!saveUri) { - return; + return false; } await this.nativeHostService.createZipFile(saveUri, [...files]); + return true; } }