@google/gemini-cli-core 0.1.13 → 0.1.14

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 (200) hide show
  1. package/README.md +22 -1
  2. package/dist/google-gemini-cli-core-0.1.13.tgz +0 -0
  3. package/dist/src/code_assist/codeAssist.js +2 -2
  4. package/dist/src/code_assist/codeAssist.js.map +1 -1
  5. package/dist/src/code_assist/oauth2.js +9 -2
  6. package/dist/src/code_assist/oauth2.js.map +1 -1
  7. package/dist/src/code_assist/oauth2.test.js +92 -0
  8. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  9. package/dist/src/code_assist/server.d.ts +4 -6
  10. package/dist/src/code_assist/server.js +4 -69
  11. package/dist/src/code_assist/server.js.map +1 -1
  12. package/dist/src/code_assist/setup.d.ts +6 -1
  13. package/dist/src/code_assist/setup.js +4 -1
  14. package/dist/src/code_assist/setup.js.map +1 -1
  15. package/dist/src/code_assist/setup.test.js +4 -1
  16. package/dist/src/code_assist/setup.test.js.map +1 -1
  17. package/dist/src/code_assist/types.d.ts +2 -2
  18. package/dist/src/config/config.d.ts +25 -7
  19. package/dist/src/config/config.js +46 -16
  20. package/dist/src/config/config.js.map +1 -1
  21. package/dist/src/config/config.test.js +1 -23
  22. package/dist/src/config/config.test.js.map +1 -1
  23. package/dist/src/config/flashFallback.test.js +1 -1
  24. package/dist/src/config/flashFallback.test.js.map +1 -1
  25. package/dist/src/core/client.d.ts +5 -2
  26. package/dist/src/core/client.js +39 -17
  27. package/dist/src/core/client.js.map +1 -1
  28. package/dist/src/core/client.test.js +51 -0
  29. package/dist/src/core/client.test.js.map +1 -1
  30. package/dist/src/core/contentGenerator.d.ts +1 -1
  31. package/dist/src/core/contentGenerator.js +1 -1
  32. package/dist/src/core/contentGenerator.js.map +1 -1
  33. package/dist/src/core/geminiChat.d.ts +4 -3
  34. package/dist/src/core/geminiChat.js +8 -11
  35. package/dist/src/core/geminiChat.js.map +1 -1
  36. package/dist/src/core/geminiRequest.js +2 -37
  37. package/dist/src/core/geminiRequest.js.map +1 -1
  38. package/dist/src/core/logger.js +6 -0
  39. package/dist/src/core/logger.js.map +1 -1
  40. package/dist/src/core/logger.test.js +1 -1
  41. package/dist/src/core/logger.test.js.map +1 -1
  42. package/dist/src/core/nonInteractiveToolExecutor.test.js +5 -5
  43. package/dist/src/core/prompts.js +42 -18
  44. package/dist/src/core/prompts.js.map +1 -1
  45. package/dist/src/core/prompts.test.js +121 -4
  46. package/dist/src/core/prompts.test.js.map +1 -1
  47. package/dist/src/core/turn.d.ts +7 -2
  48. package/dist/src/core/turn.js +9 -0
  49. package/dist/src/core/turn.js.map +1 -1
  50. package/dist/src/core/turn.test.js +129 -0
  51. package/dist/src/core/turn.test.js.map +1 -1
  52. package/dist/src/ide/ide-client.d.ts +28 -0
  53. package/dist/src/ide/ide-client.js +79 -0
  54. package/dist/src/ide/ide-client.js.map +1 -0
  55. package/dist/src/ide/ideContext.d.ts +174 -0
  56. package/dist/src/{services → ide}/ideContext.js +28 -25
  57. package/dist/src/ide/ideContext.js.map +1 -0
  58. package/dist/src/{services → ide}/ideContext.test.js +39 -39
  59. package/dist/src/ide/ideContext.test.js.map +1 -0
  60. package/dist/src/index.d.ts +3 -1
  61. package/dist/src/index.js +4 -1
  62. package/dist/src/index.js.map +1 -1
  63. package/dist/src/mcp/google-auth-provider.d.ts +23 -0
  64. package/dist/src/mcp/google-auth-provider.js +63 -0
  65. package/dist/src/mcp/google-auth-provider.js.map +1 -0
  66. package/dist/src/mcp/google-auth-provider.test.js +54 -0
  67. package/dist/src/mcp/google-auth-provider.test.js.map +1 -0
  68. package/dist/src/services/loopDetectionService.d.ts +48 -5
  69. package/dist/src/services/loopDetectionService.js +124 -38
  70. package/dist/src/services/loopDetectionService.js.map +1 -1
  71. package/dist/src/services/loopDetectionService.test.js +39 -112
  72. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  73. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +2 -1
  74. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +17 -2
  75. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  76. package/dist/src/telemetry/constants.d.ts +1 -0
  77. package/dist/src/telemetry/constants.js +1 -0
  78. package/dist/src/telemetry/constants.js.map +1 -1
  79. package/dist/src/telemetry/file-exporters.d.ts +28 -0
  80. package/dist/src/telemetry/file-exporters.js +62 -0
  81. package/dist/src/telemetry/file-exporters.js.map +1 -0
  82. package/dist/src/telemetry/loggers.d.ts +2 -1
  83. package/dist/src/telemetry/loggers.js +17 -1
  84. package/dist/src/telemetry/loggers.js.map +1 -1
  85. package/dist/src/telemetry/sdk.js +17 -6
  86. package/dist/src/telemetry/sdk.js.map +1 -1
  87. package/dist/src/telemetry/types.d.ts +9 -2
  88. package/dist/src/telemetry/types.js +13 -1
  89. package/dist/src/telemetry/types.js.map +1 -1
  90. package/dist/src/tools/edit.js +10 -4
  91. package/dist/src/tools/edit.js.map +1 -1
  92. package/dist/src/tools/edit.test.js +12 -0
  93. package/dist/src/tools/edit.test.js.map +1 -1
  94. package/dist/src/tools/grep.test.js +1 -1
  95. package/dist/src/tools/grep.test.js.map +1 -1
  96. package/dist/src/tools/ls.d.ts +5 -2
  97. package/dist/src/tools/ls.js +39 -10
  98. package/dist/src/tools/ls.js.map +1 -1
  99. package/dist/src/tools/mcp-client.d.ts +5 -1
  100. package/dist/src/tools/mcp-client.js +414 -28
  101. package/dist/src/tools/mcp-client.js.map +1 -1
  102. package/dist/src/tools/mcp-client.test.js +46 -6
  103. package/dist/src/tools/mcp-client.test.js.map +1 -1
  104. package/dist/src/tools/mcp-tool.js +1 -1
  105. package/dist/src/tools/mcp-tool.js.map +1 -1
  106. package/dist/src/tools/mcp-tool.test.js +34 -0
  107. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  108. package/dist/src/tools/read-file.test.js +98 -69
  109. package/dist/src/tools/read-file.test.js.map +1 -1
  110. package/dist/src/tools/read-many-files.d.ts +5 -3
  111. package/dist/src/tools/read-many-files.js +62 -22
  112. package/dist/src/tools/read-many-files.js.map +1 -1
  113. package/dist/src/tools/read-many-files.test.js +5 -2
  114. package/dist/src/tools/read-many-files.test.js.map +1 -1
  115. package/dist/src/tools/shell.d.ts +2 -23
  116. package/dist/src/tools/shell.js +49 -136
  117. package/dist/src/tools/shell.js.map +1 -1
  118. package/dist/src/tools/shell.test.js +33 -319
  119. package/dist/src/tools/shell.test.js.map +1 -1
  120. package/dist/src/tools/tool-registry.d.ts +13 -1
  121. package/dist/src/tools/tool-registry.js +45 -1
  122. package/dist/src/tools/tool-registry.js.map +1 -1
  123. package/dist/src/tools/tool-registry.test.js +3 -3
  124. package/dist/src/tools/tool-registry.test.js.map +1 -1
  125. package/dist/src/utils/bfsFileSearch.d.ts +2 -0
  126. package/dist/src/utils/bfsFileSearch.js +4 -1
  127. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  128. package/dist/src/utils/bfsFileSearch.test.js +108 -105
  129. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  130. package/dist/src/utils/editCorrector.js +4 -4
  131. package/dist/src/utils/editCorrector.js.map +1 -1
  132. package/dist/src/utils/editCorrector.test.js +1 -1
  133. package/dist/src/utils/editor.js +16 -10
  134. package/dist/src/utils/editor.js.map +1 -1
  135. package/dist/src/utils/editor.test.js +128 -28
  136. package/dist/src/utils/editor.test.js.map +1 -1
  137. package/dist/src/utils/errorReporting.d.ts +1 -1
  138. package/dist/src/utils/errorReporting.js +2 -2
  139. package/dist/src/utils/errorReporting.js.map +1 -1
  140. package/dist/src/utils/errorReporting.test.js +44 -38
  141. package/dist/src/utils/errorReporting.test.js.map +1 -1
  142. package/dist/src/utils/fileUtils.d.ts +4 -4
  143. package/dist/src/utils/fileUtils.js +31 -15
  144. package/dist/src/utils/fileUtils.js.map +1 -1
  145. package/dist/src/utils/fileUtils.test.js +37 -37
  146. package/dist/src/utils/fileUtils.test.js.map +1 -1
  147. package/dist/src/utils/getFolderStructure.d.ts +3 -2
  148. package/dist/src/utils/getFolderStructure.js +27 -28
  149. package/dist/src/utils/getFolderStructure.js.map +1 -1
  150. package/dist/src/utils/getFolderStructure.test.js +169 -187
  151. package/dist/src/utils/getFolderStructure.test.js.map +1 -1
  152. package/dist/src/utils/gitIgnoreParser.js +4 -7
  153. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  154. package/dist/src/utils/gitIgnoreParser.test.js +70 -61
  155. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  156. package/dist/src/utils/memoryDiscovery.d.ts +2 -1
  157. package/dist/src/utils/memoryDiscovery.js +11 -5
  158. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  159. package/dist/src/utils/memoryDiscovery.test.js +160 -371
  160. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  161. package/dist/src/utils/partUtils.d.ts +14 -0
  162. package/dist/src/utils/partUtils.js +65 -0
  163. package/dist/src/utils/partUtils.js.map +1 -0
  164. package/dist/src/utils/partUtils.test.d.ts +6 -0
  165. package/dist/src/utils/partUtils.test.js +130 -0
  166. package/dist/src/utils/partUtils.test.js.map +1 -0
  167. package/dist/src/utils/paths.d.ts +11 -0
  168. package/dist/src/utils/paths.js +17 -1
  169. package/dist/src/utils/paths.js.map +1 -1
  170. package/dist/src/utils/quotaErrorDetection.js +0 -2
  171. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  172. package/dist/src/utils/retry.js +1 -1
  173. package/dist/src/utils/retry.js.map +1 -1
  174. package/dist/src/utils/schemaValidator.d.ts +1 -1
  175. package/dist/src/utils/schemaValidator.js +6 -3
  176. package/dist/src/utils/schemaValidator.js.map +1 -1
  177. package/dist/src/utils/shell-utils.d.ts +44 -0
  178. package/dist/src/utils/shell-utils.js +243 -0
  179. package/dist/src/utils/shell-utils.js.map +1 -0
  180. package/dist/src/utils/shell-utils.test.d.ts +6 -0
  181. package/dist/src/utils/shell-utils.test.js +450 -0
  182. package/dist/src/utils/shell-utils.test.js.map +1 -0
  183. package/dist/src/utils/summarizer.js +1 -30
  184. package/dist/src/utils/summarizer.js.map +1 -1
  185. package/dist/src/utils/systemEncoding.d.ts +40 -0
  186. package/dist/src/utils/systemEncoding.js +149 -0
  187. package/dist/src/utils/systemEncoding.js.map +1 -0
  188. package/dist/src/utils/systemEncoding.test.d.ts +6 -0
  189. package/dist/src/utils/systemEncoding.test.js +368 -0
  190. package/dist/src/utils/systemEncoding.test.js.map +1 -0
  191. package/dist/tsconfig.tsbuildinfo +1 -1
  192. package/package.json +2 -1
  193. package/dist/google-gemini-cli-core-0.1.12.tgz +0 -0
  194. package/dist/src/core/geminiRequest.test.js +0 -72
  195. package/dist/src/core/geminiRequest.test.js.map +0 -1
  196. package/dist/src/services/ideContext.d.ts +0 -126
  197. package/dist/src/services/ideContext.js.map +0 -1
  198. package/dist/src/services/ideContext.test.js.map +0 -1
  199. /package/dist/src/{services → ide}/ideContext.test.d.ts +0 -0
  200. /package/dist/src/{core/geminiRequest.test.d.ts → mcp/google-auth-provider.test.d.ts} +0 -0
