@theia/ai-ide 1.67.0-next.0 → 1.67.0-next.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/lib/browser/context-file-validation-service-impl.d.ts +13 -0
  2. package/lib/browser/context-file-validation-service-impl.d.ts.map +1 -0
  3. package/lib/browser/context-file-validation-service-impl.js +123 -0
  4. package/lib/browser/context-file-validation-service-impl.js.map +1 -0
  5. package/lib/browser/context-file-validation-service-impl.spec.d.ts +2 -0
  6. package/lib/browser/context-file-validation-service-impl.spec.d.ts.map +1 -0
  7. package/lib/browser/context-file-validation-service-impl.spec.js +340 -0
  8. package/lib/browser/context-file-validation-service-impl.spec.js.map +1 -0
  9. package/lib/browser/context-functions.d.ts +2 -0
  10. package/lib/browser/context-functions.d.ts.map +1 -1
  11. package/lib/browser/context-functions.js +41 -5
  12. package/lib/browser/context-functions.js.map +1 -1
  13. package/lib/browser/context-functions.spec.js +120 -0
  14. package/lib/browser/context-functions.spec.js.map +1 -1
  15. package/lib/browser/frontend-module.d.ts.map +1 -1
  16. package/lib/browser/frontend-module.js +4 -0
  17. package/lib/browser/frontend-module.js.map +1 -1
  18. package/lib/browser/workspace-functions.d.ts +3 -0
  19. package/lib/browser/workspace-functions.d.ts.map +1 -1
  20. package/lib/browser/workspace-functions.js +56 -0
  21. package/lib/browser/workspace-functions.js.map +1 -1
  22. package/package.json +21 -21
  23. package/src/browser/context-file-validation-service-impl.spec.ts +405 -0
  24. package/src/browser/context-file-validation-service-impl.ts +120 -0
  25. package/src/browser/context-functions.spec.ts +155 -1
  26. package/src/browser/context-functions.ts +40 -6
  27. package/src/browser/frontend-module.ts +5 -0
  28. package/src/browser/workspace-functions.ts +68 -1
