2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { IDisposable } from '../../../../../../base/common/lifecycle.js';
7
>
import { ResourceMap, ResourceSet } from '../../../../../../base/common/map.js';
8
>
import { dirname, extUriBiasedIgnorePathCase } from '../../../../../../base/common/resources.js';
9
>
import { URI } from '../../../../../../base/common/uri.js';
10
>
import { localize } from '../../../../../../nls.js';
11
>
import { ILabelService } from '../../../../../../platform/label/common/label.js';
12
>
import { ObservableMemento, observableMemento } from '../../../../../../platform/observable/common/observableMemento.js';
13
>
import { IStorageService, StorageScope, StorageTarget } from '../../../../../../platform/storage/common/storage.js';
14
>
import { ConfirmedReason, ToolConfirmKind } from '../../chatService/chatService.js';
15
>
import {
16
>
ILanguageModelToolConfirmationActions,
17
>
ILanguageModelToolConfirmationContribution,
18
>
ILanguageModelToolConfirmationContributionQuickTreeItem,
19
>
ILanguageModelToolConfirmationRef
20
>
} from '../languageModelToolsConfirmationService.js';
21
>
22
>
const workspaceAllowlistMemento = observableMemento<readonly string[]>({
23
>
key: 'chat.externalPath.workspaceAllowlist',
24
>
defaultValue: [],
25
>
toStorage: value => JSON.stringify(value),
26
>
fromStorage: value => {
27
const parsed = JSON.parse(value);
28
return Array.isArray(parsed) ? parsed : [];
29
},
31
>
32
>
export interface IExternalPathInfo {
33
>
path: string;
34
>
isDirectory: boolean;
35
>
}
36
>
37
>
/**
38
>
* Confirmation contribution for read_file and list_dir tools that allows users to approve
39
>
* accessing paths outside the workspace, with an option to allow all access
40
>
* from a containing folder for the current chat session.
41
>
*/
42
>
export class ChatExternalPathConfirmationContribution implements ILanguageModelToolConfirmationContribution, IDisposable {
43
>
readonly canUseDefaultApprovals = false;
44
>
45
>
private readonly _sessionFolderAllowlist = new ResourceMap<ResourceSet>();
46
>
/** Cache of path URI -> resolved git root URI (or null if not in a repo) */
47
>
private readonly _gitRootCache = new ResourceMap<URI | null>();
48
>
private readonly _workspaceAllowlist?: ObservableMemento<readonly string[]>;
49
>
50
>
constructor(
51
>
private readonly _getPathInfo: (ref: ILanguageModelToolConfirmationRef) => IExternalPathInfo | undefined,
52
>
private readonly _labelService: ILabelService,
53
>
private readonly _findGitRoot?: (pathUri: URI) => Promise<URI | undefined>,
54
>
storageService?: IStorageService,
55
>
private readonly _pickFolder?: () => Promise<URI | undefined>,
56
>
) {
57
>
if (storageService) {
58
this._workspaceAllowlist = workspaceAllowlistMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE, storageService);
59
}
61
>
62
>
dispose(): void {
63
>
this._workspaceAllowlist?.dispose();
64
>
}
65
>
66
>
private _getWorkspaceFolders(): ResourceSet {
67
if (!this._workspaceAllowlist) {
68
return new ResourceSet();