@@ -12,59 +12,59 @@ describe('ideContext - Active File', () => {
12
12
  ideContext = createIdeContextStore();
13
13
  });
14
14
  it('should return undefined initially for active file context', () => {
15
- expect(ideContext.getActiveFileContext()).toBeUndefined();
15
+ expect(ideContext.getOpenFilesContext()).toBeUndefined();
16
16
  });
17
17
  it('should set and retrieve the active file context', () => {
18
18
  const testFile = {
19
- filePath: '/path/to/test/file.ts',
20
- cursor: { line: 5, character: 10 },
19
+ activeFile: '/path/to/test/file.ts',
20
+ selectedText: '1234',
21
21
  };
22
- ideContext.setActiveFileContext(testFile);
23
- const activeFile = ideContext.getActiveFileContext();
22
+ ideContext.setOpenFilesContext(testFile);
23
+ const activeFile = ideContext.getOpenFilesContext();
24
24
  expect(activeFile).toEqual(testFile);
25
25
  });
26
26
  it('should update the active file context when called multiple times', () => {
27
27
  const firstFile = {
28
- filePath: '/path/to/first.js',
29
- cursor: { line: 1, character: 1 },
28
+ activeFile: '/path/to/first.js',
29
+ selectedText: '1234',
30
30
  };
31
- ideContext.setActiveFileContext(firstFile);
31
+ ideContext.setOpenFilesContext(firstFile);
32
32
  const secondFile = {
33
- filePath: '/path/to/second.py',
33
+ activeFile: '/path/to/second.py',
34
34
  cursor: { line: 20, character: 30 },
35
35
  };
36
- ideContext.setActiveFileContext(secondFile);
37
- const activeFile = ideContext.getActiveFileContext();
36
+ ideContext.setOpenFilesContext(secondFile);
37
+ const activeFile = ideContext.getOpenFilesContext();
38
38
  expect(activeFile).toEqual(secondFile);
39
39
  });
