Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/agentHost/test/node/copilotShellTools.test.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
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 assert from 'assert';
7
import { URI } from '../../../../base/common/uri.js';
8
import { Disposable, DisposableStore, type IDisposable } from '../../../../base/common/lifecycle.js';
9
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
10
import { IInstantiationService } from '../../../instantiation/common/instantiation.js';
11
import { InstantiationService } from '../../../instantiation/common/instantiationService.js';
12
import { ServiceCollection } from '../../../instantiation/common/serviceCollection.js';
13
import { ILogService, NullLogService } from '../../../log/common/log.js';
14
import type { CreateTerminalParams } from '../../common/state/protocol/commands.js';
15
import type { TerminalClaim, TerminalInfo } from '../../common/state/protocol/state.js';
16
import { IAgentHostTerminalManager } from '../../node/agentHostTerminalManager.js';
17
import { ShellManager, prefixForHistorySuppression } from '../../node/copilot/copilotShellTools.js';
18
19
class TestAgentHostTerminalManager implements IAgentHostTerminalManager {
20
declare readonly _serviceBrand: undefined;
21
22
readonly created: { params: CreateTerminalParams; options?: { shell?: string; preventShellHistory?: boolean; nonInteractive?: boolean } }[] = [];
23
24
async createTerminal(params: CreateTerminalParams, options?: { shell?: string; preventShellHistory?: boolean; nonInteractive?: boolean }): Promise<void> {
25
this.created.push({ params, options });
26
}
27
writeInput(): void { }
28
onData(): IDisposable { return Disposable.None; }
29
onExit(): IDisposable { return Disposable.None; }
30
onClaimChanged(): IDisposable { return Disposable.None; }
31
onCommandFinished(): IDisposable { return Disposable.None; }
32
getContent(): string | undefined { return undefined; }
33
getClaim(): TerminalClaim | undefined { return undefined; }
34
hasTerminal(): boolean { return false; }
35
getExitCode(): number | undefined { return undefined; }
36
supportsCommandDetection(): boolean { return false; }
37
disposeTerminal(): void { }
38
getTerminalInfos(): TerminalInfo[] { return []; }
39
getTerminalState(): undefined { return undefined; }
40
}
41
42
suite('CopilotShellTools', () => {
43
44
const disposables = new DisposableStore();
45
46
teardown(() => disposables.clear());
47
ensureNoDisposablesAreLeakedInTestSuite();
48
49
test('uses session working directory for created shells', async () => {
50
const terminalManager = new TestAgentHostTerminalManager();
51
const services = new ServiceCollection();
52
services.set(ILogService, new NullLogService());
53
services.set(IAgentHostTerminalManager, terminalManager);
54
const instantiationService: IInstantiationService = disposables.add(new InstantiationService(services));
55
services.set(IInstantiationService, instantiationService);
56
const worktreePath = URI.file('/workspace/worktree').fsPath;
57
const explicitCwd = URI.file('/explicit/cwd').fsPath;
58
const shellManager = disposables.add(instantiationService.createInstance(ShellManager, URI.parse('copilot:/session-1'), URI.file(worktreePath)));
59
60
await shellManager.getOrCreateShell('bash', 'turn-1', 'tool-1');
61
await shellManager.getOrCreateShell('bash', 'turn-2', 'tool-2', explicitCwd);
62
63
assert.deepStrictEqual(terminalManager.created.map(c => c.params.cwd), [
64
worktreePath,
65
explicitCwd,
66
]);
67
});
68
69
test('opts every managed shell into shell-history suppression and non-interactive mode', async () => {
70
const terminalManager = new TestAgentHostTerminalManager();
71
const services = new ServiceCollection();
72
services.set(ILogService, new NullLogService());
73
services.set(IAgentHostTerminalManager, terminalManager);
74
const instantiationService: IInstantiationService = disposables.add(new InstantiationService(services));
75
services.set(IInstantiationService, instantiationService);
76
const shellManager = disposables.add(instantiationService.createInstance(ShellManager, URI.parse('copilot:/session-1'), undefined));
77
78
await shellManager.getOrCreateShell('bash', 'turn-1', 'tool-1');
79
80
assert.strictEqual(terminalManager.created.length, 1);
81
assert.strictEqual(terminalManager.created[0].options?.preventShellHistory, true);
82
assert.strictEqual(terminalManager.created[0].options?.nonInteractive, true);
83
});
84
85
test('prefixForHistorySuppression prepends a space for POSIX shells, no-op for PowerShell', () => {
86
assert.strictEqual(prefixForHistorySuppression('bash'), ' ');
87
assert.strictEqual(prefixForHistorySuppression('powershell'), '');
88
});
89
});
90
91