@@ -0,0 +1,13 @@
1
+ import { URI } from '@theia/core';
2
+ import { FileService } from '@theia/filesystem/lib/browser/file-service';
3
+ import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
4
+ import { ContextFileValidationService, FileValidationResult } from '@theia/ai-chat/lib/browser/context-file-validation-service';
5
+ import { WorkspaceFunctionScope } from './workspace-functions';
6
+ export declare class ContextFileValidationServiceImpl implements ContextFileValidationService {
7
+ protected readonly fileService: FileService;
8
+ protected readonly workspaceScope: WorkspaceFunctionScope;
9
+ protected readonly workspaceService: WorkspaceService;
10
+ validateFile(pathOrUri: string | URI): Promise<FileValidationResult>;
11
+ protected findInSecondaryWorkspaceRoots(pathOrUri: string | URI): Promise<URI | undefined>;
12
+ }
13
+ //# sourceMappingURL=context-file-validation-service-impl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-file-validation-service-impl.d.ts","sourceRoot":"","sources":["../../src/browser/context-file-validation-service-impl.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AAClF,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAuB,MAAM,4DAA4D,CAAC;AACrJ,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,qBACa,gCAAiC,YAAW,4BAA4B;IAGjF,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAG5C,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,sBAAsB,CAAC;IAG1D,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAEhD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC;cAmD1D,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;CAiCnG"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2025 EclipseSource GmbH.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.ContextFileValidationServiceImpl = void 0;
19
+ const tslib_1 = require("tslib");
20
+ const inversify_1 = require("@theia/core/shared/inversify");
21
+ const core_1 = require("@theia/core");
22
+ const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
23
+ const workspace_service_1 = require("@theia/workspace/lib/browser/workspace-service");
24
+ const context_file_validation_service_1 = require("@theia/ai-chat/lib/browser/context-file-validation-service");
25
+ const workspace_functions_1 = require("./workspace-functions");
26
+ let ContextFileValidationServiceImpl = class ContextFileValidationServiceImpl {
27
+ async validateFile(pathOrUri) {
28
+ try {
29
+ const resolvedUri = await this.workspaceScope.resolveToUri(pathOrUri);
30
+ if (!resolvedUri) {
31
+ return {
32
+ state: context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND,
33
+ message: 'File does not exist'
34
+ };
35
+ }
36
+ const exists = await this.fileService.exists(resolvedUri);
37
+ if (!exists) {
38
+ const secondaryRootUri = await this.findInSecondaryWorkspaceRoots(pathOrUri);
39
+ if (secondaryRootUri) {
40
+ return {
41
+ state: context_file_validation_service_1.FileValidationState.INVALID_SECONDARY,
42
+ message: 'File is in a secondary workspace root. AI agents can only access files in the first workspace root.'
43
+ };
44
+ }
45
+ return {
46
+ state: context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND,
47
+ message: 'File does not exist'
48
+ };
49
+ }
50
+ if (this.workspaceScope.isInPrimaryWorkspace(resolvedUri)) {
51
+ return {
52
+ state: context_file_validation_service_1.FileValidationState.VALID
53
+ };
54
+ }
55
+ if (this.workspaceScope.isInWorkspace(resolvedUri)) {
56
+ return {
57
+ state: context_file_validation_service_1.FileValidationState.INVALID_SECONDARY,
58
+ message: 'File is in a secondary workspace root. AI agents can only access files in the first workspace root.'
59
+ };
60
+ }
61
+ return {
62
+ state: context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND,
63
+ message: 'File does not exist in the workspace'
64
+ };
65
+ }
66
+ catch (error) {
67
+ return {
68
+ state: context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND,
69
+ message: 'File does not exist'
70
+ };
71
+ }
72
+ }
73
+ async findInSecondaryWorkspaceRoots(pathOrUri) {
74
+ const roots = this.workspaceService.tryGetRoots();
75
+ if (roots.length <= 1) {
76
+ return undefined;
77
+ }
78
+ for (let i = 1; i < roots.length; i++) {
79
+ const root = roots[i];
80
+ let candidateUri;
81
+ if (pathOrUri instanceof core_1.URI) {
82
+ candidateUri = pathOrUri;
83
+ }
84
+ else if (pathOrUri.includes('://')) {
85
+ try {
86
+ candidateUri = new core_1.URI(pathOrUri);
87
+ }
88
+ catch {
89
+ continue;
90
+ }
91
+ }
92
+ else {
93
+ candidateUri = root.resource.resolve(pathOrUri);
94
+ }
95
+ try {
96
+ if (await this.fileService.exists(candidateUri)) {
97
+ return candidateUri;
98
+ }
99
+ }
100
+ catch {
101
+ continue;
102
+ }
103
+ }
104
+ return undefined;
105
+ }
106
+ };
107
+ exports.ContextFileValidationServiceImpl = ContextFileValidationServiceImpl;
108
+ tslib_1.__decorate([
109
+ (0, inversify_1.inject)(file_service_1.FileService),
110
+ tslib_1.__metadata("design:type", file_service_1.FileService)
111
+ ], ContextFileValidationServiceImpl.prototype, "fileService", void 0);
112
+ tslib_1.__decorate([
113
+ (0, inversify_1.inject)(workspace_functions_1.WorkspaceFunctionScope),
114
+ tslib_1.__metadata("design:type", workspace_functions_1.WorkspaceFunctionScope)
115
+ ], ContextFileValidationServiceImpl.prototype, "workspaceScope", void 0);
116
+ tslib_1.__decorate([
117
+ (0, inversify_1.inject)(workspace_service_1.WorkspaceService),
118
+ tslib_1.__metadata("design:type", workspace_service_1.WorkspaceService)
119
+ ], ContextFileValidationServiceImpl.prototype, "workspaceService", void 0);
120
+ exports.ContextFileValidationServiceImpl = ContextFileValidationServiceImpl = tslib_1.__decorate([
121
+ (0, inversify_1.injectable)()
122
+ ], ContextFileValidationServiceImpl);
123
+ //# sourceMappingURL=context-file-validation-service-impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-file-validation-service-impl.js","sourceRoot":"","sources":["../../src/browser/context-file-validation-service-impl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=context-file-validation-service-impl.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-file-validation-service-impl.spec.d.ts","sourceRoot":"","sources":["../../src/browser/context-file-validation-service-impl.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,340 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2025 EclipseSource GmbH.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const jsdom_1 = require("@theia/core/lib/browser/test/jsdom");
19
+ let disableJSDOM = (0, jsdom_1.enableJSDOM)();
20
+ const frontend_application_config_provider_1 = require("@theia/core/lib/browser/frontend-application-config-provider");
21
+ frontend_application_config_provider_1.FrontendApplicationConfigProvider.set({});
22
+ const chai_1 = require("chai");
23
+ const inversify_1 = require("@theia/core/shared/inversify");
24
+ const core_1 = require("@theia/core");
25
+ const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
26
+ const workspace_service_1 = require("@theia/workspace/lib/browser/workspace-service");
27
+ const context_file_validation_service_1 = require("@theia/ai-chat/lib/browser/context-file-validation-service");
28
+ const context_file_validation_service_impl_1 = require("./context-file-validation-service-impl");
29
+ const workspace_functions_1 = require("./workspace-functions");
30
+ disableJSDOM();
31
+ describe('ContextFileValidationService', () => {
32
+ let container;
33
+ let validationService;
34
+ let mockFileService;
35
+ let mockWorkspaceService;
36
+ let mockPreferenceService;
37
+ const workspaceRoot = new core_1.URI('file:///home/user/workspace');
38
+ // Store URIs as actual URI strings, exactly as URI.toString() would produce them
39
+ const existingFiles = new Map([
40
+ // Files inside workspace
41
+ ['file:///home/user/workspace/src/index.tsx', true],
42
+ ['file:///home/user/workspace/package.json', true],
43
+ ['file:///home/user/workspace/README.md', true],
44
+ ['file:///home/user/workspace/src/components/Button.tsx', true],
45
+ ['file:///home/user/workspace/config.json', true],
46
+ ['file:///home/user/workspace/src/file%20with%20spaces.tsx', true],
47
+ // Files outside workspace (these exist but should be rejected)
48
+ ['file:///etc/passwd', true],
49
+ ['file:///etc/hosts', true],
50
+ ['file:///home/other-user/secret.txt', true],
51
+ ['file:///tmp/temporary-file.log', true]
52
+ ]);
53
+ before(() => {
54
+ disableJSDOM = (0, jsdom_1.enableJSDOM)();
55
+ });
56
+ after(() => {
57
+ disableJSDOM();
58
+ });
59
+ beforeEach(async () => {
60
+ container = new inversify_1.Container();
61
+ // Mock WorkspaceService
62
+ mockWorkspaceService = {
63
+ tryGetRoots: () => [{
64
+ resource: workspaceRoot,
65
+ isDirectory: true
66
+ }],
67
+ roots: Promise.resolve([{
68
+ resource: workspaceRoot,
69
+ isDirectory: true
70
+ }])
71
+ };
72
+ // Mock FileService
73
+ mockFileService = {
74
+ exists: async (uri) => {
75
+ const normalizedUri = uri.path.normalize();
76
+ const normalizedUriString = uri.withPath(normalizedUri).toString();
77
+ const uriString = uri.toString();
78
+ const exists = (existingFiles.has(uriString) && existingFiles.get(uriString) === true) ||
79
+ (existingFiles.has(normalizedUriString) && existingFiles.get(normalizedUriString) === true);
80
+ return exists;
81
+ },
82
+ resolve: async (uri) => {
83
+ const uriString = uri.toString();
84
+ if (existingFiles.has(uriString) && existingFiles.get(uriString) === true) {
85
+ return {
86
+ resource: uri,
87
+ isDirectory: false
88
+ };
89
+ }
90
+ throw new Error('File not found');
91
+ }
92
+ };
93
+ // Mock PreferenceService
94
+ mockPreferenceService = {
95
+ get: () => false
96
+ };
97
+ container.bind(file_service_1.FileService).toConstantValue(mockFileService);
98
+ container.bind(workspace_service_1.WorkspaceService).toConstantValue(mockWorkspaceService);
99
+ container.bind(core_1.PreferenceService).toConstantValue(mockPreferenceService);
100
+ container.bind(workspace_functions_1.WorkspaceFunctionScope).toSelf();
101
+ container.bind(context_file_validation_service_impl_1.ContextFileValidationServiceImpl).toSelf();
102
+ container.bind(context_file_validation_service_1.ContextFileValidationService).toService(context_file_validation_service_impl_1.ContextFileValidationServiceImpl);
103
+ validationService = await container.getAsync(context_file_validation_service_1.ContextFileValidationService);
104
+ });
105
+ describe('validateFile with relative paths', () => {
106
+ it('should validate existing file with relative path', async () => {
107
+ const result = await validationService.validateFile('src/index.tsx');
108
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
109
+ });
110
+ it('should reject non-existing file with relative path', async () => {
111
+ const result = await validationService.validateFile('src/missing.tsx');
112
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
113
+ });
114
+ it('should validate nested file with relative path', async () => {
115
+ const result = await validationService.validateFile('src/components/Button.tsx');
116
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
117
+ });
118
+ it('should validate file in root with relative path', async () => {
119
+ const result = await validationService.validateFile('package.json');
120
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
121
+ });
122
+ });
123
+ describe('validateFile with absolute file paths', () => {
124
+ it('should validate existing file with absolute path within workspace', async () => {
125
+ const result = await validationService.validateFile('/home/user/workspace/src/index.tsx');
126
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
127
+ });
128
+ it('should reject non-existing file with absolute path within workspace', async () => {
129
+ const result = await validationService.validateFile('/home/user/workspace/src/missing.tsx');
130
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
131
+ });
132
+ it('should reject existing file with absolute path outside workspace (/etc/passwd)', async () => {
133
+ const result = await validationService.validateFile('/etc/passwd');
134
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
135
+ });
136
+ it('should reject existing file with absolute path outside workspace (/etc/hosts)', async () => {
137
+ const result = await validationService.validateFile('/etc/hosts');
138
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
139
+ });
140
+ it('should reject existing file with absolute path in other user directory', async () => {
141
+ const result = await validationService.validateFile('/home/other-user/secret.txt');
142
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
143
+ });
144
+ it('should reject existing file with absolute path in /tmp', async () => {
145
+ const result = await validationService.validateFile('/tmp/temporary-file.log');
146
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
147
+ });
148
+ it('should reject non-existing file with absolute path outside workspace', async () => {
149
+ const result = await validationService.validateFile('/var/log/nonexistent.log');
150
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
151
+ });
152
+ it('should validate nested file with absolute path within workspace', async () => {
153
+ const result = await validationService.validateFile('/home/user/workspace/src/components/Button.tsx');
154
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
155
+ });
156
+ });
157
+ describe('validateFile with file:// URIs', () => {
158
+ it('should validate existing file with file:// URI within workspace', async () => {
159
+ const result = await validationService.validateFile('file:///home/user/workspace/src/index.tsx');
160
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
161
+ });
162
+ it('should reject non-existing file with file:// URI within workspace', async () => {
163
+ const result = await validationService.validateFile('file:///home/user/workspace/src/missing.tsx');
164
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
165
+ });
166
+ it('should reject existing file with file:// URI outside workspace (/etc/passwd)', async () => {
167
+ const result = await validationService.validateFile('file:///etc/passwd');
168
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
169
+ });
170
+ it('should reject existing file with file:// URI outside workspace (/etc/hosts)', async () => {
171
+ const result = await validationService.validateFile('file:///etc/hosts');
172
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
173
+ });
174
+ it('should reject existing file with file:// URI in other user directory', async () => {
175
+ const result = await validationService.validateFile('file:///home/other-user/secret.txt');
176
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
177
+ });
178
+ it('should reject existing file with file:// URI in /tmp', async () => {
179
+ const result = await validationService.validateFile('file:///tmp/temporary-file.log');
180
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
181
+ });
182
+ it('should reject non-existing file with file:// URI outside workspace', async () => {
183
+ const result = await validationService.validateFile('file:///var/log/nonexistent.log');
184
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
185
+ });
186
+ it('should validate file at workspace root with file:// URI', async () => {
187
+ const result = await validationService.validateFile('file:///home/user/workspace/package.json');
188
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
189
+ });
190
+ });
191
+ describe('validateFile with URI objects', () => {
192
+ it('should validate existing file with URI object within workspace', async () => {
193
+ const uri = new core_1.URI('file:///home/user/workspace/src/index.tsx');
194
+ const result = await validationService.validateFile(uri);
195
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
196
+ });
197
+ it('should reject non-existing file with URI object within workspace', async () => {
198
+ const uri = new core_1.URI('file:///home/user/workspace/src/missing.tsx');
199
+ const result = await validationService.validateFile(uri);
200
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
201
+ });
202
+ it('should reject existing file with URI object outside workspace', async () => {
203
+ const uri = new core_1.URI('file:///etc/passwd');
204
+ const result = await validationService.validateFile(uri);
205
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
206
+ });
207
+ it('should reject another existing file with URI object outside workspace', async () => {
208
+ const uri = new core_1.URI('file:///home/other-user/secret.txt');
209
+ const result = await validationService.validateFile(uri);
210
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
211
+ });
212
+ });
213
+ describe('validateFile with no workspace', () => {
214
+ beforeEach(async () => {
215
+ // Override mock to return no workspace roots
216
+ mockWorkspaceService.tryGetRoots = () => [];
217
+ });
218
+ it('should reject any file when no workspace is open', async () => {
219
+ const result = await validationService.validateFile('src/index.tsx');
220
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
221
+ });
222
+ it('should reject absolute path when no workspace is open', async () => {
223
+ const result = await validationService.validateFile('/home/user/file.txt');
224
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
225
+ });
226
+ it('should reject file:// URI when no workspace is open', async () => {
227
+ const result = await validationService.validateFile('file:///home/user/file.txt');
228
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
229
+ });
230
+ });
231
+ describe('validateFile with multiple workspace roots', () => {
232
+ const workspaceRoot2 = new core_1.URI('file:///home/user/other-project');
233
+ beforeEach(async () => {
234
+ // Override mock to return multiple workspace roots
235
+ mockWorkspaceService.tryGetRoots = () => [
236
+ {
237
+ resource: workspaceRoot,
238
+ isDirectory: true
239
+ },
240
+ {
241
+ resource: workspaceRoot2,
242
+ isDirectory: true
243
+ }
244
+ ];
245
+ // Add files in the second workspace
246
+ existingFiles.set('file:///home/user/other-project/index.js', true);
247
+ existingFiles.set('file:///home/user/other-project/lib/utils.js', true);
248
+ });
249
+ afterEach(() => {
250
+ // Clean up files added for this test
251
+ existingFiles.delete('file:///home/user/other-project/index.js');
252
+ existingFiles.delete('file:///home/user/other-project/lib/utils.js');
253
+ });
254
+ it('should validate file in first workspace root', async () => {
255
+ const result = await validationService.validateFile('src/index.tsx');
256
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
257
+ });
258
+ it('should validate file in second workspace root with relative path', async () => {
259
+ const result = await validationService.validateFile('index.js');
260
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_SECONDARY);
261
+ });
262
+ it('should validate file in second workspace root with absolute path', async () => {
263
+ const result = await validationService.validateFile('/home/user/other-project/index.js');
264
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_SECONDARY);
265
+ });
266
+ it('should validate file in second workspace root with file:// URI', async () => {
267
+ const result = await validationService.validateFile('file:///home/user/other-project/lib/utils.js');
268
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_SECONDARY);
269
+ });
270
+ it('should still reject files outside both workspace roots', async () => {
271
+ const result = await validationService.validateFile('/etc/passwd');
272
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
273
+ });
274
+ });
275
+ describe('validateFile error handling', () => {
276
+ it('should return false when FileService.exists throws error', async () => {
277
+ mockFileService.exists = async () => {
278
+ throw new Error('Permission denied');
279
+ };
280
+ const result = await validationService.validateFile('src/index.tsx');
281
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
282
+ });
283
+ it('should handle Windows-style paths', async () => {
284
+ // Add a Windows path to existing files
285
+ // Note: URI encoding will convert 'c:' to 'c%3A'
286
+ const windowsRoot = new core_1.URI('file:///c:/Users/user/project');
287
+ const windowsFile = new core_1.URI('file:///c:/Users/user/project/file.txt');
288
+ existingFiles.set(windowsFile.toString(), true);
289
+ // Override workspace to use Windows path
290
+ mockWorkspaceService.tryGetRoots = () => [{
291
+ resource: windowsRoot,
292
+ isDirectory: true
293
+ }];
294
+ const result = await validationService.validateFile('file:///c:/Users/user/project/file.txt');
295
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
296
+ // Clean up
297
+ existingFiles.delete(windowsFile.toString());
298
+ });
299
+ it('should reject Windows system files outside workspace', async () => {
300
+ // Add Windows system file
301
+ const windowsSystemFile = 'file:///c:/Windows/System32/config/sam';
302
+ existingFiles.set(windowsSystemFile, true);
303
+ // Keep workspace as Linux for this test
304
+ const result = await validationService.validateFile('file:///c:/Windows/System32/config/sam');
305
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
306
+ // Clean up
307
+ existingFiles.delete(windowsSystemFile);
308
+ });
309
+ });
310
+ describe('edge cases', () => {
311
+ it('should handle paths with special characters', async () => {
312
+ const result = await validationService.validateFile('file:///home/user/workspace/src/file%20with%20spaces.tsx');
313
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
314
+ });
315
+ it('should handle paths with normalized separators', async () => {
316
+ const result = await validationService.validateFile('src\\components\\Button.tsx');
317
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.VALID);
318
+ });
319
+ it('should reject empty path', async () => {
320
+ const result = await validationService.validateFile('');
321
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
322
+ });
323
+ it('should reject parent directory references in relative paths', async () => {
324
+ // Parent directory references are not allowed for security and clarity
325
+ const result = await validationService.validateFile('src/../config.json');
326
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
327
+ });
328
+ it('should reject path traversal attempts with parent directory references', async () => {
329
+ // Path traversal attempts should be rejected
330
+ const result = await validationService.validateFile('../../../../../../etc/passwd');
331
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
332
+ });
333
+ it('should reject absolute paths with parent directory references', async () => {
334
+ // Even absolute paths with .. should be rejected for consistency
335
+ const result = await validationService.validateFile('/home/user/workspace/src/../config.json');
336
+ (0, chai_1.expect)(result.state).to.equal(context_file_validation_service_1.FileValidationState.INVALID_NOT_FOUND);
337
+ });
338
+ });
339
+ });
340
+ //# sourceMappingURL=context-file-validation-service-impl.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-file-validation-service-impl.spec.js","sourceRoot":"","sources":["../../src/browser/context-file-validation-service-impl.spec.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { ToolProvider, ToolRequest } from '@theia/ai-core';
2
+ import { ContextFileValidationService } from '@theia/ai-chat/lib/browser/context-file-validation-service';
2
3
  export declare class ListChatContext implements ToolProvider {
3
4
  static ID: string;
4
5
  getTool(): ToolRequest;
@@ -9,6 +10,7 @@ export declare class ResolveChatContext implements ToolProvider {
9
10
  }
10
11
  export declare class AddFileToChatContext implements ToolProvider {
11
12
  static ID: string;
13
+ protected readonly validationService: ContextFileValidationService | undefined;
12
14
  getTool(): ToolRequest;
13
15
  }
14
16
  //# sourceMappingURL=context-functions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-functions.d.ts","sourceRoot":"","sources":["../../src/browser/context-functions.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAK3D,qBACa,eAAgB,YAAW,YAAY;IAChD,MAAM,CAAC,EAAE,SAAiC;IAE1C,OAAO,IAAI,WAAW;CAqBzB;AAED,qBACa,kBAAmB,YAAW,YAAY;IACnD,MAAM,CAAC,EAAE,SAAoC;IAE7C,OAAO,IAAI,WAAW;CAkCzB;AAED,qBACa,oBAAqB,YAAW,YAAY;IACrD,MAAM,CAAC,EAAE,SAAoC;IAE7C,OAAO,IAAI,WAAW;CA+BzB"}
1
+ {"version":3,"file":"context-functions.d.ts","sourceRoot":"","sources":["../../src/browser/context-functions.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI3D,OAAO,EAAE,4BAA4B,EAAuB,MAAM,4DAA4D,CAAC;AAE/H,qBACa,eAAgB,YAAW,YAAY;IAChD,MAAM,CAAC,EAAE,SAAiC;IAE1C,OAAO,IAAI,WAAW;CAqBzB;AAED,qBACa,kBAAmB,YAAW,YAAY;IACnD,MAAM,CAAC,EAAE,SAAoC;IAE7C,OAAO,IAAI,WAAW;CAkCzB;AAED,qBACa,oBAAqB,YAAW,YAAY;IACrD,MAAM,CAAC,EAAE,SAAoC;IAG7C,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,4BAA4B,GAAG,SAAS,CAAC;IAE/E,OAAO,IAAI,WAAW;CA6DzB"}
@@ -21,6 +21,7 @@ const tslib_1 = require("tslib");
21
21
  const inversify_1 = require("@theia/core/shared/inversify");
22
22
  const context_functions_1 = require("../common/context-functions");
23
23
  const file_variable_contribution_1 = require("@theia/ai-core/lib/browser/file-variable-contribution");
24
+ const context_file_validation_service_1 = require("@theia/ai-chat/lib/browser/context-file-validation-service");
24
25
  let ListChatContext = ListChatContext_1 = class ListChatContext {
25
26
  getTool() {
26
27
  return {
@@ -107,23 +108,58 @@ let AddFileToChatContext = AddFileToChatContext_1 = class AddFileToChatContext {
107
108
  },
108
109
  required: ['filesToAdd']
109
110
  },
110
- description: 'Adds one or more files to the context of the current chat session, and returns the current list of files in the context.',
111
+ description: 'Adds one or more files to the context of the current chat session. ' +
112
+ 'Only files that exist within the workspace boundaries will be added. ' +
113
+ 'Files outside the workspace or non-existent files will be rejected. ' +
114
+ 'Returns a detailed status for each file, including which were successfully added and which were rejected with reasons.',
111
115
  handler: async (arg, ctx) => {
112
116
  var _a, _b;
113
117
  if ((_b = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.response) === null || _a === void 0 ? void 0 : _a.cancellationToken) === null || _b === void 0 ? void 0 : _b.isCancellationRequested) {
114
118
  return JSON.stringify({ error: 'Operation cancelled by user' });
115
119
  }
116
120
  const { filesToAdd } = JSON.parse(arg);
117
- ctx.session.context.addVariables(...filesToAdd.map(file => ({ arg: file, variable: file_variable_contribution_1.FILE_VARIABLE })));
118
- const result = ctx.session.context.getVariables().filter(candidate => candidate.variable.id === file_variable_contribution_1.FILE_VARIABLE.id && !!candidate.arg)
119
- .map(fileRequest => fileRequest.arg);
120
- return JSON.stringify(result);
121
+ const added = [];
122
+ const rejected = [];
123
+ for (const file of filesToAdd) {
124
+ if (this.validationService) {
125
+ const validationResult = await this.validationService.validateFile(file);
126
+ if (validationResult.state === context_file_validation_service_1.FileValidationState.VALID) {
127
+ ctx.session.context.addVariables({ arg: file, variable: file_variable_contribution_1.FILE_VARIABLE });
128
+ added.push(file);
129
+ }
130
+ else {
131
+ rejected.push({
132
+ file,
133
+ reason: validationResult.message || 'File validation failed',
134
+ state: validationResult.state
135
+ });
136
+ }
137
+ }
138
+ else {
139
+ ctx.session.context.addVariables({ arg: file, variable: file_variable_contribution_1.FILE_VARIABLE });
140
+ added.push(file);
141
+ }
142
+ }
143
+ return JSON.stringify({
144
+ added,
145
+ rejected,
146
+ summary: {
147
+ totalRequested: filesToAdd.length,
148
+ added: added.length,
149
+ rejected: rejected.length
150
+ }
151
+ });
121
152
  }
122
153
  };
123
154
  }
124
155
  };
125
156
  exports.AddFileToChatContext = AddFileToChatContext;
126
157
  AddFileToChatContext.ID = context_functions_1.UPDATE_CONTEXT_FILES_FUNCTION_ID;
158
+ tslib_1.__decorate([
159
+ (0, inversify_1.inject)(context_file_validation_service_1.ContextFileValidationService),
160
+ (0, inversify_1.optional)(),
161
+ tslib_1.__metadata("design:type", Object)
162
+ ], AddFileToChatContext.prototype, "validationService", void 0);
127
163
  exports.AddFileToChatContext = AddFileToChatContext = AddFileToChatContext_1 = tslib_1.__decorate([
128
164
  (0, inversify_1.injectable)()
129
165
  ], AddFileToChatContext);