40
40
  it('should handle empty string for file path', () => {
41
41
  const testFile = {
42
- filePath: '',
43
- cursor: { line: 0, character: 0 },
42
+ activeFile: '',
43
+ selectedText: '1234',
44
44
  };
45
- ideContext.setActiveFileContext(testFile);
46
- expect(ideContext.getActiveFileContext()).toEqual(testFile);
45
+ ideContext.setOpenFilesContext(testFile);
46
+ expect(ideContext.getOpenFilesContext()).toEqual(testFile);
47
47
  });
48
48
  it('should notify subscribers when active file context changes', () => {
49
49
  const subscriber1 = vi.fn();
50
50
  const subscriber2 = vi.fn();
51
- ideContext.subscribeToActiveFile(subscriber1);
52
- ideContext.subscribeToActiveFile(subscriber2);
51
+ ideContext.subscribeToOpenFiles(subscriber1);
52
+ ideContext.subscribeToOpenFiles(subscriber2);
53
53
  const testFile = {
54
- filePath: '/path/to/subscribed.ts',
54
+ activeFile: '/path/to/subscribed.ts',
55
55
  cursor: { line: 15, character: 25 },
56
56
  };
57
- ideContext.setActiveFileContext(testFile);
57
+ ideContext.setOpenFilesContext(testFile);
58
58
  expect(subscriber1).toHaveBeenCalledTimes(1);
59
59
  expect(subscriber1).toHaveBeenCalledWith(testFile);
60
60
  expect(subscriber2).toHaveBeenCalledTimes(1);
61
61
  expect(subscriber2).toHaveBeenCalledWith(testFile);
62
62
  // Test with another update
63
63
  const newFile = {
64
- filePath: '/path/to/new.js',
65
- cursor: { line: 1, character: 1 },
64
+ activeFile: '/path/to/new.js',
65
+ selectedText: '1234',
66
66
  };
67
- ideContext.setActiveFileContext(newFile);
67
+ ideContext.setOpenFilesContext(newFile);
68
68
  expect(subscriber1).toHaveBeenCalledTimes(2);
69
69
  expect(subscriber1).toHaveBeenCalledWith(newFile);
70
70
  expect(subscriber2).toHaveBeenCalledTimes(2);
@@ -73,39 +73,39 @@ describe('ideContext - Active File', () => {
73
73
  it('should stop notifying a subscriber after unsubscribe', () => {
74
74
  const subscriber1 = vi.fn();
75
75
  const subscriber2 = vi.fn();
76
- const unsubscribe1 = ideContext.subscribeToActiveFile(subscriber1);
77
- ideContext.subscribeToActiveFile(subscriber2);
78
- ideContext.setActiveFileContext({
79
- filePath: '/path/to/file1.txt',
80
- cursor: { line: 1, character: 1 },
76
+ const unsubscribe1 = ideContext.subscribeToOpenFiles(subscriber1);
77
+ ideContext.subscribeToOpenFiles(subscriber2);
78
+ ideContext.setOpenFilesContext({
79
+ activeFile: '/path/to/file1.txt',
80
+ selectedText: '1234',
81
81
  });
82
82
  expect(subscriber1).toHaveBeenCalledTimes(1);
83
83
  expect(subscriber2).toHaveBeenCalledTimes(1);
84
84
  unsubscribe1();
85
- ideContext.setActiveFileContext({
86
- filePath: '/path/to/file2.txt',
87
- cursor: { line: 2, character: 2 },
85
+ ideContext.setOpenFilesContext({
86
+ activeFile: '/path/to/file2.txt',
87
+ selectedText: '1234',
88
88
  });
89
89
  expect(subscriber1).toHaveBeenCalledTimes(1); // Should not be called again
90
90
  expect(subscriber2).toHaveBeenCalledTimes(2);
91
91
  });
92
92
  it('should allow the cursor to be optional', () => {
93
93
  const testFile = {
94
- filePath: '/path/to/test/file.ts',
94
+ activeFile: '/path/to/test/file.ts',
95
95
  };
96
- ideContext.setActiveFileContext(testFile);
97
- const activeFile = ideContext.getActiveFileContext();
96
+ ideContext.setOpenFilesContext(testFile);
97
+ const activeFile = ideContext.getOpenFilesContext();
98
98
  expect(activeFile).toEqual(testFile);
99
99
  });
100
100
  it('should clear the active file context', () => {
101
101
  const testFile = {
102
- filePath: '/path/to/test/file.ts',
103
- cursor: { line: 5, character: 10 },
102
+ activeFile: '/path/to/test/file.ts',
103
+ selectedText: '1234',
104
104
  };
105
- ideContext.setActiveFileContext(testFile);
106
- expect(ideContext.getActiveFileContext()).toEqual(testFile);
107
- ideContext.clearActiveFileContext();
108
- expect(ideContext.getActiveFileContext()).toBeUndefined();
105
+ ideContext.setOpenFilesContext(testFile);
106
+ expect(ideContext.getOpenFilesContext()).toEqual(testFile);
107
+ ideContext.clearOpenFilesContext();
108
+ expect(ideContext.getOpenFilesContext()).toBeUndefined();
109
109
  });
110
110
  });
111
111
  //# sourceMappingURL=ideContext.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ideContext.test.js","sourceRoot":"","sources":["../../../src/ide/ideContext.test.ts"],"names":[],"mappings":"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"}
@@ -28,9 +28,11 @@ export * from './utils/editor.js';
28
28
  export * from './utils/quotaErrorDetection.js';
29
29
  export * from './utils/fileUtils.js';
30
30
  export * from './utils/retry.js';
31
+ export * from './utils/systemEncoding.js';
31
32
  export * from './services/fileDiscoveryService.js';
32
33
  export * from './services/gitService.js';
33
- export * from './services/ideContext.js';
34
+ export * from './ide/ide-client.js';
35
+ export * from './ide/ideContext.js';
34
36
  export * from './tools/tools.js';
35
37
  export * from './tools/tool-registry.js';
36
38
  export * from './tools/read-file.js';
package/dist/src/index.js CHANGED
@@ -31,10 +31,13 @@ export * from './utils/editor.js';
31
31
  export * from './utils/quotaErrorDetection.js';
32
32
  export * from './utils/fileUtils.js';
33
33
  export * from './utils/retry.js';
34
+ export * from './utils/systemEncoding.js';
34
35
  // Export services
35
36
  export * from './services/fileDiscoveryService.js';
36
37
  export * from './services/gitService.js';
37
- export * from './services/ideContext.js';
38
+ // Export IDE specific logic
39
+ export * from './ide/ide-client.js';
40
+ export * from './ide/ideContext.js';
38
41
  // Export base tool definitions
39
42
  export * from './tools/tools.js';
40
43
  export * from './tools/tool-registry.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gBAAgB;AAChB,cAAc,oBAAoB,CAAC;AAEnC,oBAAoB;AACpB,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sCAAsC,CAAC;AAErD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AAEvC,mBAAmB;AACnB,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AAEjC,kBAAkB;AAClB,cAAc,oCAAoC,CAAC;AACnD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,+BAA+B;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AAEzC,6BAA6B;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AAEpC,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAGL,oBAAoB,GACrB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,6BAA6B;AAC7B,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gBAAgB;AAChB,cAAc,oBAAoB,CAAC;AAEnC,oBAAoB;AACpB,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sCAAsC,CAAC;AAErD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AAEvC,mBAAmB;AACnB,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAE1C,kBAAkB;AAClB,cAAc,oCAAoC,CAAC;AACnD,cAAc,0BAA0B,CAAC;AAEzC,4BAA4B;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AAEpC,+BAA+B;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AAEzC,6BAA6B;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AAEpC,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAGL,oBAAoB,GACrB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,6BAA6B;AAC7B,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
7
+ import { OAuthClientInformation, OAuthClientInformationFull, OAuthClientMetadata, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
8
+ import { MCPServerConfig } from '../config/config.js';
9
+ export declare class GoogleCredentialProvider implements OAuthClientProvider {
10
+ private readonly config?;
11
+ private readonly auth;
12
+ readonly redirectUrl = "";
13
+ readonly clientMetadata: OAuthClientMetadata;
14
+ private _clientInformation?;
15
+ constructor(config?: MCPServerConfig | undefined);
16
+ clientInformation(): OAuthClientInformation | undefined;
17
+ saveClientInformation(clientInformation: OAuthClientInformationFull): void;
18
+ tokens(): Promise<OAuthTokens | undefined>;
19
+ saveTokens(_tokens: OAuthTokens): void;
20
+ redirectToAuthorization(_authorizationUrl: URL): void;
21
+ saveCodeVerifier(_codeVerifier: string): void;
22
+ codeVerifier(): string;
23
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { GoogleAuth } from 'google-auth-library';
7
+ export class GoogleCredentialProvider {
8
+ config;
9
+ auth;
10
+ // Properties required by OAuthClientProvider, with no-op values
11
+ redirectUrl = '';
12
+ clientMetadata = {
13
+ client_name: 'Gemini CLI (Google ADC)',
14
+ redirect_uris: [],
15
+ grant_types: [],
16
+ response_types: [],
17
+ token_endpoint_auth_method: 'none',
18
+ };
19
+ _clientInformation;
20
+ constructor(config) {
21
+ this.config = config;
22
+ const scopes = this.config?.oauth?.scopes;
23
+ if (!scopes || scopes.length === 0) {
24
+ throw new Error('Scopes must be provided in the oauth config for Google Credentials provider');
25
+ }
26
+ this.auth = new GoogleAuth({
27
+ scopes,
28
+ });
29
+ }
30
+ clientInformation() {
31
+ return this._clientInformation;
32
+ }
33
+ saveClientInformation(clientInformation) {
34
+ this._clientInformation = clientInformation;
35
+ }
36
+ async tokens() {
37
+ const client = await this.auth.getClient();
38
+ const accessTokenResponse = await client.getAccessToken();
39
+ if (!accessTokenResponse.token) {
40
+ console.error('Failed to get access token from Google ADC');
41
+ return undefined;
42
+ }
43
+ const tokens = {
44
+ access_token: accessTokenResponse.token,
45
+ token_type: 'Bearer',
46
+ };
47
+ return tokens;
48
+ }
49
+ saveTokens(_tokens) {
50
+ // No-op, ADC manages tokens.
51
+ }
52
+ redirectToAuthorization(_authorizationUrl) {
53
+ // No-op
54
+ }
55
+ saveCodeVerifier(_codeVerifier) {
56
+ // No-op
57
+ }
58
+ codeVerifier() {
59
+ // No-op
60
+ return '';
61
+ }
62
+ }
63
+ //# sourceMappingURL=google-auth-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-auth-provider.js","sourceRoot":"","sources":["../../../src/mcp/google-auth-provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,MAAM,OAAO,wBAAwB;IAcN;IAbZ,IAAI,CAAa;IAElC,gEAAgE;IACvD,WAAW,GAAG,EAAE,CAAC;IACjB,cAAc,GAAwB;QAC7C,WAAW,EAAE,yBAAyB;QACtC,aAAa,EAAE,EAAE;QACjB,WAAW,EAAE,EAAE;QACf,cAAc,EAAE,EAAE;QAClB,0BAA0B,EAAE,MAAM;KACnC,CAAC;IACM,kBAAkB,CAA8B;IAExD,YAA6B,MAAwB;QAAxB,WAAM,GAAN,MAAM,CAAkB;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC;YACzB,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED,qBAAqB,CAAC,iBAA6C;QACjE,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAC3C,MAAM,mBAAmB,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAC;QAE1D,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,MAAM,GAAgB;YAC1B,YAAY,EAAE,mBAAmB,CAAC,KAAK;YACvC,UAAU,EAAE,QAAQ;SACrB,CAAC;QACF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,UAAU,CAAC,OAAoB;QAC7B,6BAA6B;IAC/B,CAAC;IAED,uBAAuB,CAAC,iBAAsB;QAC5C,QAAQ;IACV,CAAC;IAED,gBAAgB,CAAC,aAAqB;QACpC,QAAQ;IACV,CAAC;IAED,YAAY;QACV,QAAQ;QACR,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { GoogleAuth } from 'google-auth-library';
7
+ import { GoogleCredentialProvider } from './google-auth-provider.js';
8
+ import { vi, describe, beforeEach, it, expect } from 'vitest';
9
+ vi.mock('google-auth-library');
10
+ describe('GoogleCredentialProvider', () => {
11
+ it('should throw an error if no scopes are provided', () => {
12
+ expect(() => new GoogleCredentialProvider()).toThrow('Scopes must be provided in the oauth config for Google Credentials provider');
13
+ });
14
+ it('should use scopes from the config if provided', () => {
15
+ const config = {
16
+ oauth: {
17
+ scopes: ['scope1', 'scope2'],
18
+ },
19
+ };
20
+ new GoogleCredentialProvider(config);
21
+ expect(GoogleAuth).toHaveBeenCalledWith({
22
+ scopes: ['scope1', 'scope2'],
23
+ });
24
+ });
25
+ describe('with provider instance', () => {
26
+ let provider;
27
+ beforeEach(() => {
28
+ const config = {
29
+ oauth: {
30
+ scopes: ['scope1', 'scope2'],
31
+ },
32
+ };
33
+ provider = new GoogleCredentialProvider(config);
34
+ vi.clearAllMocks();
35
+ });
36
+ it('should return credentials', async () => {
37
+ const mockClient = {
38
+ getAccessToken: vi.fn().mockResolvedValue({ token: 'test-token' }),
39
+ };
40
+ GoogleAuth.prototype.getClient.mockResolvedValue(mockClient);
41
+ const credentials = await provider.tokens();
42
+ expect(credentials?.access_token).toBe('test-token');
43
+ });
44
+ it('should return undefined if access token is not available', async () => {
45
+ const mockClient = {
46
+ getAccessToken: vi.fn().mockResolvedValue({ token: null }),
47
+ };
48
+ GoogleAuth.prototype.getClient.mockResolvedValue(mockClient);
49
+ const credentials = await provider.tokens();
50
+ expect(credentials).toBeUndefined();
51
+ });
52
+ });
53
+ });
54
+ //# sourceMappingURL=google-auth-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-auth-provider.test.js","sourceRoot":"","sources":["../../../src/mcp/google-auth-provider.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAQ,MAAM,QAAQ,CAAC;AAGpE,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAE/B,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAClD,6EAA6E,CAC9E,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG;YACb,KAAK,EAAE;gBACL,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;aAC7B;SACiB,CAAC;QACrB,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC;YACtC,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,IAAI,QAAkC,CAAC;QAEvC,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE;oBACL,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;iBAC7B;aACiB,CAAC;YACrB,QAAQ,GAAG,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;YAChD,EAAE,CAAC,aAAa,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,UAAU,GAAG;gBACjB,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;aACnE,CAAC;YACD,UAAU,CAAC,SAAS,CAAC,SAAkB,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEvE,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;YAE5C,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,MAAM,UAAU,GAAG;gBACjB,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;aAC3D,CAAC;YACD,UAAU,CAAC,SAAS,CAAC,SAAkB,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAEvE,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC5C,MAAM,CAAC,WAAW,CAAC,CAAC,aAAa,EAAE,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -11,11 +11,13 @@ import { Config } from '../config/config.js';
11
11
  */
12
12
  export declare class LoopDetectionService {
13
13
  private readonly config;
14
+ private promptId;
14
15
  private lastToolCallKey;
15
16
  private toolCallRepetitionCount;
16
- private lastRepeatedSentence;
17
- private sentenceRepetitionCount;
18
- private partialContent;
17
+ private streamContentHistory;
18
+ private contentStats;
19
+ private lastContentIndex;
20
+ private loopDetected;
19
21
  private turnsInCurrentPrompt;
20
22
  private llmCheckInterval;
21
23
  private lastCheckTurn;
@@ -39,13 +41,54 @@ export declare class LoopDetectionService {
39
41
  */
40
42
  turnStarted(signal: AbortSignal): Promise<boolean>;
41
43
  private checkToolCallLoop;
44
+ /**
45
+ * Detects content loops by analyzing streaming text for repetitive patterns.
46
+ *
47
+ * The algorithm works by:
48
+ * 1. Appending new content to the streaming history
49
+ * 2. Truncating history if it exceeds the maximum length
50
+ * 3. Analyzing content chunks for repetitive patterns using hashing
51
+ * 4. Detecting loops when identical chunks appear frequently within a short distance
52
+ */
42
53
  private checkContentLoop;
54
+ /**
55
+ * Truncates the content history to prevent unbounded memory growth.
56
+ * When truncating, adjusts all stored indices to maintain their relative positions.
57
+ */
58
+ private truncateAndUpdate;
59
+ /**
60
+ * Analyzes content in fixed-size chunks to detect repetitive patterns.
61
+ *
62
+ * Uses a sliding window approach:
63
+ * 1. Extract chunks of fixed size (CONTENT_CHUNK_SIZE)
64
+ * 2. Hash each chunk for efficient comparison
65
+ * 3. Track positions where identical chunks appear
66
+ * 4. Detect loops when chunks repeat frequently within a short distance
67
+ */
68
+ private analyzeContentChunksForLoop;
69
+ private hasMoreChunksToProcess;
70
+ /**
71
+ * Determines if a content chunk indicates a loop pattern.
72
+ *
73
+ * Loop detection logic:
74
+ * 1. Check if we've seen this hash before (new chunks are stored for future comparison)
75
+ * 2. Verify actual content matches to prevent hash collisions
76
+ * 3. Track all positions where this chunk appears
77
+ * 4. A loop is detected when the same chunk appears CONTENT_LOOP_THRESHOLD times
78
+ * within a small average distance (≤ 1.5 * chunk size)
79
+ */
80
+ private isLoopDetectedForChunk;
81
+ /**
82
+ * Verifies that two chunks with the same hash actually contain identical content.
83
+ * This prevents false positives from hash collisions.
84
+ */
85
+ private isActualContentMatch;
43
86
  private checkForLoopWithLLM;
44
87
  /**
45
88
  * Resets all loop detection state.
46
89
  */
47
- reset(): void;
90
+ reset(promptId: string): void;
48
91
  private resetToolCallCount;
49
- private resetSentenceCount;
92
+ private resetContentTracking;
50
93
  private resetLlmCheckTracking;
51
94
  }