@google/gemini-cli 0.12.0-preview.0 → 0.13.0-nightly.20251030.42c79c64
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.
- package/dist/package.json +2 -2
- package/dist/src/config/auth.js +0 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/auth.test.js +1 -3
- package/dist/src/config/auth.test.js.map +1 -1
- package/dist/src/config/sandboxConfig.d.ts +1 -1
- package/dist/src/config/sandboxConfig.js +6 -3
- package/dist/src/config/sandboxConfig.js.map +1 -1
- package/dist/src/config/settings.js +1 -1
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/gemini.js +8 -1
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +1 -0
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/nonInteractiveCli.d.ts +9 -1
- package/dist/src/nonInteractiveCli.js +16 -1
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.test.js +209 -103
- package/dist/src/nonInteractiveCli.test.js.map +1 -1
- package/dist/src/ui/AppContainer.js +32 -3
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/auth/ApiAuthDialog.d.ts +14 -0
- package/dist/src/ui/auth/ApiAuthDialog.js +26 -0
- package/dist/src/ui/auth/ApiAuthDialog.js.map +1 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.d.ts +6 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js +91 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -0
- package/dist/src/ui/auth/AuthDialog.js +7 -3
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/auth/useAuth.d.ts +2 -0
- package/dist/src/ui/auth/useAuth.js +31 -2
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +4 -0
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.js +27 -5
- package/dist/src/ui/components/messages/Todo.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.test.js +19 -7
- package/dist/src/ui/components/messages/Todo.test.js.map +1 -1
- package/dist/src/ui/components/shared/TextInput.d.ts +15 -0
- package/dist/src/ui/components/shared/TextInput.js +38 -0
- package/dist/src/ui/components/shared/TextInput.js.map +1 -0
- package/dist/src/ui/components/shared/TextInput.test.d.ts +6 -0
- package/dist/src/ui/components/shared/TextInput.test.js +242 -0
- package/dist/src/ui/components/shared/TextInput.test.js.map +1 -0
- package/dist/src/ui/components/shared/text-buffer.d.ts +8 -2
- package/dist/src/ui/components/shared/text-buffer.js +28 -13
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.test.js +137 -0
- package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.js +8 -29
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +84 -68
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
- package/dist/src/ui/contexts/UIStateContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +29 -7
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +162 -64
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.js +2 -2
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/types.d.ts +1 -0
- package/dist/src/ui/types.js +2 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/clipboardUtils.js +2 -2
- package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.js +6 -3
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.test.js +5 -1
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
- package/dist/src/utils/commentJson.js +2 -2
- package/dist/src/utils/commentJson.js.map +1 -1
- package/dist/src/utils/commentJson.test.js +7 -6
- package/dist/src/utils/commentJson.test.js.map +1 -1
- package/dist/src/utils/version.js +6 -2
- package/dist/src/utils/version.js.map +1 -1
- package/dist/src/zed-integration/acp.js +2 -1
- package/dist/src/zed-integration/acp.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/src/utils/package.d.ts +0 -12
- package/dist/src/utils/package.js +0 -24
- package/dist/src/utils/package.js.map +0 -1
|
@@ -23,6 +23,9 @@ describe('handleAtCommand', () => {
|
|
|
23
23
|
await fsPromises.writeFile(fullPath, fileContents);
|
|
24
24
|
return path.resolve(testRootDir, fullPath);
|
|
25
25
|
}
|
|
26
|
+
function getRelativePath(absolutePath) {
|
|
27
|
+
return path.relative(testRootDir, absolutePath);
|
|
28
|
+
}
|
|
26
29
|
beforeEach(async () => {
|
|
27
30
|
vi.resetAllMocks();
|
|
28
31
|
testRootDir = await fsPromises.mkdtemp(path.join(os.tmpdir(), 'folder-structure-test-'));
|
|
@@ -103,6 +106,7 @@ describe('handleAtCommand', () => {
|
|
|
103
106
|
it('should process a valid text file path', async () => {
|
|
104
107
|
const fileContent = 'This is the file content.';
|
|
105
108
|
const filePath = await createTestFile(path.join(testRootDir, 'path', 'to', 'file.txt'), fileContent);
|
|
109
|
+
const relativePath = getRelativePath(filePath);
|
|
106
110
|
const query = `@${filePath}`;
|
|
107
111
|
const result = await handleAtCommand({
|
|
108
112
|
query,
|
|
@@ -114,9 +118,9 @@ describe('handleAtCommand', () => {
|
|
|
114
118
|
});
|
|
115
119
|
expect(result).toEqual({
|
|
116
120
|
processedQuery: [
|
|
117
|
-
{ text: `@${
|
|
121
|
+
{ text: `@${relativePath}` },
|
|
118
122
|
{ text: '\n--- Content from referenced files ---' },
|
|
119
|
-
{ text: `\nContent from @${
|
|
123
|
+
{ text: `\nContent from @${relativePath}:\n` },
|
|
120
124
|
{ text: fileContent },
|
|
121
125
|
{ text: '\n--- End of content ---' },
|
|
122
126
|
],
|
|
@@ -131,8 +135,10 @@ describe('handleAtCommand', () => {
|
|
|
131
135
|
const fileContent = 'This is the file content.';
|
|
132
136
|
const filePath = await createTestFile(path.join(testRootDir, 'path', 'to', 'file.txt'), fileContent);
|
|
133
137
|
const dirPath = path.dirname(filePath);
|
|
138
|
+
const relativeDirPath = getRelativePath(dirPath);
|
|
139
|
+
const relativeFilePath = getRelativePath(filePath);
|
|
134
140
|
const query = `@${dirPath}`;
|
|
135
|
-
const resolvedGlob =
|
|
141
|
+
const resolvedGlob = path.join(relativeDirPath, '**');
|
|
136
142
|
const result = await handleAtCommand({
|
|
137
143
|
query,
|
|
138
144
|
config: mockConfig,
|
|
@@ -145,7 +151,7 @@ describe('handleAtCommand', () => {
|
|
|
145
151
|
processedQuery: [
|
|
146
152
|
{ text: `@${resolvedGlob}` },
|
|
147
153
|
{ text: '\n--- Content from referenced files ---' },
|
|
148
|
-
{ text: `\nContent from @${
|
|
154
|
+
{ text: `\nContent from @${relativeFilePath}:\n` },
|
|
149
155
|
{ text: fileContent },
|
|
150
156
|
{ text: '\n--- End of content ---' },
|
|
151
157
|
],
|
|
@@ -156,6 +162,7 @@ describe('handleAtCommand', () => {
|
|
|
156
162
|
it('should handle query with text before and after @command', async () => {
|
|
157
163
|
const fileContent = 'Markdown content.';
|
|
158
164
|
const filePath = await createTestFile(path.join(testRootDir, 'doc.md'), fileContent);
|
|
165
|
+
const relativePath = getRelativePath(filePath);
|
|
159
166
|
const textBefore = 'Explain this: ';
|
|
160
167
|
const textAfter = ' in detail.';
|
|
161
168
|
const query = `${textBefore}@${filePath}${textAfter}`;
|
|
@@ -169,9 +176,9 @@ describe('handleAtCommand', () => {
|
|
|
169
176
|
});
|
|
170
177
|
expect(result).toEqual({
|
|
171
178
|
processedQuery: [
|
|
172
|
-
{ text: `${textBefore}@${
|
|
179
|
+
{ text: `${textBefore}@${relativePath}${textAfter}` },
|
|
173
180
|
{ text: '\n--- Content from referenced files ---' },
|
|
174
|
-
{ text: `\nContent from @${
|
|
181
|
+
{ text: `\nContent from @${relativePath}:\n` },
|
|
175
182
|
{ text: fileContent },
|
|
176
183
|
{ text: '\n--- End of content ---' },
|
|
177
184
|
],
|
|
@@ -193,9 +200,9 @@ describe('handleAtCommand', () => {
|
|
|
193
200
|
});
|
|
194
201
|
expect(result).toEqual({
|
|
195
202
|
processedQuery: [
|
|
196
|
-
{ text: `@${filePath}` },
|
|
203
|
+
{ text: `@${getRelativePath(filePath)}` },
|
|
197
204
|
{ text: '\n--- Content from referenced files ---' },
|
|
198
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
205
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
199
206
|
{ text: fileContent },
|
|
200
207
|
{ text: '\n--- End of content ---' },
|
|
201
208
|
],
|
|
@@ -222,11 +229,13 @@ describe('handleAtCommand', () => {
|
|
|
222
229
|
});
|
|
223
230
|
expect(result).toEqual({
|
|
224
231
|
processedQuery: [
|
|
225
|
-
{
|
|
232
|
+
{
|
|
233
|
+
text: `@${getRelativePath(file1Path)} @${getRelativePath(file2Path)}`,
|
|
234
|
+
},
|
|
226
235
|
{ text: '\n--- Content from referenced files ---' },
|
|
227
|
-
{ text: `\nContent from @${file1Path}:\n` },
|
|
236
|
+
{ text: `\nContent from @${getRelativePath(file1Path)}:\n` },
|
|
228
237
|
{ text: content1 },
|
|
229
|
-
{ text: `\nContent from @${file2Path}:\n` },
|
|
238
|
+
{ text: `\nContent from @${getRelativePath(file2Path)}:\n` },
|
|
230
239
|
{ text: content2 },
|
|
231
240
|
{ text: '\n--- End of content ---' },
|
|
232
241
|
],
|
|
@@ -252,11 +261,13 @@ describe('handleAtCommand', () => {
|
|
|
252
261
|
});
|
|
253
262
|
expect(result).toEqual({
|
|
254
263
|
processedQuery: [
|
|
255
|
-
{
|
|
264
|
+
{
|
|
265
|
+
text: `${text1}@${getRelativePath(file1Path)}${text2}@${getRelativePath(file2Path)}${text3}`,
|
|
266
|
+
},
|
|
256
267
|
{ text: '\n--- Content from referenced files ---' },
|
|
257
|
-
{ text: `\nContent from @${file1Path}:\n` },
|
|
268
|
+
{ text: `\nContent from @${getRelativePath(file1Path)}:\n` },
|
|
258
269
|
{ text: content1 },
|
|
259
|
-
{ text: `\nContent from @${file2Path}:\n` },
|
|
270
|
+
{ text: `\nContent from @${getRelativePath(file2Path)}:\n` },
|
|
260
271
|
{ text: content2 },
|
|
261
272
|
{ text: '\n--- End of content ---' },
|
|
262
273
|
],
|
|
@@ -281,12 +292,12 @@ describe('handleAtCommand', () => {
|
|
|
281
292
|
expect(result).toEqual({
|
|
282
293
|
processedQuery: [
|
|
283
294
|
{
|
|
284
|
-
text: `Look at @${file1Path} then @${invalidFile} and also just @ symbol, then @${file2Path}`,
|
|
295
|
+
text: `Look at @${getRelativePath(file1Path)} then @${invalidFile} and also just @ symbol, then @${getRelativePath(file2Path)}`,
|
|
285
296
|
},
|
|
286
297
|
{ text: '\n--- Content from referenced files ---' },
|
|
287
|
-
{ text: `\nContent from @${file2Path}:\n` },
|
|
298
|
+
{ text: `\nContent from @${getRelativePath(file2Path)}:\n` },
|
|
288
299
|
{ text: content2 },
|
|
289
|
-
{ text: `\nContent from @${file1Path}:\n` },
|
|
300
|
+
{ text: `\nContent from @${getRelativePath(file1Path)}:\n` },
|
|
290
301
|
{ text: content1 },
|
|
291
302
|
{ text: '\n--- End of content ---' },
|
|
292
303
|
],
|
|
@@ -350,9 +361,9 @@ describe('handleAtCommand', () => {
|
|
|
350
361
|
});
|
|
351
362
|
expect(result).toEqual({
|
|
352
363
|
processedQuery: [
|
|
353
|
-
{ text: `@${validFile}` },
|
|
364
|
+
{ text: `@${getRelativePath(validFile)}` },
|
|
354
365
|
{ text: '\n--- Content from referenced files ---' },
|
|
355
|
-
{ text: `\nContent from @${validFile}:\n` },
|
|
366
|
+
{ text: `\nContent from @${getRelativePath(validFile)}:\n` },
|
|
356
367
|
{ text: 'console.log("Hello world");' },
|
|
357
368
|
{ text: '\n--- End of content ---' },
|
|
358
369
|
],
|
|
@@ -374,9 +385,9 @@ describe('handleAtCommand', () => {
|
|
|
374
385
|
});
|
|
375
386
|
expect(result).toEqual({
|
|
376
387
|
processedQuery: [
|
|
377
|
-
{ text: `@${validFile} @${gitIgnoredFile}` },
|
|
388
|
+
{ text: `@${getRelativePath(validFile)} @${gitIgnoredFile}` },
|
|
378
389
|
{ text: '\n--- Content from referenced files ---' },
|
|
379
|
-
{ text: `\nContent from @${validFile}:\n` },
|
|
390
|
+
{ text: `\nContent from @${getRelativePath(validFile)}:\n` },
|
|
380
391
|
{ text: '# Project README' },
|
|
381
392
|
{ text: '\n--- End of content ---' },
|
|
382
393
|
],
|
|
@@ -459,9 +470,9 @@ describe('handleAtCommand', () => {
|
|
|
459
470
|
});
|
|
460
471
|
expect(result).toEqual({
|
|
461
472
|
processedQuery: [
|
|
462
|
-
{ text: `@${validFile}` },
|
|
473
|
+
{ text: `@${getRelativePath(validFile)}` },
|
|
463
474
|
{ text: '\n--- Content from referenced files ---' },
|
|
464
|
-
{ text: `\nContent from @${validFile}:\n` },
|
|
475
|
+
{ text: `\nContent from @${getRelativePath(validFile)}:\n` },
|
|
465
476
|
{ text: 'console.log("Hello world");' },
|
|
466
477
|
{ text: '\n--- End of content ---' },
|
|
467
478
|
],
|
|
@@ -483,9 +494,9 @@ describe('handleAtCommand', () => {
|
|
|
483
494
|
});
|
|
484
495
|
expect(result).toEqual({
|
|
485
496
|
processedQuery: [
|
|
486
|
-
{ text: `@${validFile} @${geminiIgnoredFile}` },
|
|
497
|
+
{ text: `@${getRelativePath(validFile)} @${geminiIgnoredFile}` },
|
|
487
498
|
{ text: '\n--- Content from referenced files ---' },
|
|
488
|
-
{ text: `\nContent from @${validFile}:\n` },
|
|
499
|
+
{ text: `\nContent from @${getRelativePath(validFile)}:\n` },
|
|
489
500
|
{ text: '// Main application entry' },
|
|
490
501
|
{ text: '\n--- End of content ---' },
|
|
491
502
|
],
|
|
@@ -500,77 +511,77 @@ describe('handleAtCommand', () => {
|
|
|
500
511
|
name: 'comma',
|
|
501
512
|
fileName: 'test.txt',
|
|
502
513
|
fileContent: 'File content here',
|
|
503
|
-
queryTemplate: (filePath) => `Look at @${filePath}, then explain it.`,
|
|
514
|
+
queryTemplate: (filePath) => `Look at @${getRelativePath(filePath)}, then explain it.`,
|
|
504
515
|
messageId: 400,
|
|
505
516
|
},
|
|
506
517
|
{
|
|
507
518
|
name: 'period',
|
|
508
519
|
fileName: 'readme.md',
|
|
509
520
|
fileContent: 'File content here',
|
|
510
|
-
queryTemplate: (filePath) => `Check @${filePath}. What does it say?`,
|
|
521
|
+
queryTemplate: (filePath) => `Check @${getRelativePath(filePath)}. What does it say?`,
|
|
511
522
|
messageId: 401,
|
|
512
523
|
},
|
|
513
524
|
{
|
|
514
525
|
name: 'semicolon',
|
|
515
526
|
fileName: 'example.js',
|
|
516
527
|
fileContent: 'Code example',
|
|
517
|
-
queryTemplate: (filePath) => `Review @${filePath}; check for bugs.`,
|
|
528
|
+
queryTemplate: (filePath) => `Review @${getRelativePath(filePath)}; check for bugs.`,
|
|
518
529
|
messageId: 402,
|
|
519
530
|
},
|
|
520
531
|
{
|
|
521
532
|
name: 'exclamation mark',
|
|
522
533
|
fileName: 'important.txt',
|
|
523
534
|
fileContent: 'Important content',
|
|
524
|
-
queryTemplate: (filePath) => `Look at @${filePath}! This is critical.`,
|
|
535
|
+
queryTemplate: (filePath) => `Look at @${getRelativePath(filePath)}! This is critical.`,
|
|
525
536
|
messageId: 403,
|
|
526
537
|
},
|
|
527
538
|
{
|
|
528
539
|
name: 'question mark',
|
|
529
540
|
fileName: 'config.json',
|
|
530
541
|
fileContent: 'Config settings',
|
|
531
|
-
queryTemplate: (filePath) => `What is in @${filePath}? Please explain.`,
|
|
542
|
+
queryTemplate: (filePath) => `What is in @${getRelativePath(filePath)}? Please explain.`,
|
|
532
543
|
messageId: 404,
|
|
533
544
|
},
|
|
534
545
|
{
|
|
535
546
|
name: 'opening parenthesis',
|
|
536
547
|
fileName: 'func.ts',
|
|
537
548
|
fileContent: 'Function definition',
|
|
538
|
-
queryTemplate: (filePath) => `Analyze @${filePath}(the main function).`,
|
|
549
|
+
queryTemplate: (filePath) => `Analyze @${getRelativePath(filePath)}(the main function).`,
|
|
539
550
|
messageId: 405,
|
|
540
551
|
},
|
|
541
552
|
{
|
|
542
553
|
name: 'closing parenthesis',
|
|
543
554
|
fileName: 'data.json',
|
|
544
555
|
fileContent: 'Test data',
|
|
545
|
-
queryTemplate: (filePath) => `Use data from @${filePath}) for testing.`,
|
|
556
|
+
queryTemplate: (filePath) => `Use data from @${getRelativePath(filePath)}) for testing.`,
|
|
546
557
|
messageId: 406,
|
|
547
558
|
},
|
|
548
559
|
{
|
|
549
560
|
name: 'opening square bracket',
|
|
550
561
|
fileName: 'array.js',
|
|
551
562
|
fileContent: 'Array data',
|
|
552
|
-
queryTemplate: (filePath) => `Check @${filePath}[0] for the first element.`,
|
|
563
|
+
queryTemplate: (filePath) => `Check @${getRelativePath(filePath)}[0] for the first element.`,
|
|
553
564
|
messageId: 407,
|
|
554
565
|
},
|
|
555
566
|
{
|
|
556
567
|
name: 'closing square bracket',
|
|
557
568
|
fileName: 'list.md',
|
|
558
569
|
fileContent: 'List content',
|
|
559
|
-
queryTemplate: (filePath) => `Review item @${filePath}] from the list.`,
|
|
570
|
+
queryTemplate: (filePath) => `Review item @${getRelativePath(filePath)}] from the list.`,
|
|
560
571
|
messageId: 408,
|
|
561
572
|
},
|
|
562
573
|
{
|
|
563
574
|
name: 'opening curly brace',
|
|
564
575
|
fileName: 'object.ts',
|
|
565
576
|
fileContent: 'Object definition',
|
|
566
|
-
queryTemplate: (filePath) => `Parse @${filePath}{prop1: value1}.`,
|
|
577
|
+
queryTemplate: (filePath) => `Parse @${getRelativePath(filePath)}{prop1: value1}.`,
|
|
567
578
|
messageId: 409,
|
|
568
579
|
},
|
|
569
580
|
{
|
|
570
581
|
name: 'closing curly brace',
|
|
571
582
|
fileName: 'config.yaml',
|
|
572
583
|
fileContent: 'Configuration',
|
|
573
|
-
queryTemplate: (filePath) => `Use settings from @${filePath}} for deployment.`,
|
|
584
|
+
queryTemplate: (filePath) => `Use settings from @${getRelativePath(filePath)}} for deployment.`,
|
|
574
585
|
messageId: 410,
|
|
575
586
|
},
|
|
576
587
|
];
|
|
@@ -589,7 +600,7 @@ describe('handleAtCommand', () => {
|
|
|
589
600
|
processedQuery: [
|
|
590
601
|
{ text: query },
|
|
591
602
|
{ text: '\n--- Content from referenced files ---' },
|
|
592
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
603
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
593
604
|
{ text: fileContent },
|
|
594
605
|
{ text: '\n--- End of content ---' },
|
|
595
606
|
],
|
|
@@ -612,11 +623,13 @@ describe('handleAtCommand', () => {
|
|
|
612
623
|
});
|
|
613
624
|
expect(result).toEqual({
|
|
614
625
|
processedQuery: [
|
|
615
|
-
{
|
|
626
|
+
{
|
|
627
|
+
text: `Compare @${getRelativePath(file1Path)}, @${getRelativePath(file2Path)}; what's different?`,
|
|
628
|
+
},
|
|
616
629
|
{ text: '\n--- Content from referenced files ---' },
|
|
617
|
-
{ text: `\nContent from @${file1Path}:\n` },
|
|
630
|
+
{ text: `\nContent from @${getRelativePath(file1Path)}:\n` },
|
|
618
631
|
{ text: content1 },
|
|
619
|
-
{ text: `\nContent from @${file2Path}:\n` },
|
|
632
|
+
{ text: `\nContent from @${getRelativePath(file2Path)}:\n` },
|
|
620
633
|
{ text: content2 },
|
|
621
634
|
{ text: '\n--- End of content ---' },
|
|
622
635
|
],
|
|
@@ -638,9 +651,9 @@ describe('handleAtCommand', () => {
|
|
|
638
651
|
});
|
|
639
652
|
expect(result).toEqual({
|
|
640
653
|
processedQuery: [
|
|
641
|
-
{ text: `Check @${filePath}, it has spaces.` },
|
|
654
|
+
{ text: `Check @${getRelativePath(filePath)}, it has spaces.` },
|
|
642
655
|
{ text: '\n--- Content from referenced files ---' },
|
|
643
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
656
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
644
657
|
{ text: fileContent },
|
|
645
658
|
{ text: '\n--- End of content ---' },
|
|
646
659
|
],
|
|
@@ -650,7 +663,7 @@ describe('handleAtCommand', () => {
|
|
|
650
663
|
it('should not break file paths with periods in extensions', async () => {
|
|
651
664
|
const fileContent = 'TypeScript content';
|
|
652
665
|
const filePath = await createTestFile(path.join(testRootDir, 'example.d.ts'), fileContent);
|
|
653
|
-
const query = `Analyze @${filePath} for type definitions.`;
|
|
666
|
+
const query = `Analyze @${getRelativePath(filePath)} for type definitions.`;
|
|
654
667
|
const result = await handleAtCommand({
|
|
655
668
|
query,
|
|
656
669
|
config: mockConfig,
|
|
@@ -661,9 +674,11 @@ describe('handleAtCommand', () => {
|
|
|
661
674
|
});
|
|
662
675
|
expect(result).toEqual({
|
|
663
676
|
processedQuery: [
|
|
664
|
-
{
|
|
677
|
+
{
|
|
678
|
+
text: `Analyze @${getRelativePath(filePath)} for type definitions.`,
|
|
679
|
+
},
|
|
665
680
|
{ text: '\n--- Content from referenced files ---' },
|
|
666
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
681
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
667
682
|
{ text: fileContent },
|
|
668
683
|
{ text: '\n--- End of content ---' },
|
|
669
684
|
],
|
|
@@ -673,7 +688,7 @@ describe('handleAtCommand', () => {
|
|
|
673
688
|
it('should handle file paths ending with period followed by space', async () => {
|
|
674
689
|
const fileContent = 'Config content';
|
|
675
690
|
const filePath = await createTestFile(path.join(testRootDir, 'config.json'), fileContent);
|
|
676
|
-
const query = `Check @${filePath}. This file contains settings.`;
|
|
691
|
+
const query = `Check @${getRelativePath(filePath)}. This file contains settings.`;
|
|
677
692
|
const result = await handleAtCommand({
|
|
678
693
|
query,
|
|
679
694
|
config: mockConfig,
|
|
@@ -684,9 +699,11 @@ describe('handleAtCommand', () => {
|
|
|
684
699
|
});
|
|
685
700
|
expect(result).toEqual({
|
|
686
701
|
processedQuery: [
|
|
687
|
-
{
|
|
702
|
+
{
|
|
703
|
+
text: `Check @${getRelativePath(filePath)}. This file contains settings.`,
|
|
704
|
+
},
|
|
688
705
|
{ text: '\n--- Content from referenced files ---' },
|
|
689
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
706
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
690
707
|
{ text: fileContent },
|
|
691
708
|
{ text: '\n--- End of content ---' },
|
|
692
709
|
],
|
|
@@ -696,7 +713,7 @@ describe('handleAtCommand', () => {
|
|
|
696
713
|
it('should handle comma termination with complex file paths', async () => {
|
|
697
714
|
const fileContent = 'Package info';
|
|
698
715
|
const filePath = await createTestFile(path.join(testRootDir, 'package.json'), fileContent);
|
|
699
|
-
const query = `Review @${filePath}, then check dependencies.`;
|
|
716
|
+
const query = `Review @${getRelativePath(filePath)}, then check dependencies.`;
|
|
700
717
|
const result = await handleAtCommand({
|
|
701
718
|
query,
|
|
702
719
|
config: mockConfig,
|
|
@@ -707,9 +724,11 @@ describe('handleAtCommand', () => {
|
|
|
707
724
|
});
|
|
708
725
|
expect(result).toEqual({
|
|
709
726
|
processedQuery: [
|
|
710
|
-
{
|
|
727
|
+
{
|
|
728
|
+
text: `Review @${getRelativePath(filePath)}, then check dependencies.`,
|
|
729
|
+
},
|
|
711
730
|
{ text: '\n--- Content from referenced files ---' },
|
|
712
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
731
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
713
732
|
{ text: fileContent },
|
|
714
733
|
{ text: '\n--- End of content ---' },
|
|
715
734
|
],
|
|
@@ -719,7 +738,7 @@ describe('handleAtCommand', () => {
|
|
|
719
738
|
it('should not terminate at period within file name', async () => {
|
|
720
739
|
const fileContent = 'Version info';
|
|
721
740
|
const filePath = await createTestFile(path.join(testRootDir, 'version.1.2.3.txt'), fileContent);
|
|
722
|
-
const query = `Check @${filePath} contains version information.`;
|
|
741
|
+
const query = `Check @${getRelativePath(filePath)} contains version information.`;
|
|
723
742
|
const result = await handleAtCommand({
|
|
724
743
|
query,
|
|
725
744
|
config: mockConfig,
|
|
@@ -730,9 +749,11 @@ describe('handleAtCommand', () => {
|
|
|
730
749
|
});
|
|
731
750
|
expect(result).toEqual({
|
|
732
751
|
processedQuery: [
|
|
733
|
-
{
|
|
752
|
+
{
|
|
753
|
+
text: `Check @${getRelativePath(filePath)} contains version information.`,
|
|
754
|
+
},
|
|
734
755
|
{ text: '\n--- Content from referenced files ---' },
|
|
735
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
756
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
736
757
|
{ text: fileContent },
|
|
737
758
|
{ text: '\n--- End of content ---' },
|
|
738
759
|
],
|
|
@@ -742,7 +763,7 @@ describe('handleAtCommand', () => {
|
|
|
742
763
|
it('should handle end of string termination for period and comma', async () => {
|
|
743
764
|
const fileContent = 'End file content';
|
|
744
765
|
const filePath = await createTestFile(path.join(testRootDir, 'end.txt'), fileContent);
|
|
745
|
-
const query = `Show me @${filePath}.`;
|
|
766
|
+
const query = `Show me @${getRelativePath(filePath)}.`;
|
|
746
767
|
const result = await handleAtCommand({
|
|
747
768
|
query,
|
|
748
769
|
config: mockConfig,
|
|
@@ -753,9 +774,9 @@ describe('handleAtCommand', () => {
|
|
|
753
774
|
});
|
|
754
775
|
expect(result).toEqual({
|
|
755
776
|
processedQuery: [
|
|
756
|
-
{ text: `Show me @${filePath}.` },
|
|
777
|
+
{ text: `Show me @${getRelativePath(filePath)}.` },
|
|
757
778
|
{ text: '\n--- Content from referenced files ---' },
|
|
758
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
779
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
759
780
|
{ text: fileContent },
|
|
760
781
|
{ text: '\n--- End of content ---' },
|
|
761
782
|
],
|
|
@@ -765,7 +786,7 @@ describe('handleAtCommand', () => {
|
|
|
765
786
|
it('should handle files with special characters in names', async () => {
|
|
766
787
|
const fileContent = 'File with special chars content';
|
|
767
788
|
const filePath = await createTestFile(path.join(testRootDir, 'file$with&special#chars.txt'), fileContent);
|
|
768
|
-
const query = `Check @${filePath} for content.`;
|
|
789
|
+
const query = `Check @${getRelativePath(filePath)} for content.`;
|
|
769
790
|
const result = await handleAtCommand({
|
|
770
791
|
query,
|
|
771
792
|
config: mockConfig,
|
|
@@ -776,9 +797,9 @@ describe('handleAtCommand', () => {
|
|
|
776
797
|
});
|
|
777
798
|
expect(result).toEqual({
|
|
778
799
|
processedQuery: [
|
|
779
|
-
{ text: `Check @${filePath} for content.` },
|
|
800
|
+
{ text: `Check @${getRelativePath(filePath)} for content.` },
|
|
780
801
|
{ text: '\n--- Content from referenced files ---' },
|
|
781
|
-
{ text: `\nContent from @${filePath}:\n` },
|
|
802
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
782
803
|
{ text: fileContent },
|
|
783
804
|
{ text: '\n--- End of content ---' },
|
|
784
805
|
],
|
|
@@ -788,7 +809,7 @@ describe('handleAtCommand', () => {
|
|
|
788
809
|
it('should handle basic file names without special characters', async () => {
|
|
789
810
|
const fileContent = 'Basic file content';
|
|
790
811
|
const filePath = await createTestFile(path.join(testRootDir, 'basicfile.txt'), fileContent);
|
|
791
|
-
const query = `Check @${filePath} please.`;
|
|
812
|
+
const query = `Check @${getRelativePath(filePath)} please.`;
|
|
792
813
|
const result = await handleAtCommand({
|
|
793
814
|
query,
|
|
794
815
|
config: mockConfig,
|
|
@@ -799,21 +820,98 @@ describe('handleAtCommand', () => {
|
|
|
799
820
|
});
|
|
800
821
|
expect(result).toEqual({
|
|
801
822
|
processedQuery: [
|
|
802
|
-
{ text: `Check @${filePath} please.` },
|
|
823
|
+
{ text: `Check @${getRelativePath(filePath)} please.` },
|
|
824
|
+
{ text: '\n--- Content from referenced files ---' },
|
|
825
|
+
{ text: `\nContent from @${getRelativePath(filePath)}:\n` },
|
|
826
|
+
{ text: fileContent },
|
|
827
|
+
{ text: '\n--- End of content ---' },
|
|
828
|
+
],
|
|
829
|
+
shouldProceed: true,
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
});
|
|
833
|
+
describe('absolute path handling', () => {
|
|
834
|
+
it('should handle absolute file paths correctly', async () => {
|
|
835
|
+
const fileContent = 'console.log("This is an absolute path test");';
|
|
836
|
+
const relativePath = path.join('src', 'absolute-test.ts');
|
|
837
|
+
const absolutePath = await createTestFile(path.join(testRootDir, relativePath), fileContent);
|
|
838
|
+
const query = `Check @${absolutePath} please.`;
|
|
839
|
+
const result = await handleAtCommand({
|
|
840
|
+
query,
|
|
841
|
+
config: mockConfig,
|
|
842
|
+
addItem: mockAddItem,
|
|
843
|
+
onDebugMessage: mockOnDebugMessage,
|
|
844
|
+
messageId: 500,
|
|
845
|
+
signal: abortController.signal,
|
|
846
|
+
});
|
|
847
|
+
expect(result).toEqual({
|
|
848
|
+
processedQuery: [
|
|
849
|
+
{ text: `Check @${relativePath} please.` },
|
|
803
850
|
{ text: '\n--- Content from referenced files ---' },
|
|
804
|
-
{ text: `\nContent from @${
|
|
851
|
+
{ text: `\nContent from @${relativePath}:\n` },
|
|
805
852
|
{ text: fileContent },
|
|
806
853
|
{ text: '\n--- End of content ---' },
|
|
807
854
|
],
|
|
808
855
|
shouldProceed: true,
|
|
809
856
|
});
|
|
857
|
+
expect(mockOnDebugMessage).toHaveBeenCalledWith(expect.stringContaining(`using relative path: ${relativePath}`));
|
|
858
|
+
});
|
|
859
|
+
it('should handle absolute directory paths correctly', async () => {
|
|
860
|
+
const fileContent = 'export default function test() { return "absolute dir test"; }';
|
|
861
|
+
const subDirPath = path.join('src', 'utils');
|
|
862
|
+
const fileName = 'helper.ts';
|
|
863
|
+
await createTestFile(path.join(testRootDir, subDirPath, fileName), fileContent);
|
|
864
|
+
const absoluteDirPath = path.join(testRootDir, subDirPath);
|
|
865
|
+
const query = `Check @${absoluteDirPath} please.`;
|
|
866
|
+
const result = await handleAtCommand({
|
|
867
|
+
query,
|
|
868
|
+
config: mockConfig,
|
|
869
|
+
addItem: mockAddItem,
|
|
870
|
+
onDebugMessage: mockOnDebugMessage,
|
|
871
|
+
messageId: 501,
|
|
872
|
+
signal: abortController.signal,
|
|
873
|
+
});
|
|
874
|
+
expect(result.shouldProceed).toBe(true);
|
|
875
|
+
expect(result.processedQuery).toEqual(expect.arrayContaining([
|
|
876
|
+
{ text: `Check @${path.join(subDirPath, '**')} please.` },
|
|
877
|
+
expect.objectContaining({
|
|
878
|
+
text: '\n--- Content from referenced files ---',
|
|
879
|
+
}),
|
|
880
|
+
]));
|
|
881
|
+
expect(mockOnDebugMessage).toHaveBeenCalledWith(expect.stringContaining(`using glob: ${path.join(subDirPath, '**')}`));
|
|
882
|
+
});
|
|
883
|
+
it('should skip absolute paths outside workspace', async () => {
|
|
884
|
+
const outsidePath = '/tmp/outside-workspace.txt';
|
|
885
|
+
const query = `Check @${outsidePath} please.`;
|
|
886
|
+
const mockWorkspaceContext = {
|
|
887
|
+
isPathWithinWorkspace: vi.fn((path) => path.startsWith(testRootDir)),
|
|
888
|
+
getDirectories: () => [testRootDir],
|
|
889
|
+
addDirectory: vi.fn(),
|
|
890
|
+
getInitialDirectories: () => [testRootDir],
|
|
891
|
+
setDirectories: vi.fn(),
|
|
892
|
+
onDirectoriesChanged: vi.fn(() => () => { }),
|
|
893
|
+
};
|
|
894
|
+
mockConfig.getWorkspaceContext = () => mockWorkspaceContext;
|
|
895
|
+
const result = await handleAtCommand({
|
|
896
|
+
query,
|
|
897
|
+
config: mockConfig,
|
|
898
|
+
addItem: mockAddItem,
|
|
899
|
+
onDebugMessage: mockOnDebugMessage,
|
|
900
|
+
messageId: 502,
|
|
901
|
+
signal: abortController.signal,
|
|
902
|
+
});
|
|
903
|
+
expect(result).toEqual({
|
|
904
|
+
processedQuery: [{ text: `Check @${outsidePath} please.` }],
|
|
905
|
+
shouldProceed: true,
|
|
906
|
+
});
|
|
907
|
+
expect(mockOnDebugMessage).toHaveBeenCalledWith(`Path ${outsidePath} is not in the workspace and will be skipped.`);
|
|
810
908
|
});
|
|
811
909
|
});
|
|
812
910
|
it("should not add the user's turn to history, as that is the caller's responsibility", async () => {
|
|
813
911
|
// Arrange
|
|
814
912
|
const fileContent = 'This is the file content.';
|
|
815
913
|
const filePath = await createTestFile(path.join(testRootDir, 'path', 'to', 'another-file.txt'), fileContent);
|
|
816
|
-
const query = `A query with @${filePath}`;
|
|
914
|
+
const query = `A query with @${getRelativePath(filePath)}`;
|
|
817
915
|
// Act
|
|
818
916
|
await handleAtCommand({
|
|
819
917
|
query,
|